首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSB() LSB() popcount()在numba

MSB() LSB() popcount()在numba
EN

Stack Overflow用户
提问于 2022-02-13 02:36:02
回答 1查看 143关注 0票数 1

我有一个使用numba的程序,需要使用MSB() LSB() POPCOUNT()等等--我似乎找不到与numba相关的任何引用,如何获得这些内置函数,比如python的bit_length()与numba一起工作?

代码语言:javascript
复制
Unknown attribute 'bit_length' of type int64

File "v.py", line 116:
def msb(x):
    return int(int(x).bit_length()) - 1
    ^
EN

回答 1

Stack Overflow用户

发布于 2022-02-13 12:09:28

Numba还没有提供popcount函数。虽然这个函数可以实现,但它显然不对用户友好(它需要深入研究Numba的工作方式和处理LLVM的方式),也不是可移植的(依赖于目标体系结构)。有关更多信息,请阅读文献资料关于本质和这个职位。如果您真的想走这条路,那么请注意,虽然可以在Numba中实现一个新的内部函数以满足您的需要,但popcount似乎还不支持LLVM-Lite JIT包装层和AFAIK,唯一的解决方案是直接从Lite调用内联程序集,这既不简单也不可移植(它甚至不适用于所有x86-64 CPU).

bit_lengthint对象的一种方法,它只对可变大小的整数有意义,但Numba不使用这种类型(如Numpy),因为与本地固定大小的数字相比,它们的开销非常大。

Numpy将函数,该函数可能稍后由Numba实现,但情况还不是这样。这无疑是未来读者的最佳解决方案。

希望有一种方法可以使用钻头缠绕式黑客获得相对较快的代码,尽管它生成代码的速度肯定不会像大多数x86-64最近处理器上可用的popcnt指令那样快。例如,可以使用Numba中的以下代码实现对无符号32位整数的波普计数:

代码语言:javascript
复制
import numba as nb

# The signature is critical for the function to be correct
@nb.njit('int_(uint32)')
def popcount(v):
    v = v - ((v >> 1) & 0x55555555)
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333)
    c = np.uint32((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24
    return c

# Returns 17
popcount(0b00110101_00011110_00111010_11101001)

在我的机器上,这是非常快的,特别是如果上面的函数被放入一个循环中,由于JIT可以使用AVX-2 SIMD指令,所以它可以被自动矢量化:它在我的机器上需要大约4周期/int,在AVX-2中需要1.5周期/int。

同样的情况适用于MSB和LSB。请注意,具有较少位的整数的位旋转黑客应该会产生更快的生成代码(特别是由于SIMD和需要更少的指令)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71097470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档