【问题标题】:Using SSE to speed up lower_bound function使用 SSE 加速 lower_bound 函数
【发布时间】:2011-01-22 20:12:43
【问题描述】:


在我目前正在处理的项目中,我经常需要在可以插入元素的排序数组中找到可能的最低索引(如 C++ 中的 std::lower_bound )。 使用 SSE 来加速我的算法对我来说似乎很有吸引力,因为我正在使用 uint32 数组,它的大小通常是处理器缓存线的大小。 我以前从未使用过 SSE 指令,所以我无法弄清楚这个函数的 SSE 实现是什么样的。请提供提示以帮助我使用 SSE 以最佳方式写出。

【问题讨论】:

  • 花时间做一些研究。然后考虑一下,也许尝试一些事情来“感觉”它是如何工作的。然后问一个更有针对性的问题——这里没有问题。
  • 我找到了将 4 个 32 位压缩整数与 32 位操作数进行比较的 pcmpled,但我无法找到如何获得该指令的结果。如果你有的话,也许你可以指出如何使用这个指令(或相应的内在指令)的一个很好的参考?
  • 好像我错了; pcmpled 比较两个 32 位整数的 vector4,并根据比较结果用 0 和 1 填充 vec4。对我来说没有什么可利用的。似乎比利奥尼尔是对的,SSE 对我没用。

标签: c assembly x86 x86-64 sse


【解决方案1】:

没有像std::lower_bound 这样的东西可以使用 SSE 很好地扩展。 SSE 使事情变得更快的原因是它允许您一次进行多个计算。例如,一条 SSE 指令可能会导致同时进行 4 次乘法运算。但是std::lower_bound的操作方式不能并行化,因为算法中的每一步都需要前一步的比较结果。另外,它已经是 O(lg n),因此不太可能成为瓶颈。

此外,在转向内联汇编之前,您应该知道,无论何时使用内联汇编,都会使程序的该部分可能发生的大多数编译器优化失败,因此您的程序通常会变慢 - 编译器通常编写比我们人类更好的汇编程序。

如果您想使用 SSE,最好使用 intrinsics -- 编译器提供的特殊“函数”或关键字,它们调用 SSE 指令,但允许进行优化。此类内在函数在 Microsoft's Visual C++GNU Compiler Collection 中可用。 (可能是大多数编译器。请查阅编译器的文档)

与其尝试使用 SSE 加速 std::lower_bound,不如一开始就不需要调用它。例如,如果您经常使用lower_bound 将元素插入向量中,您应该知道您有效创建的是insertion sort,并且插入排序很差,这将需要二次时间。您可能最好将新元素简单地放在向量的末尾,然后在需要排序时对向量进行排序,这会将事情减少到 O(n lg n) 排序。如果您的数据访问模式过于频繁,那么您应该使用 std::set 之类的东西,它为插入提供 O(lg n) 操作,而不是您的 O(n + lg n) 插入目前正在使用向量。

当然,记得进行基准测试 :)

【讨论】:

    猜你喜欢
    • 2015-08-15
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2013-09-08
    相关资源
    最近更新 更多