我正在尝试将其转换为 AVX2:
// parallel arrays
int16_t* Nums = ...
int16_t* Capacities = ...
int** Data = ...
int* freePointer = ...
for (int i = 0; i < n; i++)
{
if (Nums[i] == 0)
Capacities[i] = 0;
else
{
Data[i] = freePointer;
freePointer += Capacities[i];
}
}
但没有走得太远:
for (int i = 0; i < n; i += 4) // 4 as Data is 64 bits
{
const __m256i nums = _mm256_loadu_si256((__m256i*)&Nums[i]);
const __m256i bZeroes = _mm256_cmpeq_epi16(nums, ZEROES256);
const __m256i capacities = _mm256_loadu_si256((__m256i*)&Capacities[i]);
const __m256i zeroedCapacities = _mm256_andnot_si256(bZeroes, capacities);
_mm256_storeu_si256((__m256i*)&Capacities[i], zeroedCapacities);
}
卡在
else
分支,不知道如何将(前缀和?...)Capacities
添加到freePointer
中,并将“串行”结果分配给同一个256位SIMD寄存器中的Data
。
我的术语可能有问题,我希望代码能够理解我想要完成的任务。
lane0: freePointer
lane1: freePointer + Capacities[i + 0]
lane2: freePointer + Capacities[i + 0] + Capacities[i + 1]
lane3: freePointer + Capacities[i + 0] + Capacities[i + 1] + Capacities[i + 2]
基本上,如果可能的话,这就是我想要用尽可能少的指令来完成的事情。目标是AVX2。
您可以在这里找到很多详细信息:https://stackoverflow.com/a/69452433/5021064
在这里您可以插入任何类型而不是T,然后您可以看到x86和arm的汇编结果