我正在尝试并行化矩阵处理程序。使用 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;
}
}
这背后一定有一个合理的解释,这样的程序预期不同的执行时间是否合理?