gpt4 book ai didi

c - 为什么 CILK_NWORKERS 会影响只有一个 cilk_spawn 的程序?

转载 作者:行者123 更新时间:2023-11-30 15:29:51 27 4
gpt4 key购买 nike

我正在尝试并行化矩阵处理程序。使用 OpenMP 后,我决定也检查一下 CilkPlus,我注意到以下几点:

在我的 C 代码中,我仅在一个部分应用并行性,即:

//(test_function declarations)

cilk_spawn highPrep(d, x, half);

d = temp_0;
r = malloc(sizeof(int)*(half));
temp_1 = r;
x = x_alloc + F_EXTPAD;
lowPrep(r, d, x, half);

cilk_sync;

//test_function return

根据我到目前为止阅读的文档,cilk_spawn 预计 - 可能 - (CilkPlus 不强制并行)采用 highPrep() 函数并在另一个可用的硬件线程中执行它,然后继续其余代码的执行,包括函数 lowPrep()。然后,在执行其余代码之前,线程应在 cilk_sync 处同步。

我在 8 核/16 线程 Xeon E5-2680 上运行此程序,除了我的实验之外,它在任何给定时间都不会执行任何其他操作。我现在的问题是,我注意到当我更改环境变量 CILK_NWORKERS 并尝试诸如 2、4、8、16 之类的值时,test_function 需要执行的时间会发生很大的变化。特别是,CILK_NWORKERS 设置得越高(2 之后),函数变得越慢。这对我来说似乎违反直觉,因为我希望可用线程数不会改变 cilk_spawn 的操作。我希望如果有 2 个线程可用,那么函数 highPrep 将在另一个线程上执行。我希望任何超过 2 个线程的线程都保持空闲状态。

highPrep 和 lowPrep 函数是:

void lowPrep(int *dest, int *src1, int *src2, int size)
{
double temp;
int i;
for(i = 0; i < size; i++)
{
temp = -.25 * (src1[i] + src1[i + 1]) + .5;
if (temp > 0)
temp = (int)temp;
else
{
if (temp != (int)temp)
temp = (int)(temp - 1);
}
dest[i] = src2[2*i] - (int)(temp);
}
}

void highPrep(int *dest, int *src, int size)
{
double temp;
int i;
for(i=0; i < size + 1; i++)
{
temp = (-1.0/16 * (src[-4 + 2*i] + src[2 + 2*i]) + 9.0/16 * (src[-2 + 2*i] + src[0 + 2*i]) + 0.5);
if (temp > 0)
temp = (int)temp;
else
{
if (temp != (int)temp)
temp = (int)(temp - 1);
}
dest[i] = src[-1 + 2*i] - (int)temp;
}
}

这背后一定有一个合理的解释,对于这样的程序期望不同的执行时间是否合理?

最佳答案

澄清:Cilk 执行的是“连续窃取”,而不是“子窃取”,因此 highPrep 始终与其调用者在同一硬件线程上运行。这是“其余代码”可能最终在不同的线程上运行。请参阅this primer以获得更全面的解释。

至于速度减慢,这可能是由于实现偏向于高度并行性而导致的,这可能会消耗所有线程。额外的线程正在寻找工作,在此过程中,会消耗一些内存带宽,对于超线程处理器来说,会消耗一些核心周期。 Linux“完全公平调度程序”在这方面给我们带来了一些麻烦,因为 sleep(0) 不再放弃时间片。额外的线程也可能导致操作系统将软件线程映射到计算机的效率较低。

问题的根源在于一个棘手的权衡:积极地运行窃贼可以让他们在出现工作时更快地接手工作,但如果没有工作可用,也会导致他们不必要地消耗资源。在没有可用工作时让小偷进入休眠状态可以节省资源,但会增加大量的生成开销,因为现在生成线程必须检查是否有 sleep 线程需要唤醒。 TBB 支付了这笔开销,但对于 TBB 来说并不多,因为无论如何 TBB 的生成开销要高得多。当前的 Cilk 实现确实支付了此税:它仅在顺序执行期间使工作线程休眠。

我能给出的最好(但不完美)的建议是找到更多的并行性,这样工作线程就不会长时间闲置并造成麻烦。

关于c - 为什么 CILK_NWORKERS 会影响只有一个 cilk_spawn 的程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26003918/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com