从基于来源的指数转换为基于目的地的指数

我在一些C代码中使用AVX2指令。

VPERMD指令采用两个8整数向量aidx并通过基于idx置换a来生成第三个向量dst 。 这似乎相当于dst[i] = a[idx[i]] for i in 0..7 。 我正在调用此源代码,因为该移动是基于源索引的。

但是,我有基于目的地forms的计算索引。 这对于设置数组是很自然的,相当于dst[idx[i]] = a[i] for i in 0..7

如何从基于源的表单转换为基于目标的表单? 一个示例测试用例是:

 {2 1 0 5 3 4 6 7} source-based form. {2 1 0 4 5 3 6 7} destination-based equivalent 

对于这种转换,我留在ymm寄存器中,这意味着基于目标的解决方案不起作用。 即使我要单独插入每个,因为它只在常量索引上运行,你不能只设置它们。

我想你是暗示说你不能修改你的代码来计算基于源的索引? 除了采用基于dst的索引的AVX512分散指令之外,我无法想到你可以用x86 SIMD做什么。

存储到内存,反转和重新加载矢量可能实际上是最好的。 (或者直接转移到整数寄存器,而不是通过内存,也许是在vextracti128 / packusdw之后,所以你只需要从向量到整数寄存器的两个64位传输:movq和pextrq)。

但无论如何,然后使用它们作为索引将计数器存储到内存中的数组中,并将其作为向量重新加载。 这仍然是缓慢而丑陋的,并且包括存储转发故障延迟。 因此,更改索引生成代码以生成基于源的随机向量可能值得您花些时间。