提问人:Octavianus 提问时间:11/19/2020 最后编辑:Octavianus 更新时间:11/21/2020 访问量:233
测试在二进制表示中设置了哪些 trit
Testing which trits are set in a binary representation
问:
我有一个问题,我有八个元素可以包含 0、1 或 2。我可以轻松地用 16 位表示这一点,但出于 SIMD 效率的原因,我需要它占用 13 位(它不是通道中唯一存在的东西)。
幸运的是,,和 ,所以我想要的状态可以适应。然而,这就是事情变得有趣的地方。天真地,我只是通过计算三元数字状态来表示这些状态。例如,为了表示 tritmask(我将以此为例),我可以只写 .2^13==8192
3^8==6561
0t12211012
0t12211012 = 2*3^0+1*3^1+0*3^2+1*3^3+1*3^4+2*3^5+2*3^6+1*3^7 = 4244 = 0b1000010010100
我有一组需要支持的操作:
- 修改 trits。这在默认表示中很容易。例如,如果我有 tritmask,并且我希望将 a 放在保持零的位置,我可以简单地添加 .(请注意,转换为 tritspace 很容易,因为我只有 8 个 trit,所以我可以将基本功率存储在寄存器中并使用 pshufw 对其进行索引)。
0t12211012
2
0t200=18
- 查找设置为特定值的所有元素。例如,给定 tritmask ,我希望能够提取 的位掩码 ,即 、 、 和 ,即 。我还没有弄清楚该怎么做,这就是我想要的帮助。如何在适合 x86 SIMD 的少量操作中执行此操作?
0t12211012
0
0b00000100
1
0b10011010
2
0b01100001
谢谢!
编辑 11/18/20:举一个我认为太慢的方法的例子:我们可以迭代地找到值 mod 3 并除以 3 以从表示的最不重要的一端拉出 trits,然后以这种方式组装蒙版。C++ 代码段:
uint32_t trits = <something>;
uint8_t mask0 = 0, mask1 = 0, mask2 = 0;
for (uint8_t shift = 0; shift < 8; ++shift) {
const uint32_t remainder = trits % 3;
mask0 |= (!remainder) << shift;
mask1 |= (remainder == 1) << shift;
mask2 |= (remainder == 2) << shift;
trits /= 3;
}
当实际用 SIMD 语言编写它时,我们将使用标准的乘移技巧来除以常数。但是你可以看到它在trit的数量上是线性的,并且每次迭代都有很多操作。我们可以对此进行一些编码,但我认为这从根本上是错误的方法。理想情况下,应该可以为每个 trit 并行执行某些操作......但我没有看到。
编辑 11 年 20 月 20 日:我半心半意地将 Aha 应用于这个问题,但没有成功。也许要解决的一个有趣的子问题是 - 在与上述相同的约束下,是否有一小段按位运算充当“三元按位 AND”?也就是说,在 tritspace 中比较两个编码数字并返回一个位掩码,当相应的 trit 相等且不然为零时,该位掩码为 1?这将是一个原始的,我们可以从中构建所需的操作。我们在三分空间中有左移和右移(只需乘以或除以 3);我们有一个 +/- 一个值。因此,我们缺少的是测试 trits 是否为特定值的能力......
答: 暂无答案
评论
pmovzxbw
uint16_t three2four[6561]
k
3^k