我想要实现的是一种使用intel内在函数有效地将32位整数广播到C中的256位YMM寄存器的方法。 但是,我希望将32位整数的每个位转换为寄存器中的 0x00 或 0xFF 字节,取决于是否我的整数中的位是 0 或 1 。
例如,如果我有一个位为 0011 的4位整数和一个16位寄存器,我希望16位寄存器最终得到内容: 0000 0000 1111 1111
如果我使用通常的英特尔内在函数进行广播,我最终会得到一个表格注册: 0011 0011 0011 0011。
由于可能的最低英特尔内在shuffle正在处理字节,所以我不能随后将这些位改组以匹配。
我找到的唯一解决方案是在寄存器之前为每个位使用 if ,从而预先准备数据然后将其加载到寄存器中。像这个伪C代码片段:
if(some_int & 1) {
expanded_bit[0] = 0xFF;
}
if(some_int & 2) {
expanded_bit[1] = 0xFF;
}
if(some_int & 4) {
expanded_bit[2] = 0xFF;
}
if(some_int & 8) {
expanded_bit[3] = 0xFF;
}
some_register = _mm256_load_epi8(expanded_bit[0], expanded_bit[1], expanded_bit[2], expanded_bit[3]);
这虽然看起来效率不高......(如果准备数据的开销等于使用SIMD操作所获得的时间,可以说它可能会破坏SIMD的目的。)