先說結(jié)論:原子操作性能(速度)強(qiáng)于互斥鎖,下面用例子進(jìn)行說明。
編寫測試demo,開啟兩個線程,對全局變量n分別進(jìn)行自增、自減操作,計算執(zhí)行時間。
首先看沒有用任何手段進(jìn)行互斥的情況,用文章《C++計算打印函數(shù)和代碼塊的執(zhí)行時間(支持所有類型函數(shù))》中的方法進(jìn)行時間測量:
#include
#include#include#include#include#include#includeusing namespace std;
#define TOTAL 100000000
int n = 0;
templateauto measure(T&& func, Args&&... args)->std::future::type>{
using return_type = typename std::result_of::type;
auto task = std::make_shared>(std::bind(std::forward(func), std::forward(args)...));
std::futureres = task->get_future();
auto begin = std::chrono::high_resolution_clock::now();
(*task)();
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast(end - begin);
printf("執(zhí)行時間: % .3f seconds.\n", elapsed.count() * 1e-9);
return res;
}
void funPlus()
{
for (int i = 0; i< TOTAL; i++)
{
n++;
}
}
void funMinus()
{
for (int i = 0; i< TOTAL; i++)
{
n--;
}
}
int main()
{
measure([] {
thread a(funPlus);
thread b(funMinus);
a.join();
b.join();
});
cout<< "執(zhí)行結(jié)束,n的值為: "<< n<< endl;
return 0;
}
運(yùn)行結(jié)果如下:
執(zhí)行時間是0.541秒,是耗時最短的,但是由于沒有用互斥方法保護(hù),所以臨界資源n的值不正確(正確的值應(yīng)該為0)。這是因為自增、自減操作不是原子的,編譯得到的匯編指令可能會對應(yīng)多條指令。所以我們得要對n這個臨界資源進(jìn)行互斥保護(hù)。
我們來看下使用原子操作std::atomic
#include
#include#include#include#include#include#includeusing namespace std;
#define TOTAL 100000000
atomicn(0);
templateauto measure(T&& func, Args&&... args)->std::future::type>{
using return_type = typename std::result_of::type;
auto task = std::make_shared>(std::bind(std::forward(func), std::forward(args)...));
std::futureres = task->get_future();
auto begin = std::chrono::high_resolution_clock::now();
(*task)();
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast(end - begin);
printf("執(zhí)行時間: % .3f seconds.\n", elapsed.count() * 1e-9);
return res;
}
void funPlus()
{
for (int i = 0; i< TOTAL; i++)
{
n++;
}
}
void funMinus()
{
for (int i = 0; i< TOTAL; i++)
{
n--;
}
}
int main()
{
measure([] {
thread a(funPlus);
thread b(funMinus);
a.join();
b.join();
});
cout<< "執(zhí)行結(jié)束,n的值為: "<< n<< endl;
return 0;
}
執(zhí)行效果如下:
可以看到耗時為:5.261秒,n的值為0。也就是說耗時變長了,但是臨界資源n的值可以保證 一定正確。
我們再來看使用互斥鎖的情況:
#include
#include#include#include#include#include#include#includeusing namespace std;
#define TOTAL 100000000
std::mutex g_mutex;
int n = 0;
templateauto measure(T&& func, Args&&... args)->std::future::type>{
using return_type = typename std::result_of::type;
auto task = std::make_shared>(std::bind(std::forward(func), std::forward(args)...));
std::futureres = task->get_future();
auto begin = std::chrono::high_resolution_clock::now();
(*task)();
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast(end - begin);
printf("執(zhí)行時間: % .3f seconds.\n", elapsed.count() * 1e-9);
return res;
}
void funPlus()
{
for (int i = 0; i< TOTAL; i++)
{
std::lock_guardlock(g_mutex);
n++;
}
}
void funMinus()
{
for (int i = 0; i< TOTAL; i++)
{
std::lock_guardlock(g_mutex);
n--;
}
}
int main()
{
measure([] {
thread a(funPlus);
thread b(funMinus);
a.join();
b.join();
});
cout<< "執(zhí)行結(jié)束,n的值為: "<< n<< endl;
return 0;
}
運(yùn)行效果如下:
可以看到執(zhí)行時間為27.762秒。執(zhí)行時間最長,但也能保持臨界資源n的值正確。
所以對于基本類型的臨界資源,我們進(jìn)行訪問時可以用原子操作代替互斥鎖,來提高性能。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
本文題目:C++原子操作和互斥鎖性能(速度)對比-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://chinadenli.net/article34/deeepe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站排名、網(wǎng)站改版、標(biāo)簽優(yōu)化、虛擬主機(jī)、網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容