【发布时间】:2017-12-26 20:39:52
【问题描述】:
我不确定我还能如何优化这段代码以使其高效。到目前为止,我已经将内部 for 循环相对于 j 展开了 16 倍,它产生的平均 CPE 为 1.4。我需要通过优化技术获得大约 2.5 的平均 CPE。我已经阅读了其他可用的问题,与我的问题所涉及的代码相比,它们有点不同。代码的第一部分显示了我得到的内容,然后是我尝试展开循环。给定的代码将扫描源图像矩阵的行并复制到目标图像矩阵的翻转行。任何帮助将不胜感激!
RIDX 宏:
#define RIDX(i,j,n) ((i)*(n)+(j))
给定:
void naive_rotate(int dim, struct pixel_t *src, struct pixel_t *dst)
{
int i, j;
for(i = 0; i < dim; i++)
{
for(j = 0; j < dim; j++)
{
dst[RIDX(dim-1-i, j, dim)] = src[RIDX(i, j, dim)];
}
}
}
我的尝试:这确实对其进行了优化,但随着平均 CPE 从 1.0 上升到 1.4,它只是稍微优化了一点。我希望它在 2.5 左右,并且我尝试了各种类型的阻塞和我在网上阅读过的东西,但没有设法对其进行更多优化。
for(i = 0; i < dim; i++){
for(j = 0; j < dim; j+=16){
dst[RIDX(dim-1-i,j, dim)] = src[RIDX(i,j,dim)];
dst[RIDX(dim-1-i,j+1, dim)] = src[RIDX(i,j+1,dim)];
dst[RIDX(dim-1-i,j+2, dim)] = src[RIDX(i,j+2,dim)];
dst[RIDX(dim-1-i,j+3, dim)] = src[RIDX(i,j+3,dim)];
dst[RIDX(dim-1-i,j+4, dim)] = src[RIDX(i,j+4,dim)];
dst[RIDX(dim-1-i,j+5, dim)] = src[RIDX(i,j+5,dim)];
dst[RIDX(dim-1-i,j+6, dim)] = src[RIDX(i,j+6,dim)];
dst[RIDX(dim-1-i,j+7, dim)] = src[RIDX(i,j+7,dim)];
dst[RIDX(dim-1-i,j+8, dim)] = src[RIDX(i,j+8,dim)];
dst[RIDX(dim-1-i,j+9, dim)] = src[RIDX(i,j+9,dim)];
dst[RIDX(dim-1-i,j+10, dim)] = src[RIDX(i,j+10,dim)];
dst[RIDX(dim-1-i,j+11, dim)] = src[RIDX(i,j+11,dim)];
dst[RIDX(dim-1-i,j+12, dim)] = src[RIDX(i,j+12,dim)];
dst[RIDX(dim-1-i,j+13, dim)] = src[RIDX(i,j+13,dim)];
dst[RIDX(dim-1-i,j+14, dim)] = src[RIDX(i,j+14,dim)];
dst[RIDX(dim-1-i,j+15, dim)] = src[RIDX(i,j+15,dim)];
【问题讨论】:
-
我们可以假设您已经在编译器中提高了优化级别,看看它可以为您做什么?如果没有,我建议从那里开始。
-
不,我没有这样做。我不完全了解它是如何工作的。我应该通过阻塞、展开和运动等常用技术对其进行优化。
-
RIDX 宏中有什么?了解这一点很重要。
-
只有当 dim 是 16 的倍数时,循环展开才有效... :(
-
通过尝试仅安排指针操作,我很快就使用 memcpy 获得了相当好的结果 - 速度极快的 bioost。使用 memcpy 复制/移动 pixel_t 是否安全?可以展示一下吗?
标签: c++ optimization