结构内部的英特尔固有数据类型

问题描述

我想知道如何在程序中正确使用intel固有数据类型, 我当前使用的方式涉及使用_mm256_loadu_ps_mm256_storeu_ps来加载和存储结果。但是代码的运行速度比简单代码慢,经过检查,我发现80%的时间都花在了加载和存储上。

所以我正在考虑做这样的事情以避免加载和存储

union _64bytes {
    float m[4][4] = {0};
    __m256 regs[2];
};

struct st {
  _64bytes mat44;
 float f ; int i;
// ...... and other things
};

这种方法对吗?还是应该坚持相同的加载和存储方式。 而且在我的程序中将有成千上万个struct st实例,可能是一个很大的向量。

现在,我已将代码更改为此,以避免出现临时情况。

_mm_storeu_ps(&t.mat[0][0],_mm_mul_ps(_mm_add_ps(_mm_div_ps(_mm_loadu_ps(&t.mat[0][0]),_mm_set1_ps(t.mat[0][3])),_ones),_scl));
_mm_storeu_ps(&t.mat[1][0],_mm_mul_ps(_mm_add_ps(_mm_div_ps(_mm_loadu_ps(&t.mat[1][0]),_mm_set1_ps(t.mat[1][3])),_scl));
_mm_storeu_ps(&t.mat[2][0],_mm_mul_ps(_mm_add_ps(_mm_div_ps(_mm_loadu_ps(&t.mat[2][0]),_mm_set1_ps(t.mat[2][3])),_scl));

解决方法

您的代码运行缓慢,因为您很可能在调用_mm256_loadu_ps_mm256_storeu_ps函数之间进行的操作太少。 在调用这些函数之间,您应该执行尽可能多的操作,例如

xmm1 = _mm256_loadu_ps(some_ptr);
xmm2 = _mm256_loadu_ps(some_ptr2);
xmm1 = _mm256_add_ps(xmm1,xmm2);
xmm1 = _mm256_sub_ps(xmm1,xmm2);
xmm1 = ...;
_mm256_storeu_ps(result_ptr,xmm1);

不是

xmm1 = _mm256_loadu_ps(some_ptr);
xmm2 = _mm256_loadu_ps(some_ptr2);
xmm1 = _mm256_add_ps(xmm1,xmm2);
_mm256_storeu_ps(result_ptr,xmm1);

xmm1 = _mm256_loadu_ps(some_ptr);
xmm2 = _mm256_loadu_ps(some_ptr3);
xmm1 = _mm256_sub_ps(xmm1,xmm1);