使用SSE加速lower_bound函数

fok*_*ute 3 c x86 assembly sse x86-64


在一个项目中,我目前的工作,我经常需要找到在其中的元素可以插入一个排序的数组可能的最低指数(C中类似的std :: LOWER_BOUND ++).我使用SSE加速我的算法似乎很吸引人,因为我正在使用uint32数组,其大小通常是处理器缓存行的大小.我之前从未使用过SSE指令,所以我无法弄清楚这个函数的SSE实现会是什么样子.请给出提示,以帮助我最好地用SSE写出来.

Bil*_*eal 9

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

此外,在转向内联汇编之前,您应该知道无论何时使用内联汇编,都会破坏程序该部分可能出现的大多数编译器优化,并且通常会导致程序运行速度变慢 - 编译器通常编写更好的汇编程序比我们人类做的.

如果要使用SSE,最好使用内在函数 - 编译器提供的特殊"函数"或关键字,它们调用SSE指令但允许进行优化.这些内在函数可以在Microsoft的Visual C++以及GNU Compiler Collection中找到.(可能是大多数编译器.请参阅编译器的文档)

std::lower_bound您应该尝试不需要首先调用它,而不是尝试加速使用SSE.例如,如果你经常使用元素插入向量中lower_bound,你应该知道你有效创建的是插入排序,并且插入排序很差,这需要四维时间.您可能最好只将新元素放在向量的末尾,然后在需要对其进行排序时对向量进行排序,从而将事物简化为O(n lg n)排序.如果您的数据访问模式过于频繁,那么您应该使用类似的东西std::set,它为插入提供O(lg n)操作,而不是您当前获得的O(n + lg n)插入与矢量.

当然,请记住基准测试:)