C语言 优化双循环



在X86 平台上优化以下双循环的最佳方法是什么? 该代码是将像素数据复制到锁定的 Direct3D 纹理中的例程。

由于我的目标平台及其限制,我使用的是 2003 年的编译器。 这么旧的编译器是否能够与我用汇编语言编写此代码时的速度相匹配?还是有一些技巧可以用来加速 C 代码?也许使用memcpy()会更快。

int x, y;
byte *srcdata = (byte *)compatablePixels;
byte *dstdata = (byte *)lockedRectSubImg.pBits;
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
dstdata[lockedRectSubImg.Pitch * y + bytes * x ] = srcdata[0];
dstdata[lockedRectSubImg.Pitch * y + bytes * x + 1] = srcdata[1];
dstdata[lockedRectSubImg.Pitch * y + bytes * x + 2] = srcdata[2];
dstdata[lockedRectSubImg.Pitch * y + bytes * x + 3] = srcdata[3];
srcdata += bytes;
}
}

无论如何,编译器朝这个方向优化的可能性不大,但我们可以通过添加适当的范围而不是仅仅递增来节省一些乘法,并且我们可以通过在循环外设置初始起点来节省一些加法; 此外,使用指针算法,我们只需要一半的加法(x[y] 相当于 *(x + y)!

byte* srcdata = (byte*)compatablePixels;
// moving out of loop as many operations as possible:
byte* dstdata = (byte*)lockedRectSubImg.pBits
+ lockedRectSubImg.Pitch * yoffset + xoffset;
byte* end = dstdata + height * lockedRectSubImg.Pitch;
int xrange = width * bytes;
int step = lockedRectSubImg.Pitch - width * bytes;
// += step: avoid multiplications inside loop!
for (; dstdata < end; dstdata += step)
{
for (x = xrange; x != 0; x--)
// on some platforms, comparing against 0 is faster; at least, it is never slower...
{
dstdata++ = srcdata++;
}
}

使用内存:

byte* end = dstdata + height * lockedRectSubImg.Pitch;
int xrange = width * bytes;
for (; dstdata < end; dstdata += lockedRectSubImg.Pitch, srcdata += xrange)
{
memcpy(dstdata, srcdata, xrange);
}

未经测试的代码,但是,如果您发现错误,请找到一只青蛙来喂它......

最新更新