C+中的奇怪性能+;(VC 2010) 我有这个C++写的循环,用MSVC2010编译的需要很长时间才能运行。(300毫秒) for(int i=0;i
要查看的一些内容:C+中的奇怪性能+;(VC 2010) 我有这个C++写的循环,用MSVC2010编译的需要很长时间才能运行。(300毫秒) for(int i=0;i,c++,performance,assembly,C++,Performance,Assembly,要查看的一些内容: 您需要检查实际代码是否相同。如中所示,您的内联汇编语句是否与编译器生成的语句完全相同?我可以看到三个潜在差异(可能是因为它们可能会被优化)。第一个是将val初始设置为零,第二个是额外变量val1(不太可能,因为它很可能只是更改堆栈指针的常量减法),第三个是内联程序集版本可能不会将临时结果放回val 你需要确保你的样本空间很大。你没有提到你是每个版本只运行了一次还是运行了100次,但运行次数越多越好,这样可以消除统计数据中“噪音”的影响 更好的衡量标准是CPU时间,而不是运行
- 您需要检查实际代码是否相同。如中所示,您的内联汇编语句是否与编译器生成的语句完全相同?我可以看到三个潜在差异(可能是因为它们可能会被优化)。第一个是将
初始设置为零,第二个是额外变量val
(不太可能,因为它很可能只是更改堆栈指针的常量减法),第三个是内联程序集版本可能不会将临时结果放回val1
val
- 你需要确保你的样本空间很大。你没有提到你是每个版本只运行了一次还是运行了100次,但运行次数越多越好,这样可以消除统计数据中“噪音”的影响
- 更好的衡量标准是CPU时间,而不是运行时间。运行时间取决于环境变化(如病毒检查器或某个服务在测试时决定执行某些操作)。大样本空间将缓解但不一定解决这一问题
精确的
、严格的
或快速的
(请参见/fp
选项)。我怀疑您的原始代码是使用一些限制过多的浮点模型编译的(在代码的第二个版本中,程序集后面没有),这就是为什么原始版本要慢得多的原因
换句话说,如果最初的模型确实限制太多,那么你只是简单地将苹果和橙子进行比较。这两个版本实际上没有做相同的事情,尽管乍一看可能是这样
例如,请注意,在代码的第一个版本中,中间总和累积在浮点值中。如果使用precise
模型编译,则中间结果必须四舍五入到float
类型的精度,即使变量val
已优化,且内部F在您的汇编代码中,您不必费心去舍入累积的结果,这可能有助于提高其性能
我建议您在/fp:fast
模式下编译这两个版本的代码,并查看它们在这种情况下的性能比较。您是否尝试过在这两种情况下比较生成的汇编代码…谢谢!我已经在fast模式下运行了我的原始代码,现在它在80ms内运行,而第二个版本在fast模式下仍在150ms下运行,所以我猜compiler仍然更清楚:)我找到了这些用于MSVC切换每个函数的浮点精度(在函数内部不起作用)的pragma选项:#pragma float_控件(precise、off、push)…这里的代码…#pragma float_控件(pop),但更具体地说:
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;
}
}
}
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;
}
}
}