title: How to optimize SIMD transpose function (8x4 => 4x8)?
body: <p>I need to optimize the transpose of 8x4 and 4x8 float matrices with AVX. I use Agner Fog's <a href="http://www.agner.org/optimize/#vectorclass" rel="nofollow">vector class library</a>. </p>
  
  <p>The teal task - build BVH and sum min-max. Transposing is used in final stage of every loop (they also optimized by multi-thread, but tasks can be really much). </p>
  
  <p>Code now looks like: </p>
  
  <pre><code>void transpose(register Vec4f (&amp;fin)[8], register Vec8f (&amp;mat)[4]) {
      for (int i = 0;i &lt; 8;i++) {
          fin[i] = lookup&lt;28&gt;(Vec4i(0, 8, 16, 24) + i, (float *)mat);
      }
  }
  </code></pre>
  
  <p>Needs variants of optimization. How to optimize this function for SIMD? </p>
  
  <hr>
  
  <p>I recently wrote own variants of transpose (4x8 and 8x4) with vectorclass. Version 1.0. </p>
  
  <pre><code>void transpose(register Vec4f(&amp;fin)[8], register Vec8f(&amp;mat)[4]) {
      register Vec8f a00 = blend8f&lt;0, 8, 1, 9, 2, 10, 3, 11&gt;(mat[0], mat[1]);
      register Vec8f a10 = blend8f&lt;0, 8, 1, 9, 2, 10, 3, 11&gt;(mat[2], mat[3]);
      register Vec8f a01 = blend8f&lt;4, 12, 5, 13, 6, 14, 7, 15&gt;(mat[0], mat[1]);
      register Vec8f a11 = blend8f&lt;4, 12, 5, 13, 6, 14, 7, 15&gt;(mat[2], mat[3]);
  
      register Vec8f v0_1 = blend8f&lt;0, 1, 8, 9, 2, 3, 10, 11&gt;(a00, a10);
      register Vec8f v2_3 = blend8f&lt;4, 5, 12, 13, 6, 7, 14, 15&gt;(a00, a10);
      register Vec8f v4_5 = blend8f&lt;0, 1, 8, 9, 2, 3, 10, 11&gt;(a01, a11);
      register Vec8f v6_7 = blend8f&lt;4, 5, 12, 13, 6, 7, 14, 15&gt;(a01, a11);
  
      fin[0] = v0_1.get_low();
      fin[1] = v0_1.get_high();
      fin[2] = v2_3.get_low();
      fin[3] = v2_3.get_high();
      fin[4] = v4_5.get_low();
      fin[5] = v4_5.get_high();
      fin[6] = v6_7.get_low();
      fin[7] = v6_7.get_high();
  }
  
  void transpose(register Vec8f(&amp;fin)[4], register Vec4f(&amp;mat)[8]) {
      register Vec8f a0_1 = Vec8f(mat[0], mat[1]);
      register Vec8f a2_3 = Vec8f(mat[2], mat[3]);
      register Vec8f a4_5 = Vec8f(mat[4], mat[5]);
      register Vec8f a6_7 = Vec8f(mat[6], mat[7]);
  
      register Vec8f a00 = blend8f&lt;0, 4, 8 , 12, 1, 5, 9 , 13&gt;(a0_1, a2_3);
      register Vec8f a10 = blend8f&lt;0, 4, 8 , 12, 1, 5, 9 , 13&gt;(a4_5, a6_7);
      register Vec8f a01 = blend8f&lt;2, 6, 10, 14, 3, 7, 11, 15&gt;(a0_1, a2_3);
      register Vec8f a11 = blend8f&lt;2, 6, 10, 14, 3, 7, 11, 15&gt;(a4_5, a6_7);
  
      fin[0] = blend8f&lt;0, 1, 2, 3, 8, 9, 10, 11&gt;(a00, a10);
      fin[1] = blend8f&lt;4, 5, 6, 7, 12, 13, 14, 15&gt;(a00, a10);
      fin[2] = blend8f&lt;0, 1, 2, 3, 8, 9, 10, 11&gt;(a01, a11);
      fin[3] = blend8f&lt;4, 5, 6, 7, 12, 13, 14, 15&gt;(a01, a11);
  }
  </code></pre>
  
  <p>Need version 2.0. </p>