Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+中的奇怪性能+;(VC 2010) 我有这个C++写的循环,用MSVC2010编译的需要很长时间才能运行。(300毫秒) for(int i=0;i_C++_Performance_Assembly - Fatal编程技术网

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;
        }
    }
}