OpenMP创建线程中的锁及原子操作性能比较

相关内容:线程与进程的区别

[多线程共存于应用程序中是现代操作系统中的基本特征和重要标志。用过UNIX操作系统的读者知道进程,在UNIX操作系统中,每个应用程序的执行都在操作系

 

OpenMP 创建线程中的锁及原子操作性能比较   相关文档连接: 多核编程中的任务随机竞争模式的概率分析 多核编程中的任务分组竞争模式               多核编程中的负载平衡难题 多核编程中的锁竞争难题 多核编程的几个难题及其应对策略(难题一) OpenMP并行程序设计(二)   OpenMP并行程序设计(一)   双核CPU上的快速排序效率               在多核 CPU中锁竞争到底会造成性能怎样的下降呢?相信这是许多人想了解的,因此特地写了一个测试程序来测试原子操作,windows CriticalSection, OpenMP的锁操作函数在多核CPU中的性能。   原子操作选用 InterlockedIncrement来进行测试, 对每种锁和原子操作,都测试在单任务执行和多任务执行 2000000次加锁解锁操作所消耗的时间。 测试的详细代码见后面。   测试机器环境: Intel 2.66G 双核CPU 机器一台   测试运行结果如下: 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   在单任务运行情况下,所消耗的时间如下: 原子操作                 78ms Windows CriticalSection 172ms OpenMP 的lock操作        250ms   因此从单任务情况来看,原子操作最快, Windows CriticalSection次之,OpenMP库带的锁最慢,但这几种操作的时间差距不是很大,用锁操作比原子操作慢了2~3倍左右。   在多个任务运行的情况下,所消耗的时间如下:   原子操作                 156ms Windows CriticalSection 3156ms OpenMP 的lock操作        1063ms   在多任务运行情况下,情况发生了意想不到的变化,原子操作时间比单任务操作时慢了一倍,在两个 CPU上运行比在单个CPU上运行还慢一倍,真是难以想象,

相关内容:多线程与单线程的区别

[ 单线程(Thread)与多线程的区别        首先了解一下cpu,随着主频(cpu内核工作时钟频率,表示在CPU内数字脉冲信号震荡的速度,等于外频(系统基

估计是任务切换开销造成的。 Windows CriticalSection则更离谱了,居然花了 3156ms,是单任务运行时的18倍多的时间,慢得简直无法想象。 OpenMP的 lock操作比Windows CriticalSection稍微好一些,但也花了1063ms,是单任务时的7倍左右。   由此可以知道,在多核 CPU的多任务环境中,原子操作是最快的,而OpenMP次之,Windows CriticalSection则最慢。   同时从这些锁在单任务和多任务下的性能差距可以看出,,多核 CPU上的编程和以往的单核多任务编程会有很大的区别。 需要说明的是,本测试是一种极端情况下的测试,锁住的操作只是一个简单的加1操作,并且锁竞争次数达200万次之多,在实际情况中,一由于任务中还有很多不需要加锁的代码在运行,实际情况中的性能会比本测试的性能好很多。     测试代码如下:   // TestLock.cpp : OpenMP 任务中的原子操作和锁性能测试程序。 //   #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; }    

相关问题

评论

写下你的理解