我编写了一个将矢量乘以矩阵的程序。矩阵周期性地重复了单元格,因此我在乘法之前使用临时变量对向量元素求和。相邻行的周期相同。我为每个线程创建一个单独的临时变量。 sizeof(InnerVector)== 400,我不想在每次渲染时为其分配内存(= 600次)。
代码看起来像这样:
tempsSize = omp_get_max_threads();
InnerVector temps = new InnerVector[tempsSize];
for(int k = 0; k < tempsSize; k++)
InnerVector_init(temps[k]);
for(int jmin = 1, jmax = 2; jmax < matrixSize/2; jmin *= 2, jmax *= 2)
{
int period = getPeriod(jmax);
#pragma omp parallel
{
int threadNum = omp_get_thread_num();
// printf("\n threadNum = %i", threadNum);
#pragma omp for
for(int j = jmin; j < jmax; j++)
{
InnerVector_reset(temps[threadNum]);
for(int i = jmin; i < jmax; i++)
{
InnerMatrix cell = getCell(i, j);
if(temps[threadNum].IsZero)
for(int k = j; k < matrixSize; k += period)
InnerVector_add(temps[threadNum], temps[threadNum], v[k]);
InnerVector_add_mul(v_res[i], cell, temps[threadNum]);
}
}
}
}
代码看起来是正确的,但结果错了。事实上,我对不同的运行得到不同的结果......有时结果是正确的。
当我在调试模式下编译时,结果总是正确的。 当我用“printf”取消注释行时,结果总是正确的。
P.S。我使用Visual Studio 2010。
答案 0 :(得分:3)
我怀疑可能会有数据竞争
InnerVector_add_mul(v_res[i], cell, temps[threadNum]);
由于v_res
似乎是结果向量,并且i
在并行化循环的每次迭代中从jmin
更改为jmax
,因此可能会发生多个线程写入至v_res[i]
的{{1}}值相同,结果不可预测。