C/C++
中數值操做,如自加(n++)
自減(n–-)
及賦值(n=2)
操做都不是原子操做,若是是多線程程序須要使用全局計數器,程序就須要使用鎖或者互斥量,對於較高併發的程序,會形成必定的性能瓶頸。html
**1.**概要api
爲了提升賦值操做的效率,gcc提供了一組api,經過彙編級別的代碼來保證賦值類操做的原子性,相對於涉及到操做系統系統調用和應用層同步的鎖和互斥量,這組api的效率要高不少。多線程
**2.**n++類併發
type __sync_fetch_and_add(type *ptr, type value, ...); // m+n type __sync_fetch_and_sub(type *ptr, type value, ...); // m-n type __sync_fetch_and_or(type *ptr, type value, ...); // m|n type __sync_fetch_and_and(type *ptr, type value, ...); // m&n type __sync_fetch_and_xor(type *ptr, type value, ...); // m^n type __sync_fetch_and_nand(type *ptr, type value, ...); // (~m)&n /* 對應的僞代碼 */ { tmp = *ptr; *ptr op= value; return tmp; } { tmp = *ptr; *ptr = (~tmp) & value; return tmp; } // nand
3.++n類高併發
type __sync_add_and_fetch(type *ptr, type value, ...); // m+n type __sync_sub_and_fetch(type *ptr, type value, ...); // m-n type __sync_or_and_fetch(type *ptr, type value, ...); // m|n type __sync_and_and_fetch(type *ptr, type value, ...); // m&n type __sync_xor_and_fetch(type *ptr, type value, ...); // m^n type __sync_nand_and_fetch(type *ptr, type value, ...); // (~m)&n /* 對應的僞代碼 */ { *ptr op= value; return *ptr; } { *ptr = (~*ptr) & value; return *ptr; } // nand
4.CAS類性能
bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...); type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...); /* 對應的僞代碼 */ { if (*ptr == oldval) { *ptr = newval; return true; } else { return false; } } { if (*ptr == oldval) { *ptr = newval; } return oldval; }
1.test.cfetch
例子不是併發的程序,只是演示各api
的使用參數和返回。因爲是gcc
內置api
,因此並不須要任何頭文件。ui
#include <stdio.h> int main() { int num = 0; /* * n++; * __sync_fetch_and_add(10, 3) = 10 * num = 13 */ num = 10; printf("__sync_fetch_and_add(%d, %d) = %d\n", 10, 3, __sync_fetch_and_add(&num, 3)); printf("num = %d\n", num); /* * ++n; * __sync_and_add_and_fetch(10, 3) = 13 * num = 13 */ num = 10; printf("__sync_and_add_and_fetch(%d, %d) = %d\n", 10, 3, __sync_add_and_fetch(&num, 3)); printf("num = %d\n", num); /* * CAS, match * __sync_val_compare_and_swap(10, 10, 2) = 10 * num = 2 */ num = 10; printf("__sync_val_compare_and_swap(%d, %d, %d) = %d\n", 10, 10, 2, __sync_val_compare_and_swap(&num, 10, 2)); printf("num = %d\n", num); /* * CAS, not match * __sync_val_compare_and_swap(10, 3, 5) = 10 * num = 10 */ num = 10; printf("__sync_val_compare_and_swap(%d, %d, %d) = %d\n", 10, 3, 5, __sync_val_compare_and_swap(&num, 1, 2)); printf("num = %d\n", num); return 0; }