在配备Intel Pentium双核处理器T2370(Acer Extensa)的笔记本电脑上,我运行了一个简单的多线程加速测试.我正在使用Linux.代码粘贴在下面.虽然我期待加速2-3次,但我惊讶地发现速度减慢了2倍.我尝试了同样的gcc优化等级-O0 ... -O3,但每次我得到相同的结果.我正在使用pthreads.我也尝试了同样只有两个线程(而不是代码中的3个线程),但性能类似.
可能是什么原因?更快的版本需要相当长的时间 - 大约20秒 - 所以它似乎不是启动开销的问题.
注意:这个代码有很多错误(事实上它没有多大意义,因为串行和并行版本的输出会有所不同).目的只是"获得"相同数量指令的加速比较.
#include#include #include #include class Thread{ private: pthread_t thread; static void *thread_func(void *d){((Thread *)d)->run();} public: Thread(){} virtual ~Thread(){} virtual void run(){} int start(){return pthread_create(&thread, NULL, Thread::thread_func, (void*)this);} int wait(){return pthread_join(thread, NULL);} }; #include const int ARR_SIZE = 100000000; const int N = 20; int arr[ARR_SIZE]; int main(void) { class Thread_a:public Thread{ public: Thread_a(int* a): arr_(a) {} void run() { for(int n = 0; n start() != 0) { return 1; } if (b->start() != 0) { return 1; } if (c->start() != 0) { return 1; } if (a->wait() != 0) { return 1; } if (b->wait() != 0) { return 1; } if (c->wait() != 0) { return 1; } clock_t end = clock(); double duration = (double)(end - start) / CLOCKS_PER_SEC; std::cout << duration << "seconds\n"; delete a; delete b; } { clock_t start = clock(); for(int n = 0; n
另请参阅:使用更多线程时,什么可以使程序运行得更慢?
1> Pete Kirkham..:您报告的时间是使用时钟功能测量的:
该
clock()
函数返回程序使用的处理器时间的近似值.$ time bin/amit_kumar_threads.cpp 6.62seconds serial: 2.7seconds real 0m5.247s user 0m9.025s sys 0m0.304s多处理器任务的实时时间会更短,但处理器时间通常会更长.
当您使用多个线程时,工作可能由多个处理器完成,但工作量相同,此外可能会有一些开销,例如争用有限的资源.
clock()
测量总处理器时间,这将是工作+任何争用开销.因此,它应该永远不会少于在单个线程中完成工作的处理器时间.从问题中你是否知道这一点有点难以理解,并且惊讶于返回的值
clock()
是单个线程的两倍而不是仅仅多一点,或者你期望它更少.
clock_gettime()
改为使用(你需要实时库librtg++ -lrt
等)给出:$ time bin/amit_kumar_threads.cpp 2.524 seconds serial: 2.761 seconds real 0m5.326s user 0m9.057s sys 0m0.344s这仍然不像人们希望的那样加速,但至少这些数字是有道理的.
100000000*20/2.5s = 800Hz,总线频率为1600 MHz,所以我怀疑每次迭代都有读取和写入(假设有一些缓存),你的内存带宽有限,正如tstenner建议的那样,
clock()
值显示大多数某些处理器正在等待数据的时间.(有谁知道clock()
时间是否包括这样的摊位?)
2> tstenner..:你的线程唯一做的就是添加一些元素,所以你的应用程序应该是IO绑定的.当你添加一个额外的线程时,你有2个CPU共享内存总线,所以它不会更快,相反,你将有缓存未命中等.