高效的4x4矩阵向量乘法与SSE:水平增加和积 - 有什么意义?(Efficient 4x4 mat

2019-07-20 04:57发布

我试图找到使用SSE向量(U)最有效的实现4x4矩阵(M)乘法。 我的意思是穆= V。

据我的理解有两种主要的方式去了解这一点:

    method 1) v1 = dot(row1, u), v2 = dot(row2, u), v3 = dot(row3, u), v4 = dot(row4, u)
    method 2) v = u1 col1 + u2 col2 + u3 col3 + u4 col4.

方法二是容易SSE2实现。 方法1可以是具有在SSE3或任一水平加法指令在SSE4点积指令实现。 然而,在我所有的测试方法2总是优于方法1。

一个地方,我虽然方法1将具有的优点是在3×4矩阵,例如用于仿射变换。 在这种情况下,最后点积是不必要的。 但是,即使在上的4×4矩阵这种情况下方法2是比3×4矩阵方法1更快。 我已经发现,是比在4×4矩阵方法2更快的唯一方法是在4×3矩阵方法2。

那么,有什么水平的添加和点积指令的意义呢? 其实点生产指令给出了在这种情况下,表现最差。 也许它有事情做与数据的格式? 如果一个人不能定义矩阵是如何排序,然后转置是必要的,在这种情况下,也许方法1会更好?

请参阅下面的一些代码。

__m128 m4x4v_colSSE(const __m128 cols[4], const __m128 v) {
  __m128 u1 = _mm_shuffle_ps(v,v, _MM_SHUFFLE(0,0,0,0));
  __m128 u2 = _mm_shuffle_ps(v,v, _MM_SHUFFLE(1,1,1,1));
  __m128 u3 = _mm_shuffle_ps(v,v, _MM_SHUFFLE(2,2,2,2));
  __m128 u4 = _mm_shuffle_ps(v,v, _MM_SHUFFLE(3,3,3,3));

  __m128 prod1 = _mm_mul_ps(u1, cols[0]);
  __m128 prod2 = _mm_mul_ps(u2, cols[1]);
  __m128 prod3 = _mm_mul_ps(u3, cols[2]);
  __m128 prod4 = _mm_mul_ps(u4, cols[3]);

  return _mm_add_ps(_mm_add_ps(prod1, prod2), _mm_add_ps(prod3, prod4));
}

__m128 m4x4v_rowSSE3(const __m128 rows[4], const __m128 v) {
  __m128 prod1 = _mm_mul_ps(rows[0], v);
  __m128 prod2 = _mm_mul_ps(rows[1], v);
  __m128 prod3 = _mm_mul_ps(rows[2], v);
  __m128 prod4 = _mm_mul_ps(rows[3], v);

  return _mm_hadd_ps(_mm_hadd_ps(prod1, prod2), _mm_hadd_ps(prod3, prod4));
}

__m128 m4x4v_rowSSE4(const __m128 rows[4], const __m128 v) {
  __m128 prod1 = _mm_dp_ps (rows[0], v, 0xFF);
  __m128 prod2 = _mm_dp_ps (rows[1], v, 0xFF);
  __m128 prod3 = _mm_dp_ps (rows[2], v, 0xFF);
  __m128 prod4 = _mm_dp_ps (rows[3], v, 0xFF);

  return _mm_shuffle_ps(_mm_movelh_ps(prod1, prod2), _mm_movelh_ps(prod3, prod4),  _MM_SHUFFLE(2, 0, 2, 0));
}  

Answer 1:

水平增加和点积指令是复杂的:它们被分解成由处理器一样简单的指令执行多个简单的微操作。 水平增加和点积指令到微操作的确切分解是处理器特有的,但对于近英特尔处理器水平加载被分解成2 SHUFFLE + 1个ADD微操作,并且点积被分解成1个MUL + 1个SHUFFLE + 2 ADD微操作。 除了微操作的数量较多,该指令还强调在处理器流水线中的指令译码器:Intel处理器可以解码每个周期(相对于4所简单说明)仅一个这样的复杂指令。 在AMD推土机的这些复杂指令的相对成本更高。



文章来源: Efficient 4x4 matrix vector multiplication with SSE: horizontal add and dot product - what's the point?