C++11原子操作性能測試


測試結論是發現C++11原子操作在性能上,比以往用到的InterlockedIncrement或__sync_add_and_fetch性能上慢了1倍左右。

另外補充一點,在對原子變量進行比較的時候,最好是引用它操作后的返回值,而不要直接用原子變量進行比較,比如:

下面是測試過程以及代碼

std::atomic<long> g_data = 0;
long v = ++g_data;
if(v = 1000)
{
    dosomething();
}

//不要用下面的方式,可能某個線程已將g_data原子的值設置為了1000,而引起不只一個線程執行下面的動作
if(g_data = 1000) 
{
    dosomething();
}

 

以前用到原子操作函數

volatile long Sync_Add(volatile long* value)
{
#ifdef WIN32
    return InterlockedIncrement(value);
#else
    return __sync_add_and_fetch(value, 1);
#endif
}

volatile long Sync_Sub(volatile long* value)
{
#ifdef WIN32
    return InterlockedDecrement(value);
#else
    return __sync_sub_and_fetch(value, 1);
#endif
}

 

C++ 11自帶原來操作<atomic>

#include <atomic>

std::atomic<long> g_data = 0;

g_data++; //線程安全的原子操作

 

測試的源代碼如下:

volatile long Sync_Add(volatile long* value)
{
#ifdef WIN32
    return InterlockedIncrement(value);
#else
    return __sync_add_and_fetch(value, 1);
#endif
}

volatile long Sync_Sub(volatile long* value)
{
#ifdef WIN32
    return InterlockedDecrement(value);
#else
    return __sync_sub_and_fetch(value, 1);
#endif
}

long g_data = 0;
//std::atomic<long> g_data = 0;

void threadfun()
{
    for (int i=0;i<10000;i++)
    {
        g_data = Sync_Add(&g_data);
        //g_data++;
    }
}



int main(int argc, char* argv[])
{
    int start = ::GetTickCount();

    for (int i = 0; i < 1000; i++)
    {
        std::thread t(threadfun);
        t.join();
    }

    std::cout<<"g_data = "<< g_data <<" use time = " << ::GetTickCount() - start << std::endl;

    system("pause");
    return 0;
}

 

運行結果:

g_data = 10000000 use time = 1497 //C++11的<atomic>
g_data = 10000000 use time = 717   //非C++11

  

不過這點性能對現在的計算機來說,應該沒什么影響了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM