【问题标题】:I want both implementations of __builtin_popcountll我想要 __builtin_popcountll 的两个实现
【发布时间】:2012-11-26 06:49:07
【问题描述】:

我有一些代码想要运行快速内置 CPU 指令 popcnt(当 __builtin_popcountll 使用适当的标志编译时,例如使用 g++ -mpopcntclang++ -march=corei7,会发生这种情况),但是当cpuid 显示 CPU 不支持 HW 指令时,也能够回退到代码。

当然,为了获得我相信编译器人员已经正确实现的后备代码(所以我不必引入 C 或 asm 代码来进行 popcount),我需要一个单独的编译单元来编译没有 -mpopcnt-march=corei7 标志。

将单独编译的代码链接在一起是唯一的方法吗?是否没有编译器内在函数或其他类型的提示或其他我不知道的内置函数可以用来让它生成后备 popcount 代码?

【问题讨论】:

    标签: gcc compiler-construction bit-manipulation clang instructions


    【解决方案1】:

    我不确定,但是在 popcnt 指令和回退实现之间进行选择所需的代码成本可能比一直使用非 popcnt 实现对性能的影响更大。

    要在替代实现中切换(在 popcnt 的站点进行切换),您至少需要以下内容:

    • 加载并检查 cpuid 位 (CPUID.01H:ECX.POPCNT[Bit 23])
    • 选择 popcnt 或替代实现的分支
    • 可能保存/恢复备用实现所需的寄存器
    • 如果替代实现基于 SSE 或 AVX,则可能将数据移动到 SIMD 寄存器

    我怀疑成本会阻碍您描述的内在函数的有效实现。

    【讨论】:

    • 嗯。所以,我需要做一些事情,比如用两个版本“展开”内部循环,并不太动态地从它们中选择,以便看到这样做的实际好处。没关系,这个问题有点模糊,实际上只是“如何让它发挥作用”,“它不实用”并不是一个完美的答案。
    • 具体来说:如何在同一个编译单元中生成两个替代实现(我相信它们使用相同的内在函数)?
    【解决方案2】:

    您可以直接调用“回退代码”。我相信标准库可以通过以下方式访问它:

    int __popcountsi2 (int a)
    int __popcountdi2 (long a)
    int __popcountti2 (long long a)
    

    【讨论】:

      【解决方案3】:

      gcc 有一个专门用于此的称为“多版本化”的功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多