这个问题是关于我之前问过的同一个程序。回顾一下,我有一个具有如下循环结构的程序:
for (int i1 = 0; i1 < N; i1++)
for (int i2 = 0; i2 < N; i2++)
for (int i3 = 0; i3 < N; i3++)
for (int i4 = 0; i4 < N; i4++)
histogram[bin_index(i1, i2, i3, i4)] += 1;
bin_index
是其论点的完全确定性函数,就这个问题而言,它不使用或更改任何共享状态 - 换句话说,它显然是可重入的。
我第一次编写这个程序是为了使用单线程。然后我将它转换为使用多个线程,这样线程n
运行外部循环 where 的所有迭代i1 % nthreads == n
。所以在每个线程中运行的函数看起来像
for (int i1 = n; i1 < N; i1 += nthreads)
for (int i2 = 0; i2 < N; i2++)
for (int i3 = 0; i3 < N; i3++)
for (int i4 = 0; i4 < N; i4++)
thread_local_histogram[bin_index(i1, i2, i3, i4)] += 1;
并且所有的thread_local_histogram
s 都在最后添加到主线程中。
奇怪的是:当我只用 1 个线程运行程序以进行某些特定大小的计算时,大约需要 6 秒。当我用 2 或 3 个线程运行它时,进行完全相同的计算,大约需要 9 秒。这是为什么?我希望使用 2 个线程会比 1 个线程快,因为我有一个双核 CPU。该程序不使用任何互斥锁或其他同步原语,因此两个线程应该能够并行运行。
time
供参考:一个线程(这是在 Linux 上)的典型输出:
real 0m5.968s
user 0m5.856s
sys 0m0.064s
和两个线程:
real 0m9.128s
user 0m10.129s
sys 0m6.576s
代码位于http://static.ellipsix.net/ext-tmp/distintegral.ccs
PS我知道有专门为这种事情设计的库可能会有更好的性能,但这就是我的最后一个问题,所以我不需要再次听到这些建议。(另外我想使用 pthreads 作为学习经验。)