在多线程中使用时,为什么memcpy性能会下降?

时间:2016-10-04 18:19:42

标签: c++ multithreading memcpy

我在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;
}

1 个答案:

答案 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(),但它说的是关于共享的全球状态......