2

我正在尝试做一些向量的东西,并为 immintrin.h 中的 m256d 数据类型编写了一个包装器,以使用重载运算符。下面的例子应该给你一个基本的想法。

类定义

#include <immintrin.h>
using namespace std;
class vwrap {
public:
  __m256d d;
  vwrap(void) { 
    this->d = _mm256_set_pd(0.0,0.0,0.0,0.0); 
  }
  void init (const double &a, const double &b, const double &c) { 
    this->d = _mm256_set_pd(0.0,c,b,a);
  }
};

vwrap 对象数组

让我们想象一个动态分配的 vwrap 数组:

vwrap *a = (vwrap*) malloc(sizeof(vwrap)*2);

访问冲突错误

使用包含 mm256-set-function... 的 vwrap 对象的函数会引发访问冲突错误。

a[0].init(1.3,2.3,1.2);

使用 mm256-set-function 分配 d 也会发生同样的事情(分配另一个 m256d-object 也不起作用):

a[0].d = _mm256_set_pd(1,2,3,4);

从另一个对象复制数据也不起作用。

vwrap b;
a[0].d = b.d;

有效的东西

可以毫无问题地操作 m256d 对象:

a[0].d.m256d_f64[0] = 1.0;
a[0].d.m256d_f64[1] = 2.0;
a[0].d.m256d_f64[2] = 3.0;
a[0].d.m256d_f64[3] = 4.0;

在普通类实例的情况下,分配工作:

vwrap b,c;
__mm256d t = _mm256_set_pd(1,2,3,5);
b.d = _mm256_set_pd(1,2,3,4); 
b.d = t;
b.d = c.d;

我不明白这个问题。在类数组的情况下,为什么我不能使用 _mm256 函数(或分配 m256d 对象)?我唯一的想法是避免使用 mm256 函数并直接操作双精度值。但这不是我故意想要做的。

4

1 回答 1

3

这很可能是对齐问题__m256d需要在 32 字节边界上对齐。malloc当对齐是一个问题时,你不应该使用,使用new对齐malloc

您的堆栈分配变量正常工作是编译器正确对齐它们,因为它知道它们需要对齐。而当您调用 时malloc,运行时无法知道您打算在它提供给您的内存中存储什么。因此,您需要使用 aligned 显式请求对齐malloc,或者使用类型感知分配,这就是new目的。

改变

vwrap *a = (vwrap*) malloc(sizeof(vwrap)*2);

vwrap *a = new vwrap[2];

vwrap *a = (vwrap*) _aligned_malloc(sizeof(vwrap)*2, 32);

应该管用。

编辑:在使用 GCC 4.6.1(编译器开关)在 Windows 上尝试后,-march=corei7-avx它似乎new不遵守对齐要求。将新的调用更改为使用_aligned_malloc有效。

于 2012-03-28T22:49:07.347 回答