我有一个 496*O(N^3) 循环。我正在执行一种阻塞优化技术,我一次操作 2 个图像而不是 1 个。在原始术语中,我正在展开外循环。(代码的非展开版本如下所示:)顺便说一句,我使用的是 Intel Xeon X5365 机器,它有 8 个核心,它有 3GHz 时钟,1333MHz 总线频率,共享 8MB L2(每 2 个核心共享 4MB) ,L1-I 32KB,L1-D 32KB。
for(imageNo =0; imageNo<496;imageNo++){
for (unsigned int k=0; k<256; k++)
{
double z = O_L + (double)k * R_L;
for (unsigned int j=0; j<256; j++)
{
double y = O_L + (double)j * R_L;
for (unsigned int i=0; i<256; i++)
{
double x[1] = {O_L + (double)i * R_L} ;
double w_n = (A_n[2] * x[0] + A_n[5] * y + A_n[8] * z + A_n[11]) ;
double u_n = ((A_n[0] * x[0] + A_n[3] * y + A_n[6] * z + A_n[9] ) / w_n);
double v_n = ((A_n[1] * x[0] + A_n[4] * y + A_n[7] * z + A_n[10]) / w_n);
for(int loop=0; loop<1;loop++)
{
px_x[loop] = (int) floor(u_n);
px_y[loop] = (int) floor(v_n);
alpha[loop] = u_n - px_x[loop] ;
beta[loop] = v_n - px_y[loop] ;
}
if(px_y[0]>=0 && px_y[0]<(int)threadCopy[0].S_y)
{
if (px_x[0]>=0 && px_x[0]<(int)threadCopy[0].S_x )
///////////////////(i,j) pixels ///////////////////////////////
pixel_1[0] = threadCopy[0].I_n[px_y[0] * threadCopy[0].S_x + px_x[0]];
else
pixel_1[0] =0.0;
if (px_x[0]+1>=0 && px_x[0]+1<(int)threadCopy[0].S_x)
/////////////////// (i+1, j) pixels/////////////////////////
pixel_1[2] = threadCopy[0].I_n[px_y[0] * threadCopy[0].S_x + (px_x[0]+1)];
else
pixel_1[2] = 0.0;
}
else{
pixel_1[0] =0.0;
pixel_1[2] =0.0;
}
if( px_y[0]+1>=0 && px_y[0]+1<(int)threadCopy[0].S_y)
{
if (px_x[0]>=0 && px_x[0]<(int)threadCopy[0].S_x)
pixel_1[1] = threadCopy[0].I_n[(px_y[0]+1) * threadCopy[0].S_x + px_x[0]];
else
pixel_1[1] = 0.0;
if (px_x[0]+1>=0 && px_x[0]+1<(int)threadCopy[0].S_x)
pixel_1[3] = threadCopy[0].I_n[(px_y[0]+1) * threadCopy[0].S_x + (px_x[0]+1)];
else
pixel_1[3] = 0.0;
}
else{
pixel_1[1] = 0.0;
pixel_1[3] = 0.0;
}
pix_1 = (1.0 - alpha[0]) * (1.0 - beta[0]) * pixel_1[0] + (1.0 - alpha[0]) * beta[0] * pixel_1[1]
+ alpha[0] * (1.0 - beta[0]) * pixel_1[2] + alpha[0] * beta[0] * pixel_1[3];
f_L[k * L * L + j * L + i] += (float)(1.0 / (w_n * w_n) * pix_1);
}
}
}
我使用 Intel Vtune-2013(使用从 gcc-4.1 创建的二进制文件)分析了结果,我可以看到内存带宽使用量减少了 40%,这是预期的,因为每次迭代都会处理 2 个图像。(f_L 存储操作导致每个体素 8 字节的流量)。这占总线周期减少 11.7%!此外,由于在内部循环中增加了块大小,资源停顿减少了 25.5%。这两个占响应时间减少 18%。神秘的问题是,为什么退休的指令增加了 7.9%?(这导致响应时间增加了 6.51%) - 我可以这样做的可能原因是: 1. 由于块内的分支指令数量增加(并且核心架构具有 8 位全局历史)退休的分支指令增加了 2.5% ( 虽然,错误预测保持不变!我知道,闻起来很腥对吧?!!)。但我仍然缺少其余 5.4% 的答案!任何人都可以向我阐明任何方向吗?我完全没有选择,也没有办法思考。非常感谢!!