我正在对之前从文件中读取的矩阵执行模板计算。我使用两种不同的矩阵(非零类型和零类型)。两种类型共享边界值(通常为 1000),而其余元素对于零类型为 0,对于非零类型为 1。
该代码将文件的矩阵存储在两个相同大小的已分配矩阵中。然后它使用自己的值和邻居的值(add x 4 和 mul x 1)对一个矩阵的每个元素执行操作,并将结果存储在第二个矩阵中。一旦计算完成,矩阵的指针就会被交换,并且相同的操作会执行有限的次数。这里有核心代码:
#define GET(I,J) rMat[(I)*cols + (J)]
#define PUT(I,J) wMat[(I)*cols + (J)]
for (cur_time=0; cur_time<timeSteps; cur_time++) {
for (i=1; i<rows-1; i++) {
for (j=1; j<cols-1; j++) {
PUT(i,j) = 0.2f*(GET(i-1,j) + GET(i,j-1) + GET(i,j) + GET(i,j+1) + GET(i+1,j));
}
}
// Change pointers for next iteration
auxP = wMat;
wMat = rMat;
rMat = auxP;
}
我要公开的案例使用固定数量的 500 timeSteps(外部迭代)和 8192 行和 8192 列的矩阵大小,但是在更改 timeSteps 数量或矩阵大小时问题仍然存在。请注意,我只测量算法的具体部分的时间,因此从文件中读取矩阵或其他任何内容都会影响时间测量。
发生的情况是,根据我使用的矩阵类型,我得到不同的时间,在使用零类型时获得更差的性能(每个其他矩阵都与非零类型执行相同,因为我已经尝试生成一个充满随机数的矩阵值)。
我确定这是乘法运算,就好像我将其删除并仅保留加法一样,它们的执行方式相同。请注意,对于零矩阵类型,大多数类型的求和结果将为 0,因此运算将为“0.2*0”。
这种行为对我来说肯定很奇怪,因为我认为浮点运算独立于操作数的值,这看起来不像这里的情况。我还尝试捕获并显示 SIGFPE 异常以防出现问题,但我没有得到任何结果。
如果有帮助,我使用的是 Intel Nehalem 处理器和 gcc 4.4.3。