周伟明的专栏

<<软件测试实践>> 已上市

周伟明ID:drzhouweiming
179730次访问,排名356(-1)好友0人,关注者8
软件技术爱好及研究者
drzhouweiming的文章
原创 48 篇
翻译 0 篇
转载 0 篇
评论 312 篇
周伟明的公告
一书已上市, 欢迎大家提出意见!
最近评论
algcfx:Wow gold
dimire:LZ你好,我参考你的第一个测试程序int main(int argc, char* argv[])
{
#pragma omp parallel for
for (int i = 0; i < 10; i++ )
{
printf("i = %d\n", i);
}
……
dimire:学习了
dimire:LZ你好,我参考你的第一个测试程序int main(int argc, char* argv[])
{
#pragma omp parallel for
for (int i = 0; i < 10; i++ )
{
printf("i = %d\n", i);
}
……
dimire:LZ你好,我参考你的第一个测试程序int main(int argc, char* argv[])
{
#pragma omp parallel for
for (int i = 0; i < 10; i++ )
{
printf("i = %d\n", i);
}
……
文章分类
    收藏
      相册
      最近文章
      1、多核新观念-象使用内存一样使用CPU?
      2、多核编程中的任务随机竞争模式的概率分析
      3、OpenMP创建线程中的锁及原子操作性能比较
      4、多核编程中的任务分组竞争模式
      5、称球问题的测试解法
      90%程序员写不出无BUG的二分查找程序?
      C/C++代码检视实例
      多核编程中的负载平衡难题
      多核编程中的锁竞争难题
      微软过桥问题与测试人员素养
      接口关系稳定原理探索
      接口设计定理
      模块分解原理与三权分立
      模块分解原理的探索
      测试驱动需求分析
      筑一座坝治好中国的沙漠
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

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

      新一篇: 多核新观念-象使用内存一样使用CPU?

       

      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上运行还慢一倍,真是难以想象,估计是任务切换开销造成的。
      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;
      }
       
       

      发表于 @ 2007年07月13日 23:16:00|评论(loading...)|编辑

      旧一篇: 多核编程中的任务随机竞争模式的概率分析

      评论

      #bigkai 发表于2007-07-23 17:10:54  IP: 219.133.0.*
      在Intel P42.8G(HT)上运行结果:
      SingleThread, InterlockedIncrement 2,000,000: a = 2000000, time = 93
      MultiThread, InterlockedIncrement 2,000,000: a = 2000000, time = 78
      SingleThread, Critical_Section 2,000,000:a = 2000000, time = 172
      MultiThread, Critical_Section, 2,000,000:a = 2000000, time = 3844
      SingleThread,omp_lock 2,000,000:a = 2000000, time = 188
      MultiThread,omp_lock 2,000,000:a = 2000000, time = 265


      #realdreamer 发表于2007-09-25 17:14:39  IP: 61.148.45.*
      对OpenMP的指令 #pragma 不大熟, 不知道这样的测试方法是否合理. 不过至少 Critical_Section 与 omp_lock 的锁实在是性能差异太大了... 这是何原因呢?

      还有一个 Critical_Section 的初始化, 应该用自旋的初始化函数来初始化它, 性能应该就快了.
      #realdreamer 发表于2007-09-25 17:16:55  IP: 61.148.45.*
      对OpenMP的指令 #pragma 不大熟, 不知道这样的测试方法是否合理. 不过至少 Critical_Section 与 omp_lock 的锁实在是性能差异太大了... 这是何原因呢?

      还有一个 Critical_Section 的初始化, 应该用自旋的初始化函数来初始化它, 性能应该就快了. 谁给测试下~ 我这没vc8
      #realdreamer 发表于2007-09-25 17:20:29  IP: 61.148.45.*
      对OpenMP的指令 #pragma 不大熟, 不知道这样的测试方法是否合理. 不过至少 Critical_Section 与 omp_lock 的锁实在是性能差异太大了... 这是何原因呢?

      还有一个 Critical_Section 的初始化, 应该用自旋的初始化函数来初始化它, 性能应该就快了. 谁给测试下~ 我这没vc8
      #drzhouweiming 发表于2007-09-25 17:38:34  IP: 58.31.68.*
      用自旋的初始化来初始化的话,速度会比没用自旋时快一些,但是自旋次数不同效果不一样,需要测试出合适的自旋次数。
      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © 周伟明