2013-08-13 12 views
7

私はOpenCLスタイルのベクトルのためのClangの言語拡張に慣れるためのテストプログラムを書いています。私はコードを動作させることができますが、私は問題の1つの側面を取得している。私はclangをスカラー配列のベクトルにうまく読み込む方法を理解できないようです。メモリからベクトルを読み込む方が簡単です。 (clang)

byte16 va = (byte16){ argv[1][start], argv[1][start + 1], argv[1][start + 2], 
         argv[1][start + 3], argv[1][start + 4], argv[1][start + 5], 
         argv[1][start + 6], argv[1][start + 7], argv[1][start + 8], 
         argv[1][start + 9], argv[1][start + 10], argv[1][start + 11], 
         argv[1][start + 12], argv[1][start + 13], argv[1][start + 14], 
         argv[1][start + 15]}; 

私は理想的にこのような何かたい:私は簡単にARMまたはx86のための適切な組み込み関数を使用して行うことができます

byte16 va = *(byte16 *)(&(argv[1][start])); 

私はのような何かをしなければならない瞬間

。しかし、そのコードはコンパイルしてもプログラムがクラッシュする原因になります。

+0

'memcpy(&va、&argv [1] [start]、sizeof(va))'は動作しませんか? – jxh

答えて

5

x86でクラッシュが発生する理由の1つは、アラインメントの問題によるものです。私は問題を再現するために私のシステムにclangを持っていませんが、私はGCCの例でそれを実証することができます。

あなたが何かを行う場合は、次の

/* Define a vector type of 16 characters. */ 
typedef char __attribute__ ((vector_size (16))) byte16; 

/* Global pointer. */ 
char * foo; 

byte16 test() 
{ 
    return *(byte16 *)&foo[1]; 
} 

をあなたとベクトル対応のx86上で、それをコンパイルした場合:今

$ gcc -O3 -march=native -mtune=native a.c 

あなたがテストのために、次のアセンブリを取得します:

test: 
    movq foo(%rip), %rax 
    vmovdqa 1(%rax), %xmm0 
    ret 

移動が調整されていることに注意してください。もちろん間違っています。さて、あなたはメインにこの機能をインラインだろう、とあなたのようなものがあります場合:あなたは罰金になります

int main() 
{ 
    foo = __builtin_malloc (22); 
    byte16 x = *(byte16 *)&foo[1]; 
    return x[0]; 
} 

を、あなたは非整列命令を取得します。これはバグのようなもので、新しいデータ構造などを追加して手続き間の最適化を必要とするため、コンパイラではうまくいきません。

問題の原因は、コンパイラがベクトル型が整列されるので、整列したベクトル型の配列を参照解除するときは、整列した移動を使用できます。 GCCでの問題の回避策として1は次のように整列していないベクトル型定義することができます。

typedef char __attribute__ ((vector_size (16),aligned (1))) unaligned_byte16; 

をそして間接参照非整列メモリにそれを使用しています。

セットアップ中にこの問題が発生しているとは確信していませんが、これはコンパイラのアセンブリ出力を調べて確認することをお勧めします。

+0

まあ、その場合には、私は あなたはこのような何かをしようとすることができます...それが失敗した理由はいかなる理由が表示されない: '構造体B16 { 文字のx [16]。 }; 構造体b16 x = *(struct b16 *)&argv [1] [0]; ' –

+1

Clangを使用して同様の問題に遭遇し、アセンブリを検査する際に(ARMアセンブリの場合は「:64」または「: 128 '")、私はそれが整列されたバージョンのロード命令とストア命令を使用していたことが分かりました。このソリューションは私のために働く。 – sh1

関連する問題