GCC에서 제공하는 기본 제공 원자성 작업 중 어떤 것이 획득 작업이고 어떤 것이 릴리스 작업인가요?
선언:
type __sync_fetch_and_add(유형 *ptr, 유형 값, ...)
type __sync_fetch_and_sub(유형 *ptr, 유형 값, .. .) .)
유형 __sync_fetch_and_or(유형 *ptr, 유형 값, ...)
유형 __sync_fetch_and_and(유형 *ptr, 유형 값, ...)
__sync_fetch_and_xor 유형(*ptr 유형, 값 유형, ...)
__sync_fetch_and_nand 유형(*ptr 유형, 값 유형, ...)
__sync_add_and_fetch 유형(* 유형) ptr, 유형 값, ...)
유형 __sync_sub_and_fetch(유형 *ptr, 유형 값, ...)
유형 __sync_or_and_fetch(유형 *ptr, 유형 값, ... )
__sync_and_and_fetch 유형(*ptr 유형, 값 유형, ...)
__sync_xor_and_fetch 유형(*ptr 유형, 값 유형, ...)
type __sync_nand_and_fetch (type *ptr, type value, ...)
두 함수 그룹의 차이점은 첫 번째 그룹은 사전 업데이트된 값을 반환하고 두 번째 그룹은 업데이트된 값을 반환한다는 점입니다.
p>
type1, 2, 4 또는 8 바이트 단위 int 유형은 다음과 같습니다.
int8_t / uint8_t
int16_t / uint16_t
int32_t / uint32_t
int64_t / uint64_t
표면 확장 매개변수(...)는 메모리 장벽이 필요한 변수를 나타냅니다. 현재 gcc는 전체 장벽(리눅스 커널 mb()과 유사함)을 구현합니다. 작업 전 메모리 작업 재정렬), 매개변수가 생략됩니다.
bool __sync_bool_compare_and_swap (*ptr 유형, oldval 유형 newval 유형, ...)
__sync_val_compare_and_swap 유형 (*ptr 유형 , type oldval type newval, ...)
두 함수는 원래 비교 교환 *ptr == oldval을 제공하고 newval은 *ptr에 기록됩니다.
첫 번째 함수는 다음과 같은 경우 true를 반환합니다. 동일하며 작성됩니다.
두 번째 함수는 Value 작업 이전에 반환됩니다.
__sync_synchronize (...)
전체 배리어를 보냅니다.
메모리 장벽에 관해서는, CPU 명령이 정렬되어 프로그램 효율성을 향상시키면 내가 달성하고자 하는 결과를 얻을 수 있습니다.
내 하드웨어 장치의 4개 레지스터는 작업 명령을 저장하고 대기 레지스터는 READ보다 매개변수를 저장합니다. 레지스터 제어 레지스터의 매개변수는 모두 장치에 설정됩니다. 그리고 명령 실행 프로그램은 다음을 수행할 수 있습니다:
write1(dev.register_size, size);
write1(dev.register_addr, addr);
write1(dev.register_cmd, READ);
write1(dev.register_control, GO);
write1의 처음 몇 문 앞에 메모리 장벽을 추가하여 CPU를 강제로 종료합니다. 이전 쓰기를 수행한 후 다음을 실행합니다:
write1(dev.register_size, size)
write1(dev.register_addr, addr)
write1( dev.register_cmd, READ);
write1(dev.register_addr, addr);
write1(dev.register_cmd, READ) p>
__sync_synchronize(); p>
write1(dev.register_control, GO);
여러 유형의 메모리 장벽:
장벽 획득: 장벽 허용 메모리 읽기 명령이 장벽 앞으로 이동됩니다(linux kernelwmb ())
릴리스 배리어: 배리어 이전의 메모리 읽기 명령을 배리어로 이동하도록 허용합니다(linux kernelrmb())
전체 배리어: 두 가지 유형의 배리어 컬렉션(linux kernelmb( ))
두 가지 함수:
type __sync_lock_test_and_set (type *ptr, type value, ...)
*ptr은 값을 설정하고 이전 값을 반환합니다. * ptr 작업
void __sync_lock_release (*ptr, ... 유형)
*ptr을 0으로 설정
샘플 프로그램:
# include
#include
#include
static int count = 0
void *test_func(void *arg )
{
int i=0;
for(i=0; ilt; 20000; i){
__sync_fetch_and_add( amp; 개수, 1);
}
NULL을 반환
}
int main(int argc, const char *argv [])
{
pthread_t id[20];
int i = 0
for(i=0; ilt ;20; i ){
pthread_create(amp; id[i], NULL, test_func, NULL)
}
for(i=0; ilt; 20; i){
pthread_join(id[i], NULL);
}
printf("d\n", count);
0을 반환;
피>
}