矢量化二维阵列访问(GCC)

时间:2015-06-22 05:02:28

标签: arrays gcc vector vectorization simd

我理解矢量化的基本思想。我正在考虑将我的一个程序转换为矢量化版本。但这似乎很复杂。

有一个表格(二维数组)table[M][N],以及两个向量X[1..4]Y[1..4]。我可以按以下方式进行操作吗?有什么想法吗?

X[1..4] = table[X[1..4]][Y[1..4]]

(顺序版:X[i] = table[X[i]][Y[i]]

换句话说,可以对以下循环进行矢量化吗?

    for(k=0; k<4; k++) {
        tmp1 = X[k];
        tmp2 = Y[k];
        X[k] = table[tmp1][tmp2];
    }

注意: X[]始终包含不同的值

目前,它是用C语言实现的。

4 个答案:

答案 0 :(得分:2)

1)从技术上讲,hayesti已经回答了你的问题(在AVX2上对vgather的SSE / AVX上的插入/声明指令将使其成为可能)。但请注意,GCC4.9和ICC都会对给定的代码片段进行矢量化(因此对于真正的随机访问不需要内在函数/手动编码),但对于GCC,您可能需要#pragma omp simd,并且您可以SSE机器上的ICC也需要-vec-threshold0。

2)实际上,如果你必须对给定的代码进行矢量化&#34;就像#34;它将永远不会是非常好的加速,因为你需要&#34; ammortize& #34; vgather vinsert -s的大开销(延迟)和足够的向量计算(在您的示例中没有),以进行向量化&# 34;有利可图&#34; 。并且无需说您还需要适当的环路跳闸计数等。

我刚刚使用一个新的ICC编译器检查了代码的矢量化版本的静态成本模型估计&#39; report(或&#34; Intel Vectorization Advisor&#34;)输出。

  • 对于 SSE 代码生成,它是: 0.5x (即减速)
  • 对于 AVX 代码生成,它是: 1.1x 加速(作为上限)
  • 对于 AVX2 代码生成,它是: 1.3x - 1.4x 加速(作为上限)。

现在,请记住,所有这些加速都是由非常好的优化编译器提供的乐观上限(我不知道GCC是好还是坏)。根据您的索引布局,矩阵大小和整体带宽 - 延迟平衡以及其他一些原因 - 您通常会低于给定的1.4倍,即使对于AVX2,也几乎不会期望显着的加速。为了使这种访问模式真正有利可图,你需要在循环体中使用X [k]进行一些额外的(矢量化)计算来分摊开销(而不是仅仅将数据从一个地方复制到另一个地方)。

与此同时,还有好消息。对于短期未来 AVX-512 机器(KNL Xeon Phi,一些未来Xeon)vgather性能可能会改变/改进,因此即使是简单的数据复制也可能会带来一些额外的加速,但无论如何这样不是你今天会观察到的东西&#39; AVX / AVX2机器。

最后一个小注:如果你处理稀疏矩阵(以及你告诉给定间接引用的原因),那么你可能会想到稀疏数据压缩行存储格式,结果是不同的SIMD交易-offs,虽然它与问题的原始范围相差太远。

答案 1 :(得分:1)

理论上这很好,但这取决于你拥有的处理器。您需要通过AVX2添加到x86处理器的vector gather功能,并首先出现在Haswell微体系结构中。伪代码看起来像这样

vr1 := simd_load4(x)
vr2 := simd_load4(y)
vr3 := vr1 * 4; // multiply by the number of rows
vr4 := vr3 + vr2;
vr5 := simd_gather(base=&table, offsets=vr4)
simd_store(x, vr5)

SSE / AVX版本可能如下所示

__m128i vr1 = _mm_load_si128 (x);
__m128i vr2 = _mm_load_si128 (y);
__m128i vr3 = _mm_mul_epi32 (vr1, _mm_set1_epi32 (4));
__m128i vr4 = _mm_add_epi32 (vr3, vr2);
__m128i vr5 = _mm_i32gather_epi32 (table, vr4, 1);
_mm_store_si128 (x, vr5);

答案 2 :(得分:0)

如果要复制相邻的存储单元,可以使用memcpy()复制整块数据。但由于这就是这种情况,没有办法,你必须使用循环。

答案 3 :(得分:0)

可以通过VTBL指令在ARM NEON上完成。

NEON可以相当快地处理高达32字节的LUT。