rai*_*ndi 5 c++ performance assembly
我有用C++编写的这个循环,用MSVC2010编译需要很长时间才能运行.(300毫秒)
for (int i=0; i<h; i++) {
for (int j=0; j<w; j++) {
if (buf[i*w+j] > 0) {
const int sy = max(0, i - hr);
const int ey = min(h, i + hr + 1);
const int sx = max(0, j - hr);
const int ex = min(w, j + hr + 1);
float val = 0;
for (int k=sy; k < ey; k++) {
for (int m=sx; m < ex; m++) {
val += original[k*w + m] * ds[k - i + hr][m - j + hr];
}
}
heat_map[i*w + j] = val;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说有点奇怪,所以我做了一些测试,然后将一些位改为内联汇编:(具体来说,代码总和为"val")
for (int i=0; i<h; i++) {
for (int j=0; j<w; j++) {
if (buf[i*w+j] > 0) {
const int sy = max(0, i - hr);
const int ey = min(h, i + hr + 1);
const int sx = max(0, j - hr);
const int ex = min(w, j + hr + 1);
__asm {
fldz
}
for (int k=sy; k < ey; k++) {
for (int m=sx; m < ex; m++) {
float val = original[k*w + m] * ds[k - i + hr][m - j + hr];
__asm {
fld val
fadd
}
}
}
float val1;
__asm {
fstp val1
}
heat_map[i*w + j] = val1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在它运行的时间只有一半,150毫秒.它完全一样,但为什么它快两倍?在这两种情况下,它都在发布模式下运行并进行了优化.我在原始C++代码中做错了什么?
我建议你尝试编译器支持不同的浮点计算模型- precise,strict或fast(参见/fp作出任何结论之前,你的原码-选项).我怀疑您的原始代码是使用一些过于严格的浮点模型编译的(在代码的第二个版本中未跟随您的程序集),这就是原始速度慢得多的原因.
换句话说,如果原始模型确实过于严格,那么您只是将苹果与橙子进行比较.这两个版本并没有真正做同样的事情,即使它在第一眼看上去也是如此.
请注意,例如,在代码的第一个版本中,中间和累积在一个float值中.如果使用precise模型编译,则中间结果必须舍入为float类型的精度,即使变量val已被优化并且使用内部FPU寄存器.在汇编代码中,您不必费心舍入累计结果,这可能有助于提高其性能.
我建议你在/fp:fast模式下编译两个版本的代码,看看他们的表现在这种情况下的比较.