【问题标题】:Intel intrinsic data type inside struct结构内的英特尔内在数据类型
【发布时间】:2020-12-19 22:22:06
【问题描述】:

我想知道如何在我的程序中正确使用 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])), _ones), _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])), _ones), _scl));

【问题讨论】:

  • 快速回答:这是不对的。是的,您应该坚持使用 api 提供的加载和存储方法。
  • > * 发现 80% 的时间都花在了加载和存储上* 你需要展示这部分代码,以便人们可以理解为什么它很慢并帮助你
  • Unions 还是要编译成 asm;以这种方式编写向量元素访问通常没有帮助;实际工作仍然需要,并且生成的 asm 通常充其量是相似的,或者如果它以一种创建存储转发停顿的方式编译可能会更糟。当然,请确保您在编译时进行了全面优化。
  • 感谢您的快速回复,目前,我将坚持非矢量化的方式,并会找到程序的其他一些可以显着受益于矢量化的区域。

标签: c++ struct vectorization unions intrinsics


【解决方案1】:

您的代码运行缓慢,因为您很可能在调用 _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,xmm2);
_mm256_storeu_ps(result_ptr,xmm1);

【讨论】:

  • 谢谢你的回答,我也觉得是这样。我过于频繁地调用存储和加载功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 2016-12-04
  • 2017-04-17
相关资源
最近更新 更多