2016-08-09 31 views
0

問題

是否指示存在該褶襉/提取的int[32]並將其存儲的第一位爲int收集/提取從整數數組第一比特

  • 我知道固有的pext,但那不是我真正想要的。

  • 我確實有一個代碼,但我想也許有一個指定的指令。

  • ints數組除了第一位之外爲零。人類,不需要掩蔽。

代碼

void ints2bits(int &bits, int *ints) { 
    bits = (ints[0] << 0) + (ints[1] << 1) + ... + (ints[31] << 31); 
} 

UPDATE &反饋

只是測試哈羅德建議。它工作得很好,我可以達到很好的加速。

+0

如果你想提取數組中所有31個整數的第一位,並將這些位存儲在一個int的適當位置,那麼你的代碼是錯誤的。 – sameerkn

+0

這沒有錯。我從字面上使用它。問題只在於這個操作有特定的指令。這種方法不需要掩飾陣列,這也許是你聲稱其不完整的原因。 –

+0

您的代碼假設ints中的所有其他位都爲零,您應該在您的問題規範中明確聲明。 – samgak

回答

2

沒有一條指令甚至可以讀取那麼多的數據,但使用_mm_movemask_ps可以快速處理4個組(8個AVX2)。忽略它聲稱是浮點指令的事實,它只是收集和追加4個最高位。

當然,通過_mm_slli_epi32將底部位移到頂部很容易。

所以將其組合在一起(未測試)

int res = 0; 
for (int i = 0; i < 32; i += 4) { 
    __m128i x = _mm_load_si128((__m128i*)&ints[i]); // I assume it's aligned 
    x = _mm_slli_epi32(x, 31); 
    int bits = _mm_movemask_ps(_mm_castsi128_ps(x)); 
    res += bits << i; 
} 

擴展到AVX2是很明顯的。

另一種可能的方法是將每個車道移動一個可變的數量(AVX2前需要乘法),然後求和,當然首先是垂直求和,最後保存水平和。這可能會更慢,當然更尷尬。