我在Linux上编写了一个简短的测试程序来测试memcpy在多线程中使用时的执行情况。我没想到它会像毁灭性的那样。执行时间从3.8秒增加到超过2分钟,同时运行两个程序实例大约需要4.7秒。这是为什么?
// thread example
#include <iostream>
#include <thread>
#include <string.h>
using namespace std;
void foo(/*int a[3],int b[3]*/)
{
int a[3]={7,8,3};
int b[3]={9,8,2};
for(int i=0;i<100000000;i++){
memcpy(a,b,12*(rand()&1));
}
}
int main()
{
#ifdef THREAD
thread threads[4];
for (char t=0; t<4; ++t) {
threads[t] = thread( foo );
}
for (auto& th : threads) th.join();
cout << "foo and bar completed.\n";
#else
foo();
foo();
foo();
foo();
#endif
return 0;
}
答案 0 :(得分:3)
由于memcpy
始终为12 * rand() & 1
,因此0
无效,因为它被视为(12 * rand()) & 1
。由于12是偶数,因此结果总是0
。
因此,您只是测量rand()
的时间,但该函数使用可能(或可能不)由所有线程共享的共享全局状态。看起来在您的实现中它是共享的并且它的访问是同步的,因此您会有很多争用并且性能会受到影响。
尝试使用rand_r()
,而不使用共享状态(或新的和改进的C ++随机生成器):
unsigned int r = 0;
for(int i=0;i<100000000;i++){
rand_r(&r)
}
在我的机器中,将多线程运行时间从30秒减少到0.7秒(单线程为2.2秒)。
当然,这个实验没有说明memcpy()
,但它说的是关于共享的全球状态......