Optimization 位移位和UInt64是如何工作的?
在StackOverflow上阅读帖子时(http://stackoverflow.com/questions/1502081/im-trying-to-optimize-this-c-code-using-4-way-loop-unrolling),现在标记为关闭,我看到一个答案(事实上是评论)说:“两个内部循环可能通过使用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"
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