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関数の使用を避け、double値を直接操作することです。しかし、これは私が意図的にやりたかったことではありません。

4

1 に答える 1

3

アライメントの問題である可能性があります。__m256d32バイト境界に揃える必要があります。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);

動作するはずです。

編集-march=corei7-avx:GCC 4.6.1(コンパイラスイッチ)を搭載したWindowsでこれを試した後、newアライメント要件を尊重していないようです。新しい呼び出しを使用するように変更すると機能し_aligned_mallocます。

于 2012-03-28T22:49:07.347 に答える