免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
C++小品:榨干性能:C++11中的原子操作(atomic operation) | 有{...

C++小品:榨干性能:C++11中的原子操作(atomic operation)

2011-12-05 12:55 by 陳良喬, 719 次閱讀, 沒(méi)有評(píng)論

所謂的原子操作,取的就是“原子是最小的、不可分割的最小個(gè)體”的意義,它表示在多個(gè)線程訪問(wèn)同一個(gè)全局資源的時(shí)候,能夠確保所有其他的線程都不在同一時(shí)間內(nèi)訪問(wèn)相同的資源。也就是他確保了在同一時(shí)刻只有唯一的線程對(duì)這個(gè)資源進(jìn)行訪問(wèn)。這有點(diǎn)類似互斥對(duì)象對(duì)共享資源的訪問(wèn)的保護(hù),但是原子操作更加接近底層,因而效率更高。

在以往的C++標(biāo)準(zhǔn)中并沒(méi)有對(duì)原子操作進(jìn)行規(guī)定,我們往往是使用匯編語(yǔ)言,或者是借助第三方的線程庫(kù),例如intel的pthread來(lái)實(shí)現(xiàn)。在新標(biāo)準(zhǔn)C++11,引入了原子操作的概念,并通過(guò)這個(gè)新的頭文件提供了多種原子操作數(shù)據(jù)類型,例如,atomic_bool,atomic_int等等,如果我們?cè)诙鄠€(gè)線程中對(duì)這些類型的共享資源進(jìn)行操作,編譯器將保證這些操作都是原子性的,也就是說(shuō),確保任意時(shí)刻只有一個(gè)線程對(duì)這個(gè)資源進(jìn)行訪問(wèn),編譯器將保證,多個(gè)線程訪問(wèn)這個(gè)共享資源的正確性。從而避免了鎖的使用,提高了效率。

我們還是來(lái)看一個(gè)實(shí)際的例子。假若我們要設(shè)計(jì)一個(gè)廣告點(diǎn)擊統(tǒng)計(jì)程序,在服務(wù)器程序中,使用多個(gè)線程模擬多個(gè)用戶對(duì)廣告的點(diǎn)擊:

#include <boost/thread/thread.hpp>
#include <atomic>
#include <iostream>
#include <time.h>

using namespace std;
// 全局的結(jié)果數(shù)據(jù)
long total = 0;

// 點(diǎn)擊函數(shù)
void click()
{
    for(int i=0; i<1000000;++i)
    {
        // 對(duì)全局?jǐn)?shù)據(jù)進(jìn)行無(wú)鎖訪問(wèn)
        total += 1;    
    }
}
 
 
int main(int argc, char* argv[])
{
    // 計(jì)時(shí)開(kāi)始
    clock_t start = clock();
    // 創(chuàng)建100個(gè)線程模擬點(diǎn)擊統(tǒng)計(jì)
    boost::thread_group threads;
    for(int i=0; i<100;++i)
    {
        threads.create_thread(click);
    }

    threads.join_all();
    // 計(jì)時(shí)結(jié)束
    clock_t finish = clock();
    // 輸出結(jié)果
    cout<<"result:"<<total<<endl;
    cout<<"duration:"<<finish -start<<"ms"<<endl;
    return 0;
}

從執(zhí)行的結(jié)果來(lái)看,這樣的方法雖然非??欤墙Y(jié)果不正確
E:SourceCodeMinGW>thread.exe
result:87228026
duration:528ms

很自然地,我們會(huì)想到使用互斥對(duì)象來(lái)對(duì)全局共享資源的訪問(wèn)進(jìn)行保護(hù),于是有了下面的實(shí)現(xiàn):

long total = 0;
// 對(duì)共享資源進(jìn)行保護(hù)的互斥對(duì)象
mutex m;

void click()
{
    for(int i=0; i<1000000;++i)
    {
        // 訪問(wèn)之前,鎖定互斥對(duì)象
        m.lock();
        total += 1;
        // 訪問(wèn)完成后,釋放互斥對(duì)象
        m.unlock();
    }
}
互斥對(duì)象的使用,保證了同一時(shí)刻只有唯一的一個(gè)線程對(duì)這個(gè)共享進(jìn)行訪問(wèn),從執(zhí)行的結(jié)果來(lái)看,互斥對(duì)象保證了結(jié)果的正確性,但是也有非常大的性能損失,從剛才的528ms變成了現(xiàn)在的8431,用了原來(lái)時(shí)間的10多倍的時(shí)間。這個(gè)損失夠大。
E:SourceCodeMinGW>thread.exe
result:100000000
duration:8431ms

如果是在C++11之前,我們的解決方案也就到此為止了,但是,C++對(duì)性能的追求是永無(wú)止境的,他總是想盡一切辦法榨干CPU的性能。在C++11中,實(shí)現(xiàn)了原子操作的數(shù)據(jù)類型(atomic_bool,atomic_int,atomic_long等等),對(duì)于這些原子數(shù)據(jù)類型的共享資源的訪問(wèn),無(wú)需借助mutex等鎖機(jī)制,也能夠?qū)崿F(xiàn)對(duì)共享資源的正確訪問(wèn)。

// 引入原子數(shù)據(jù)類型的頭文件
#include <atomic>
 

// 用原子數(shù)據(jù)類型作為共享資源的數(shù)據(jù)類型
atomic_long total(0);
//long total = 0;
 
void click()
{
    for(int i=0; i<1000000;++i)
    {
        // 僅僅是數(shù)據(jù)類型的不同而以,對(duì)其的訪問(wèn)形式與普通數(shù)據(jù)類型的資源并無(wú)區(qū)別
        total += 1;
    }
}

我們來(lái)看看使用原子數(shù)據(jù)類型之后的效果如何:
E:SourceCodeMinGW>thread.exe
result:100000000
duration:2105ms

結(jié)果正確!耗時(shí)只是使用mutex互斥對(duì)象的四分之一!也僅僅是不采用任何保護(hù)機(jī)制的時(shí)間的4倍??梢哉f(shuō)這是一個(gè)非常不錯(cuò)的成績(jī)了。

原子操作的實(shí)現(xiàn)跟普通數(shù)據(jù)類型類似,但是它能夠在保證結(jié)果正確的前提下,提供比mutex等鎖機(jī)制更好的性能,如果我們要訪問(wèn)的共享資源可以用原子數(shù)據(jù)類型表示,那么在多線程程序中使用這種新的等價(jià)數(shù)據(jù)類型,是一個(gè)不錯(cuò)的選擇。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C++ 新特性學(xué)習(xí)(八) — 原子操作和多線程庫(kù)[多工內(nèi)存模型]
內(nèi)核鎖問(wèn)題
多線程編程基礎(chǔ)
(轉(zhuǎn)載)關(guān)于信號(hào)量與線程互斥鎖的區(qū)別與實(shí)現(xiàn)
IOS atomic與nonatomic,assign,copy與retain的定義和區(qū)別...
淺談 Java 并發(fā)下的樂(lè)觀鎖
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服