代码之家  ›  专栏  ›  技术社区  ›  Quonux

Visual C++ 2008/2010编译器的优化程度如何?

  •  3
  • Quonux  · 技术社区  · 14 年前

    我只是想知道MSVC++编译器能优化代码(用代码示例)有多好,或者他不能优化什么,为什么。

    例如,我将SSE intrinsics与以下内容结合使用(var是一个uum128值)(这是一个frustrum剔除测试):

    if( var.m128_f32[0] > 0.0f && var.m128_f32[1] > 0.0f && var.m128_f32[2] > 0.0f && var.m128_f32[3] > 0.0f ) {
        ...
    }
    

    什么优化是它不能做的(直到现在)。

    这是否意味着当今技术的im被迫使用内部函数、内联ASM和链接ASM函数,编译器是否会找到这样的东西(我不这么认为)?

    我在哪里可以读到更多关于MSVC++编译器优化效果的信息?

    (编辑1): 我使用了SSE2开关和FP:快速开关

    5 回复  |  直到 14 年前
        1
  •  4
  •   gbjbaanb    14 年前

    编译器的默认设置是生成将在“最小公分母”CPU上运行的代码,即没有SSE 4.1指令的CPU。

    您可以通过只在构建选项中针对稍后的cpu来改变这一点。

    SSE optimisation . 我甚至不确定它是否支持SSE4。该链接为GCC的SSE优化提供了良好的信誉:

    关于GCCs的旁注 完美的代码生成 看到它甚至超过 英特尔自己的编译器

    也许你需要换个编译器!

        2
  •  2
  •   Paul R    13 年前

    你可能想试试英特尔的ICC编译器——在我的经验中,它比Visual C++生成了很多更好的代码,特别是对于SSE代码。您可以从intel.com获得30天免费试用许可证。

        3
  •  1
  •   Klaim    14 年前

    您可以激活已编译代码的asm视图并查看生成的代码。

        4
  •  0
  •   liori    14 年前

    查看演示文稿 http://lambda-the-ultimate.org/node/3674

    总结:编译器现在通常会有很多惊人的技巧,甚至是一些似乎与命令式编程无关的事情,比如尾部调用优化。MSVC++虽然不是最好的,但是看起来还是不错的。

        5
  •  0
  •   Olof Forshell    14 年前

    除非您可以使用条件移动,否则f语句将生成条件跳转,但这更可能是在手写汇编中完成的。有一些规则控制CPU的条件跳转假设(分支预测),这样,沿着规则运行的条件跳转的惩罚是可以接受的。然后是无序执行,使事情更加复杂:)。底线是,如果代码是直接向前的,那么最终发生的跳转不会影响性能。你可以看看阿格纳·福格的 optimization pages .

    C代码的非调试编译应该生成四个条件跳转。逻辑与&)括号的使用将导致从左到右的测试,因此一个C优化可能是测试最有可能是>0.0f(如果可以确定这种概率)。您有五种可能的执行变体:test1 true branch taken(t1tbt)、test1 false no branch(t1fnb)test2 true branch taken(t2tbt)等,给出以下可能的序列

    t1tbt                      ; var.m128_f32[0] <= 0.0f
    t1fnb t2tbt                ; var.m128_f32[0] >  0.0f, var.m128_f32[1] <= 0.0f
    t1fnb t2fnb t3tbt          ; var.m128_f32[0] >  0.0f, var.m128_f32[1] >  0.0f,
                               ; var.m128_f32[2] <= 0.0f
    t1fnb t2fnb t3fnb t4tbt    ; var.m128_f32[0] >  0.0f, var.m128_f32[1] >  0.0f,
                               ; var.m128_f32[2] >  0.0f, var.m128_f32[3] <= 0.0f
    t1fnb t2fnb t3fnb t4fnb    ; var.m128_f32[0] >  0.0f, var.m128_f32[1] >  0.0f
                               ; var.m128_f32[2] >  0.0f, var.m128_f32[3] >  0.0f
    

    假设浮点值的测试成本很高(它们是),如果var是一个并集,并且您精通浮点输入输出,那么您可以考虑对重叠类型进行整数测试。例如,存储值1.0f占用存储为0x00、0x00、0x80、0x3f(x86/little endian)的四个字节。将此值作为长整数读取将得到0x3f80000或+10653216。0.0f是0x00、0x00、0x00、0x00或0x00000000(长)。负浮点值的格式与正浮点值完全相同,但设置了最高位(0x80000000)。