【发布时间】:2014-01-04 09:03:41
【问题描述】:
从我关于"Using SIMD AVX SSE for tree traversal" 的另一个问题中,我得到了我试图进行基准测试的这段代码。我以前没有用 SIMD 做过任何事情,所以我对这种排列的东西有点陌生。首先,让我们看看这段代码:
__m256i const perm_mask = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0);
// compare the two halves of the cache line.
__m256i cmp1 = _mm256_load_si256(&node->m256[0]);
__m256i cmp2 = _mm256_load_si256(&node->m256[1]);
cmp1 = _mm256_cmpgt_epi32(cmp1, value); // PCMPGTD
cmp2 = _mm256_cmpgt_epi32(cmp2, value); // PCMPGTD
// merge the comparisons back together.
//
// a permute is required to get the pack results back into order
// because AVX-256 introduced that unfortunate two-lane interleave.
//
// alternately, you could pre-process your data to remove the need
// for the permute.
__m256i cmp = _mm256_packs_epi32(cmp1, cmp2); // PACKSSDW
cmp = _mm256_permutevar8x32_epi32(cmp, perm_mask); // PERMD
// finally create a move mask and count trailing
// zeroes to get an index to the next node.
unsigned mask = _mm256_movemask_epi8(cmp); // PMOVMSKB
return _tzcnt_u32(mask) / 2; // TZCNT
作者Cory Nelson试图用cmets来解释。但是,我并没有真正了解这种排列是如何工作的,以及为什么它最终会从结果向量中“提取”想要的信息。
有人能帮我理解如何在此代码中使用排列、移动掩码和 TZCNT 以及“打包/解包”在此上下文中的含义吗?对于您可能拥有的任何资源,我将不胜感激 - 谷歌对这个非常特殊的主题没有帮助。
【问题讨论】:
标签: permutation sse simd avx