溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

OpenMP創(chuàng)建線程中的鎖及原子操作性能分析

發(fā)布時(shí)間:2021-11-17 16:20:26 來源:億速云 閱讀:398 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“OpenMP創(chuàng)建線程中的鎖及原子操作性能分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“OpenMP創(chuàng)建線程中的鎖及原子操作性能分析”吧!

windows CriticalSection, OpenMP的鎖操作函數(shù)在多核CPU中的性能。

原子操作選用InterlockedIncrement來進(jìn)行測試,

對每種鎖和原子操作,都測試在單任務(wù)執(zhí)行和多任務(wù)執(zhí)行2000000次加鎖解鎖操作所消耗的時(shí)間。

測試的詳細(xì)代碼見后面。

測試機(jī)器環(huán)境: Intel 2.66G 雙核CPU 機(jī)器一臺(tái)

測試運(yùn)行結(jié)果如下:

SingleThread, InterlockedIncrement 2,000,000: a = 2000000, time = 78

MultiThread, InterlockedIncrement 2,000,000: a = 2000000, time = 156

SingleThread, Critical_Section 2,000,000:a = 2000000, time = 172

MultiThread, Critical_Section, 2,000,000:a = 2000000, time = 3156

SingleThread,omp_lock 2,000,000:a = 2000000, time = 250

MultiThread,omp_lock 2,000,000:a = 2000000, time = 1063

在單任務(wù)運(yùn)行情況下,所消耗的時(shí)間如下:

原子操作                 78ms

Windows CriticalSection 172ms

OpenMP 的lock操作        250ms

因此從單任務(wù)情況來看,原子操作最快,Windows CriticalSection次之,OpenMP庫帶的鎖最慢,但這幾種操作的時(shí)間差距不是很大,用鎖操作比原子操作慢了2~3倍左右。

在多個(gè)任務(wù)運(yùn)行的情況下,所消耗的時(shí)間如下:

原子操作                 156ms

Windows CriticalSection 3156ms

OpenMP 的lock操作        1063ms

在多任務(wù)運(yùn)行情況下,情況發(fā)生了意想不到的變化,原子操作時(shí)間比單任務(wù)操作時(shí)慢了一倍,在兩個(gè)CPU上運(yùn)行比在單個(gè)CPU上運(yùn)行還慢一倍,真是難以想象,估計(jì)是任務(wù)切換開銷造成的。

Windows CriticalSection則更離譜了,居然花了3156ms,是單任務(wù)運(yùn)行時(shí)的18倍多的時(shí)間,慢得簡直無法想象。

OpenMP的lock操作比Windows CriticalSection稍微好一些,但也花了1063ms,是單任務(wù)時(shí)的7倍左右。

由此可以知道,在多核CPU的多任務(wù)環(huán)境中,原子操作是最快的,而OpenMP次之,Windows CriticalSection則最慢。

同時(shí)從這些鎖在單任務(wù)和多任務(wù)下的性能差距可以看出,,多核CPU上的編程和以往的單核多任務(wù)編程會(huì)有很大的區(qū)別。

需要說明的是,本測試是一種極端情況下的測試,鎖住的操作只是一個(gè)簡單的加1操作,并且鎖競爭次數(shù)達(dá)200萬次之多,在實(shí)際情況中,一由于任務(wù)中還有很多不需要加鎖的代碼在運(yùn)行,實(shí)際情況中的性能會(huì)比本測試的性能好很多。

測試代碼如下:

// TestLock.cpp : OpenMP任務(wù)中的原子操作和鎖性能測試程序。 //   #include <windows.h> #include <time.h> #include <process.h> #include <omp.h> #include <stdio.h>   void TestAtomic() {      clock_t t1,t2;      int      i = 0;      volatile LONG      a = 0;        t1 = clock();        for( i = 0; i < 2000000; i++ )      {          InterlockedIncrement( &a);      }           t2 = clock();      printf("SingleThread, InterlockedIncrement 2,000,000: a = %ld, time = %ld/n", a, t2-t1);        t1 = clock();   #pragma omp parallel for      for( i = 0; i < 2000000; i++ )      {          InterlockedIncrement( &a);      }           t2 = clock();      printf("MultiThread, InterlockedIncrement 2,000,000: a = %ld, time = %ld/n", a, t2-t1); }   void TestOmpLock() {      clock_t t1,t2;      int i;      int a = 0;      omp_lock_t    mylock;        omp_init_lock(&mylock);        t1 = clock();        for( i = 0; i < 2000000; i++ )      {          omp_set_lock(&mylock);          a+=1;          omp_unset_lock(&mylock);      }      t2 = clock();           printf("SingleThread,omp_lock 2,000,000:a = %ld, time = %ld/n", a, t2-t1);        t1 = clock();   #pragma omp parallel for      for( i = 0; i < 2000000; i++ )      {          omp_set_lock(&mylock);          a+=1;          omp_unset_lock(&mylock);      }      t2 = clock();           printf("MultiThread,omp_lock 2,000,000:a = %ld, time = %ld/n", a, t2-t1);        omp_destroy_lock(&mylock); }       void TestCriticalSection() {      clock_t t1,t2;      int i;      int a = 0;      CRITICAL_SECTION   cs;        InitializeCriticalSection(&cs);        t1 = clock();        for( i = 0; i < 2000000; i++ )      {          EnterCriticalSection(&cs);          a+=1;          LeaveCriticalSection(&cs);      }      t2 = clock();        printf("SingleThread, Critical_Section 2,000,000:a = %ld, time = %ld/n", a, t2-t1);        t1 = clock();   #pragma omp parallel for      for( i = 0; i < 2000000; i++ )      {          EnterCriticalSection(&cs);          a+=1;          LeaveCriticalSection(&cs);      }      t2 = clock();        printf("MultiThread, Critical_Section, 2,000,000:a = %ld, time = %ld/n", a, t2-t1);        DeleteCriticalSection(&cs);   }   int main(int argc, char* argv[]) {        TestAtomic();      TestCriticalSection();      TestOmpLock();        return 0; }

感謝各位的閱讀,以上就是“OpenMP創(chuàng)建線程中的鎖及原子操作性能分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對OpenMP創(chuàng)建線程中的鎖及原子操作性能分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI