GCC數(shù)值原子操作API原理及應(yīng)用

文章來(lái)自GCC數(shù)值原子操作API原理及應(yīng)用

.前言

C/C++中數(shù)值操作,如自加(n++)自減(n–-)及賦值(n=2)操作都不是原子操作,如果是多線(xiàn)程程序需要使用全局計(jì)數(shù)器,程序就需要使用鎖或者互斥量,對(duì)于較高并發(fā)的程序,會(huì)造成一定的性能瓶頸。

.gcc****原子操作****api

1.概要

為了提高賦值操作的效率,gcc提供了一組api,通過(guò)匯編級(jí)別的代碼來(lái)保證賦值類(lèi)操作的原子性,相對(duì)于涉及到操作系統(tǒng)系統(tǒng)調(diào)用和應(yīng)用層同步的鎖和互斥量,這組api的效率要高很多。

2.n++類(lèi)

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
/* 對(duì)應(yīng)的偽代碼 */
{ tmp = *ptr; *ptr op= value; return tmp; }
{ tmp = *ptr; *ptr = (~tmp) & value; return tmp; }   // nand

3.++n類(lèi)

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
/* 對(duì)應(yīng)的偽代碼 */
{ *ptr op= value; return *ptr; }
{ *ptr = (~*ptr) & value; return *ptr; } // nand

4.CAS類(lèi)

bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...);
type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...);
/* 對(duì)應(yīng)的偽代碼 */
{ if (*ptr == oldval) { *ptr = newval; return true; } else { return false; } }
{ if (*ptr == oldval) { *ptr = newval; } return oldval; }

.程序?qū)嵗?/strong>

1.test.c

例子不是并發(fā)的程序,只是演示各api的使用參數(shù)和返回。由于是gcc內(nèi)置api,所以并不需要任何頭文件。

#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;
}

.Reference

(1)gcc Atomic-Builtins doc
(2)CAS(Compare-and-swap)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容