在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;
}
}
答案 0 :(得分:2)
无论如何编译器都不会朝这个方向进行优化,但是我们可以通过添加适当的范围而不是仅仅增加来节省一些乘法,并且可以通过在循环外设置初始起点来节省一些相乘。另外,使用指针算法,我们只需要加法的一半(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++;
}
}
使用memcpy:
byte* end = dstdata + height * lockedRectSubImg.Pitch;
int xrange = width * bytes;
for (; dstdata < end; dstdata += lockedRectSubImg.Pitch, srcdata += xrange)
{
memcpy(dstdata, srcdata, xrange);
}
未经测试的代码,但是,如果您发现错误,也可以找到青蛙来喂它...