问题标签 [bmi]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
algorithm - 不使用 BMI2 的便携式高效替代 PDEP?
英特尔的位操作指令集 2 (BMI2) 中的并行存款指令( )的文档PDEP
描述了该指令的以下串行实现(类似 C 的伪代码):
这个算法是 O(n),其中 n 是 中设置的位数mask
,显然它有 O(k) 的最坏情况,其中 k 是 中的总位数mask
。
更有效的最坏情况算法是否可能?
是否可以制作一个更快的版本,假设val
最多设置一个位,即等于 0 或等于从 0 到 631<<r
的某个值?r
assembly - AVX 支持是否意味着 BMI1 支持?
我有一些依赖于 AVX 的代码。
在同一个代码库中,我也使用TZCNT
.
后者是 BMI1 的一部分。我知道我可以使用 CPUID 测试这条指令,但我很懒所以我实际上并没有实现它。
为了测试支持,我只需执行 AVX 指令。如果我得到一个#UD
未定义的指令异常,我知道 CPU 不支持 AVX。
但是与(或-我总是忘记哪个是哪个)tzcnt
向后兼容(某种),因此不会触发异常。 bsf
bsr
如果我有AVX
支持,这是否意味着BMI1
支持?
作为记录,我现在正在测试的 CPU 上没有 AVX2。
c - 如何有效地找到第 n 个设置位?
对于与此问题相关的代码,我需要尽快计算以下内容:
给定一个 32 位整数i,计算第n个最低有效位的位置。n和结果都应该是 0-indexed。
例如,给定数字i = 11010110101 2和n = 4,所需的数字是 7,因为第四个设置位位于位置 7:110 1 0110101。
使用pdep
x86 的 BMI2 指令集扩展中的指令和常用的__builtin_ctz()
内在函数,可以轻松计算:
但是,许多计算机没有该pdep
指令(并且在有该指令的 AMD CPU 上速度很慢),这使得这种方法不可移植。您也可以计算这样的位位置,而不是pdep
这样:
但是,这很慢。
我的目标是至少提供__builtin_popcount()
和__builtin_ctz()
. 我怎样才能更快地找到这样的位位置?
assembly - 英特尔 CPU 是否支持尾随位操作 (TBM) 指令?
英特尔 CPU 是否支持 TBM(尾随位操作)指令?
我正在尝试bextr
在 Intel上使用直接参数CPUID
并在设置位时获得 SIGILL tbm
。
这是否意味着 Intel CPU 不支持 TBM?
检查 TBM 支持的正确方法是什么?如果供应商 ID 是,则只应检查此位AuthenticAMD
?
c++ - 多班制操作
如何在不循环的情况下实现对位掩码的操作,这对于两个位掩码a
和b
宽度n
给出具有以下属性的宽度位掩码:c
2 * n
i
c
仅当存在j
-th 位a
和k
-th 位 in时才设置 -thb
位j + k == i
C++ 实现:
可以使用一些位技巧或一些 x86 指令在不循环的情况下重新实现它吗?
c - 如何使用 x86intrin.h
在我的一个应用程序中,我需要有效地对长数据流中的位进行解交织。理想情况下,我想在可用时使用 BMI2pext_u32()
和/或pext_u64()
x86_64 内在指令。我在互联网上搜索有关x86intrin.h
( GCC ) 的文档,但找不到太多关于该主题的内容;所以,我要求 StackOverflow 上的专家帮助我。
- 在哪里可以找到有关如何使用函数的文档
x86intrin.h
? - gcc的实现是否
pext_*()
已经有代码可以依赖,还是我需要自己编写后备代码(用于条件编译)? - 如果目标不支持内在函数,是否可以编写一个自动回退到替代实现的二进制文件?如果是这样,如何做到这一点?
- 是否有已知的编程模式可以被GCC
pext_*()
识别并在启用优化和使用 编译时自动转换为-mbmi2
?
assembly - 使用单个位作为单词的掩码
我正在编写一个 LLVM 传递模块来检测程序中的每一个内存操作,并且我的部分逻辑需要对指针执行一些非常热门的二进制逻辑。
如何在尽可能少的周期内实现“位?u64_value:零”,最好不使用显式分支?我在寄存器的最低有效位中有一个位,在另一个中有一个值(假设为 u64)。如果设置了该位,我希望保留该值。如果该位为零,我想将寄存器归零。
我可以使用 x86 BMI 指令。
x86 - 使用 AVX512 生成掩码的 BMI
我受到此链接 https://www.sigarch.org/simd-instructions-considered-harmful/的启发,研究了 AVX512 的性能。我的想法是循环之后的清理循环可以使用 AVX512 掩码操作删除。
这是我正在使用的代码
我认为使用 BMI1 和/或 BMI2 指令可以生成指令更少的掩码。然而,
(在指令数量上)并不比
请参阅https://godbolt.org/z/BFQCM3和https://godbolt.org/z/tesmB_。
这似乎是因为 _bextr_u32 无论如何都会移动 8 位。
可以使用更少的指令(例如使用 BMI 或其他方法)或更优化地生成掩码吗?
我用我的 AVX512 结果扩充了链接中的表格。
我认为,如果链接的作者从-n
up to0
而不是 from 0
to计数,n
他们可能会cmp
像我在主循环中那样跳过指令(参见下面的程序集),所以对于 AVX,它应该是主循环中的 5 条指令。
这是ICC19的程序集和-O3 -xCOMMON-AVX512
在哪里
宏操作应该融合到一条指令。但是,正如 Peter Cordes在此答案 中指出的js cannot fuse。编译器本可以生成jl
,而不是融合。
我使用 Agner Fog 的testp实用程序来获取核心时钟(不是参考时钟)、指令、微指令。我为 SSE2(实际上是带有 FMA 但带有 128 位向量的 AVX2)、AVX2 和 AVX512 执行了此操作,用于三种不同的循环变体
请注意,核心时钟实际上并不是循环版本的函数。它仅取决于循环的迭代。它与 成正比2*n/vec_size
。
指令的数量确实从 v1 变为 v2,但在 v2 和 v3 之间没有变化。6*n/vec_size
对于 v1,它与 v2 和 v3成正比5*n/vec_size
最后,v1 和 v2 的微指令数量或多或少相同,但 v3 的微指令数量有所下降。7*n/vec_size
对于 v1 和 v2 它与 v3成正比6*n/vec_size
。
这是 IACA3 对于 vec_size=2 的结果
IACA 声称js
宏融合add
不同意 Agner 和testp
实用程序的性能计数器。见上文,v27*n/vec_size
与 v3 成正比6*n/vec_size
,我推断这意味着js
不会进行宏融合。
我认为除了指令数量之外,链接的作者还应该考虑核心周期,也许还有微指令。
assembly - x64 支持是否意味着 BMI1 支持?
假设 x64 构建可以使用TZCNT而不通过 cpu 标志检查它的支持是否安全?
python - 我是 python 新手,我正在尝试制作一个 bmi 计算器
输出不准确 重量以公斤为单位,身高以厘米为单位,请帮助!
它的体重 65 公斤和身高 150 厘米 它显示体重不足 它应该是超重或健康的