未来のいつか/hyoshiokの日記

hyoshiokの日々思うことをあれやこれや

機械語ではマシンの挙動は理解できない(補足)

機械語ではマシンの挙動は理解できない (id:hyoshiok:20070916#p1) の解説がアバウトすぎるという事で、種々の疑問がでてきたかと思うので、蛇足の説明など。

1+              "2:      movl 0(%4), %%eax\n"   // from -> eax
2+              "21:     movl 4(%4), %%edx\n"   // from+4 -> edx
3+              "        movnti %%eax, 0(%3)\n" // eax -> to
4+              "        movnti %%edx, 4(%3)\n" // edx -> to+4
5+              "3:      movl 8(%4), %%eax\n"   // from+8 -> eax
6+              "31:     movl 12(%4),%%edx\n"   // from+12 -> edx
7+              "        movnti %%eax, 8(%3)\n" // eax -> to+8
8+              "        movnti %%edx, 12(%3)\n"// edx -> to+12
略

OOO(Out Of Order)実行というのはよくわかった。右側にそれらしきコメントを書いたので、mov命令がやっている事の概要は分ると思う。

ここで、Intel 64 Architecture Memory Ordering White Paperをひもとくと、
http://www.intel.com/products/processor/manuals/index.htm

1 Loads are not reordered with other loads.

と書いてあって、それより、1行目が2行目より遅く観測されることはない。

次に、

2. Stores are not reordered with other stores.

と書いてあるので、3行目が4行目より遅く観測されることはないように読めなくもない。ところが、

Intel 64 and IA-32 Architectures Optimization Reference Manual
の第9章の9.5.1を読むと下記のような事が書いてある。

In Streaming SIMD Extensions, the MOVNTPS, MOVNTPD, MOVNTQ, MOVNTDQ, MOVNTI, MASKMOVQ and MASKMOVDQU instructions are streaming, non-temporal stores. With regard to memory characteristics and ordering, they are similar to the Write-Combining (WC) memory type:

+ Write combining Successive writes to the same cache line are combined.
+ Write collapsing Successive writes to the same byte(s) result in only the last write being visible.
+ Weakly ordered No ordering is preserved between WC stores or between WC stores and other loads or stores.
+ Uncacheable and not write-allocating Stored data is written around the cache and will not generate a read-for-ownership bus request for the corresponding cache line.

3、4、7、8行目のmovntiという命令は実はキャッシュを利用しないmov命令で、weakly orderedと呼ばれるセマンティックスを持っているのである。この性質を持つメモリ順は機械語での順番は保存されないのである。(きょへーーー)

という事なのである。

プログラム順を保存するためにfence命令というのが用意されていて、書き出しの順を確定したい時には、fence命令をはさむ必要がある。

まとめると先のコードの断片では、レジスタへのロードの順は保存される(プログラムの順で観測される)がレジスタからメモリへのmovnti命令でのストアの順は保存されない(プログラムの順とは無関係に観測される)。

性能を向上させるために、随分なことをやっているのが昨今のプロセッサなのである。