Optimization 位移位和UInt64是如何工作的?

Optimization 位移位和UInt64是如何工作的?,optimization,Optimization,在StackOverflow上阅读帖子时(http://stackoverflow.com/questions/1502081/im-trying-to-optimize-this-c-code-using-4-way-loop-unrolling),现在标记为关闭,我看到一个答案(事实上是评论)说:“两个内部循环可能通过使用UInt64和位移位来提高速度” 以下是帖子中的代码: char rotate8_descr[] = "rotate8: rotate with 8x8 blocking"

在StackOverflow上阅读帖子时(http://stackoverflow.com/questions/1502081/im-trying-to-optimize-this-c-code-using-4-way-loop-unrolling),现在标记为关闭,我看到一个答案(事实上是评论)说:“两个内部循环可能通过使用UInt64和位移位来提高速度”

以下是帖子中的代码:

char rotate8_descr[] = "rotate8: rotate with 8x8 blocking";

    void rotate8(int dim, pixel *src, pixel *dst) 
    {

    int i, j, ii, jj;

    for(ii = 0; ii < dim; ii += 8)
           for(jj = 0; jj < dim; jj += 8)
                  for (i = ii; i < ii + 8; i++)   
                      for (j = jj; j < jj + 8; j++)
                          dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];
    }
char rotate8_descr[]=“rotate8:使用8x8块旋转”;
无效旋转8(整数尺寸,像素*src,像素*dst)
{
int i,j,ii,jj;
对于(ii=0;ii
有人能解释一下这在这里是如何应用的吗?我很想知道如何在此代码或类似代码上应用位移位,以及为什么这会有助于提高性能。另外,该代码如何针对缓存使用进行优化?有什么建议吗

假设此代码是双平铺/分块的(大平铺=32,其中平铺为16),并且应用了循环不变代码运动。。它还会从位移位和UInt64中获益吗

如果没有,那么还有什么其他建议可行


谢谢

如果像素较小,您可以使用8个Uint64寄存器(它们很大,而且有很多)来累积旋转矩阵的结果

sizeof(pixel)==1和little-endian机器的示例:

for (int y = 0; y < 8; ++y){
 // for every line, we get 8 pixels from row y into src0.
 // they should go in the last colomn of the result
 // so after 8 iterations they'll get exactly in the 8ht byte 
  Uint64 src0 = *(Uint64*)(src + dim * y);
  dst0 = (dst0 << 8) | ( src0 & 0xff); // this was pixel src[y][0]
  dst1 = (dst1 << 8) | ((src0 >> 8) & 0xff); // and pixel src[y][1]
  etc...
};
// now the 8 dst0..dst7 registers contain rows 0..7 of the result. 
// putting them there
*(Uint64*)(dst) = dst0;
*(Uint64*)(dst + dim) = dst1;
etc..
for(int y=0;y<8;++y){
//对于每一行,我们从y行到src0得到8个像素。
//他们应该排在结果的最后一列
//因此,经过8次迭代后,它们将精确地得到8ht字节
Uint64 src0=*(Uint64*)(src+dim*y);
dst0=(dst0 8)&0xff);//和像素src[y][1]
等
};
//现在,8个dst0..dst7寄存器包含结果的第0..7行。
//把它们放在那里
*(Uint64*)(dst)=dst0;
*(Uint64*)(dst+dim)=dst1;
等

好的方面是它更容易展开和重新排序,并且内存访问更少

RIDX宏看起来像什么?您的意思是:
#定义RIDX(i,j,n)((i)*(n)+(j))
?类型定义结构{无符号短红色;/*R值/无符号短绿色;/G值/无符号短蓝色;/B值*/}像素;你的意思是,就目前的“像素”大小而言,我不能用这个?当然可以,但小像素的好处可能更大。无论如何,如果您能帮助编译器仅在对齐的地址上以64位块访问内存,那就太好了。让它在未对齐的6字节结构上工作是非常低效的。我有点明白这个概念。但是,你能详细说明一下如何在我的案例中应用这一点吗?第二行之后我有点迷路了。。你能把代码继续写到最后吗,这样我就可以测试并理解整个画面了?我知道这可以通过刷新一次来减少内存读取,但我想确保我正确理解了这个概念,从而吸收它。。你能把它应用到最内部的循环上吗,就像我拥有的“像素”大小一样?当你说:dst0=(dst0