我正在使用gcc(GCC)4.8.3 20140911在CentOS 7服务器上测试Linux上的pthread并行代码.
单线程版本很简单,它用于初始化10000*10000矩阵:
int main(int argc) { int size = 10000; int * r = (int*)malloc(size * size * sizeof(int)); for (int i=0; i然后我想看看并行代码是否可以提高性能:
#include#include #include int size = 10000; void *SetOdd(void *param) { printf("Enter odd\n"); int * r = (int*)param; for (int i=0; i 简单的代码运行大约0.8秒,而多线程版本运行大约10秒!!!!!!!
我在4核服务器上运行.但为什么多线程版本如此之慢?
1> P.P...:
rand()
既不是线程安全也不是重入.所以你不能rand()
在多线程应用程序中使用.使用
rand_r()
替代这也是一个伪随机数发生器,是线程安全的.如果你在乎.使用rand_r()
更短的执行时间结果我有2个内核(大约一半的时间作为单线程版本)系统上的代码.在两个线程函数中,执行:
void *SetOdd(void *param) { printf("Enter odd\n"); unsigned int s = (unsigned int)time(0); int * r = (int*)param; for (int i=0; i
更新:
虽然C和POSIX标准确实要求
rand()
是一个线程安全的函数,但glibc
实现(在Linux上使用)实际上确实以线程安全的方式实现它.如果我们看一下rand()的glibc实现,就会有一个锁:
291 __libc_lock_lock (lock); 292 293 (void) __random_r (&unsafe_state, &retval); 294 295 __libc_lock_unlock (lock); 296任何同步构造(互斥,条件变量等)都不利于性能,即代码中使用的此类构造的数量越少,性能就越好(当然,我们无法完全避免在多线程应用程序中确定它们).
因此,只有一个线程可以实际访问随机数生成器,因为两个线程一直在争夺锁定.这解释了为什么
rand()
导致多线程代码性能不佳.