2016-10-19 8 views
5

シンプルMWE:無効なアドレスがプリフェッチされるとどうなりますか?

int* ptr = (int*)malloc(64 * sizeof(int)); 
_mm_prefetch((const char*)(ptr + 64), _MM_HINT_0); 
  1. は、この定義または未定義の動作ですか?
  2. これはシグナルを発生させ、プログラムの実行を中止できますか?

私はループプリフェッチの内側(rbxに保存されている)アドレスをチェックせずに行われているコンパイラ生成されたコードでは、このようなプリフェッチを見ることができるので、私は聞いてるのよ:、すべての

400e73:  49 83 c5 40    add r13,0x40 
400e77:  62 f1 f9 08 28 03  vmovapd zmm0,ZMMWORD PTR [rbx] 
400e7d:  4d 3b ec    cmp r13,r12 
400e80:  62 d1 f9 08 eb 4d ff vporq zmm1,zmm0,ZMMWORD PTR [r13-0x40] 
400e87:  90      nop 
400e88:  62 d1 78 08 29 4d ff vmovaps ZMMWORD PTR [r13-0x40],zmm1 
400e8f:  72 03     jb  400e94 <main+0x244> 
400e91:  49 89 c5    mov r13,rax 
400e94:  62 f1 78 08 18 53 1d vprefetch1 [rbx+0x740] 
400e9b:  ff c1     inc ecx 
400e9d:  62 f1 78 08 18 4b 02 vprefetch0 [rbx+0x80] 
400ea4:  48 83 c3 40    add rbx,0x40 
400ea8:  81 f9 00 00 10 00  cmp ecx,0x100000 
400eae:  72 c3     jb  400e73 <main+0x223> 
+1

ドキュメントをご覧になりましたか? – fuz

+1

インテルイントリンシックスガイドには何も言われていません。インテルイントリンシクス参照。 Intel Xeon Phi命令セットリファレンスもありません(逆アセンブルされたコードはKNC用にコンパイルされています)。私の知る限りでは。私はすべてのプログラマーがメモリについて知っておくべきことに、この発言だけを見つけました。_プログラムは_mm_prefetch組み込み関数をプログラムの任意のポインターで使用できます。ほとんどのプロセッサ(確かにすべてのx86とx86-64プロセッサ)は無効なポインタに起因するエラーを無視し、プログラマの寿命を大幅に改善します._ –

+0

良い点。この質問をする前に一度見ていただきありがとうございます。そのような重要な細部が文書化されていないことに興味深い! – fuz

答えて

4

ファーストそれをやっているコンパイラは、理論的には非常に異なるものです。コンパイラは、表現可能であるか完全に標準で定義されているかにかかわらず動作する汚れたハックを使用することは許可されています。

もちろんプリフェッチは信号を生成しません*もしそうなら、それはほとんど役に立たないだろう。 TLBミスをトリガするかどうかによって、無効なポインタが非常に遅くなることがあります。だから、コンパイラは安全に使うことができますが、それを無差別に使ってはいけません。

ポインタの算術演算を使って境界から外れたポインタを作成するのは、理論上はUBですが、ポインタに適用するとUBのようになります。それが失敗する唯一の方法は、コンパイラがそれを検出する方法から外れて、それが動的なサイズについて理由を述べなければならないということです)。明らかに、上記のケースは、SSE組み込み関数をサポートすると主張しているコンパイラによってサポートされていなければなりません。そうでなければ、この回答で示されているように、プリフェッチを合理的に使用できませんでした。マニュアルから

*:

PREFETCHh命令は単なるヒントであり、プログラムの動作には影響を与えません。

シグナルはプログラムの動作に影響するため、生成できません。

+0

境界外ポインタの作成は一般的なアーキテクチャではうまく動作しますが、将来のコンパイラでは、ポインタを計算すると有効であり、コンパイラは先取り/推測で逆参照できるため、未定義それが有効でない場合の動作。 – fuz

+0

@FUZxxl IA64コンパイラはすでにそれを行っていますが、そこには問題ありません。それでも、プリフェッチのためにそのポインタを使用している場合には、少なくともそれ以上のものは破棄できません。 – harold

+0

UB?これはハードウェアであり、言語標準ではありません。 – doug65536

関連する問題