>>1 MeromはSpeculative Loadをサポートするようだが、
IA64みたいに、ld.sのようなロード開始命令を使って明示的に、メモリを先読みするやり方は
x86では互換性の問題からいって無理ですよね。
どういう感じで実現されると思いますか?(・∀・)
>>901 > MeromはSpeculative Loadをサポートするようだが、
それ、どこの情報?
903 :
901 :2005/12/10(土) 21:48:17
Fall IDF 2005 - Day 1: Intel's New Architecture Details Revealed
http://www.anandtech.com/tradeshows/showdoc.aspx?i=2504 >Intel is also introducing speculative data loads with the new architecture,
> loads to be executed ahead of stores if a dependency is predicted to not exist between the two.
今までのP6でも、ストアの後のロードはストアの前に実行することができる。 厳密には、P6ではストアの後のロードはストアデータの前に実行することができるが、 ストアアドレスの前に実行することはできない。 ストアアドレスとロードアドレスを実行しないとストア−ロードの依存性チェックができず、 うかつにロードを先に実行できないから。 Meromでは、この依存性チェックをアドレス計算ではなく予測で行い、 ストアアドレスがまだ計算できない状況でも、ロードアドレスが計算できれば ロードを先に実行できるようにしたものだと思う。 もしかすると、ストアをストアアドレスとストアデータに分割しない可能性もある (というか分割する必要性が薄れる)。 Meromがどのような予測方法をとるのかは分からないが、 AlphaのstWait tableをまねたものではないかと思う。
>>901 Speculative Loadというのは、こういうコードで、
if (A){
B;
} else {
C;
}
IA-64では、Aがわかる前にBとCを両方実行しておくなんてことができるらしいが、
PenMとかの投機実行と違って実際に実行してしまうため、結果的に破棄するパスで
例外が発生したりするとまずい。
で、例外があったらNaTビットというやつに記録しておいて後で例外発生させることで
この問題を回避している。
PenMでも、例外が発生した投機実行を破棄することはあるだろうけど、
多分うまく処理してくれてるんだろう。
そういう意味ではIA-64の方が機能が低いが(他にはOoOがないとかも)、
この辺のことはCPUではなくコンパイラがやってくれる。
PenMなら例外とかの問題は元々ないので(ていうかあったら投機実行できない)、
x86とは無縁の話じゃないかと思ったが、
>>903 を見ると
IA-64のSpeculative Loadと、x86のそれは違うものを指してるんだね?
>どういう感じで実現されると思いますか?
俺は全く見当が付かなかったけど、
>>904 を読んだら904の通り内容だと思った。
予測の具体的な仕組みは、コードを見て判断するのは難しそうだな。
単純に分岐予測と同じ感じでどうだろう。
依存関係ありと予測すればペナルティはないので、予測をそちらに振って、
何回も連続で依存関係がなかったストアに対しては投機ロードをする、みたいな。
それなりにハードの負担がありそうだが。
>>904 ロードが先行するストアを追い越すには、ストアアドレスが既に全て実行されていて、
その上でストアアドレスバッファを全てチェックしないといけないんだね。
ストアが混じったコードだと、全く依存関係がなくてもロードのOoOには限界があるわけだ。
考えてみれば当たり前だけど、こんなに大変だとは思っていなかった。
Alphaではどのように予測しているの?
904を読んで、ストア・フォワードのことかと勘違いして実験。
lp:
mov [esi],eax
mov bx,[esi+hoge]
dec ecx
jnz lp
hoge=0,4,5のとき、2.25clk/loop
hoge=1,2,3のとき、10.0clk/loop
本来ならhoge=1,2のときも高速に実行できそうだが、
「アドレスが一致しないけど含まれる」ものまでチェックしてるヒマがないのだろう。
hoge=3のときと同じクロック数ということは、ストアがリタイヤするまで待っているっぽい。
>>900 漏れもPentiumMの中に入りたいでつ。
組み込み系はスループットよりレスポンスが重要になることが多いから 分岐先2箇所とも実行するのも普通に多いね
Speculative LoadするMeromで速くなりそうなコードを作ってみた。
mov [esi],0
lp:
mov eax,[esi]
imul eax,eax
imul eax,eax
mov [esi+eax+16],eax ; ストアアドレスもストアデータもeaxを含むので依存関係がある
dec ecx
jnz lp
これはDothanで12clk/loop。
mov [esi+eax+16],eax をmov [esi+16],eax に変えると、なんと2clk/loopまで高速化する。
ストアするデータに関係なく、アドレスが違うから依存関係は無い、とCPUが考えるのだ。
ストアアドレスとストアデータのユニットが分かれているメリットは初めて測定したな。
んで、投機ロードがうまく働けば、このコードでは12clk→2clkの高速化が見込める。
とはいえ、実際にどういう処理で役に立つのかイマイチわからん。
>>908 さんくす。読んでみまつ。
>>905 それはプリディケーションという奴です。
IA-64はロード開始命令とロードした値を使用する命令とか分かれていて、
命令セットレベルでSpeculative Loadをサポートしている。
OOOプロセッサの場合は、これを動的にやる必要がある。
x86の場合は、専用のuOPsを発行して投げるだろうか…。
いずれにしろ、RAW, WAR, WAWの履歴からアドレスを予測する感じなのかな。
>>910 予測方法はともかく、投機実行の方法は分岐予測の場合と変わらないんじゃないの?
普通に投機ロードして、もしロードしたデータが間違いだとわかったらその時点で
投機ロード以降の依存した命令を破棄してやり直し。
P4のデータ・スペキュレーション&リプレイみたいな実装になるだろね。
慣れないIA-64のことなんか書いたから読み直すとボロが出てるな。
>>910 投機ロードはプレディケーションを使うときに限らないってことね。
905は例外処理ばかり書いていて、パイプラインを止めないという肝心なとこが抜けている。
というか完全手(コンパイラ)動なスケジュールだからx86のアーキと全然違うな。
ld.sを前の方に置くというのは、x86でmov eax,[esi]を前の方に置くのと同じことなのかな。
今のx86ならOoOできるから、ld.sと同じっぽい動作になる。
IA-64でただのldを前の方に置くと、In-Orderだから、そこでキャッシュミスした場合に
他の命令も巻き添えで遅くさせてしまうんだよね。
ぐむ、In-OrderのCPUを触ったことがないから全然IA-64の気持ちになれん・・・。
Intelさん、いつかx86にCellのSPEみたいなの付けたやつ売ってください。
>>908 [命令当たり1bit]*1024のstWaitテーブルがあって、
ロード命令がストアに依存したら、その命令のstWait bitをセット。16384clk毎に強制解除。
stWait bitがオンなロード命令では投機ロードはしない。オフならする。
てことで良い?
テーブルに入りきらなくなったら無視するのかな。どうせ16384clkの命だし。
1回でも失敗したらというのは妥当かも。16384clkもほどよい長さだ。
これって投機ロードするのがデフォルト?それだと、やや冒険な感じがするが。
>>913 なるほど、やってることが似てるね。
てか、P4のデータ・スペキュレーションて難しいな。何やってんだ。
>>914 > これって投機ロードするのがデフォルト?それだと、やや冒険な感じがするが。
レジスタがたくさんあるRISCプロセッサは、
ストアしたデータをすぐにまたロードするなんて事は
あまり想定してないのかも(?)。
Power4系のロードも基本的に投機ロードみたいだし。
そういえばPower4系のストアもストアアドレスとストアデータの2度発行なんだね。
OoOプロセッサでは、ld命令のデコード後にしか投機的な発行は出来ないけど、 IA64では、いくらでも先にld.sを置いて先読みできるのでは? だからキャッシュだけでなく、メインメモリのレイテンシのタイミングにも合わせられる。
プリフェッチ命令+ロード命令でいいんでは?
プリフェッチ命令を追加すると既存のx86コードと互換性がなくなってしまう。 IA64は、標準的な命令として、明示的な投機ロードが行えるところが強みの一つだね。 プリフェッチ+ロードだと、結局ロード時に、キャッシュのレイテンシが入っちゃうし。
キャッシュのレイテンシくらいだったら、 デコード後の投機ロードでも十分な気もする。
>>916 なるほど、レジスタ8個のx86とは事情が違うわけだ。
>>917 OoO付きx86でも、いくらでも先にmov(ld)を置ける。
IA-64ではOoOがないため、先にldを置くとまずいから、ldの代わりにld.sを入れる。
つまり、「ld.sを置く」というのはIA-64がOoOがないという点でOoO付きx86に劣っているから
仕方なく行っていることで、基本的にIA-64の有利な点ではない(と思う)。
x86だとprefetch命令が必要な場面で、IA-64ではld.sだけで済むことってある?
あるとすれば、ノンブロッキングキャッシュシステムみたいな機能の差によるものだと思う。
ところで、根元的なところだがldを先に置くとパイプラインが止まるってのは本当?
In-OrderのP5でも、順番通りにディスパッチするってだけで、レイテンシの隠蔽はできたのでは
ないかな。FPUもパイプライン化されてたし。
Loadだけでストールするというのは聞いたことがないね。 Loadスロットを浪費したり、待ちのためにRetirementが出来なくなって その結果としてストールという例ならたくさん目撃してるが。
じゃあld.sは、プレディケーションなど(先行するストアアドレス未確定も含むのかな) だけでしか使う意味がないということかな。
IA-64の話だったのか。それだったら
>>922 は筋違い。
922は、P5なら正しいけど、IA-64では間違いということか。 それならそれでいいです。
アセンブラスレの154へ。 話の腰を折るとか考えなくていいのに。本当に迷惑だったらスルーするだけだし。 むしろ初心者の質問は欲しい。それに答えられなかったら俺の理解が甘いということだから。 このスレが、「こういうことに興味はあるけど難しくてわかんない」ものだったら ログが残ってる意味が薄くなるので、「わからない人は何を知ればわかるようになるのか」が かなり知りたいわけです。
927 :
デフォルトの名無しさん :2005/12/14(水) 19:15:45
みんな2.5クロックとか、どうやって測ってるんだろ・・・ 専用のハードウェアでも使ってるの? 俺なんてRDTSCくらいしか思いつかない。
>>927 rdtsc以外にないでしょう。
2.5clkってのは1000回実行して2500clkだったということかと。
P4のデータ・スペキュレーション&リプレイについて。
Intelのページより。
>ロード・スケジューラから実行に至るまでのクロック数はロードを実行するレイテンシ
>そのものよりも長くなります。
>ロード実行が完了する前に、そのロードに依存した命令をディスパッチします。
P4では、L1ヒットするか不明な時点で発行する。
P6では、L1ヒットが確定してから(いつ利用可能になるか判明してから)発行する。
かなあ?
わかった気になっても、思考実験してみるとこんがらがってくる。むずい。
P4は、L2帯域が凄まじいが、ロードした結果をすぐ使うようなコードだと
リプレイのせいで遅くなったりするんだろうか。
安藤さんは専門家で実績のある方なんだけど 氏の書いた物は、読み物としていまいちなんだよな・・・ て感じてるのはおいらだけ?
本書く専門家じゃないから仕方ないべ
古い話題だが、Cレベルでダウンカウンタのループは本当に速いのか。 1から1000まで足して測ってみた。 コンパイラやCPUに依存する問題ではあるが。 for (i=1000 ;i>=0 ;i--) k+=i; //1549clk 確かに速い。cmp命令が省けるためだ。他のものより1命令少ない。 for (i=1000 ;i>0 ;i--) k+=i; //2012clk i>0の判定にjgを使っているが、なぜかsub eax,1の後にtestを使用。 for (i=1 ;i<=1000 ;i++) k+=i; //2013clk for (i=1 ;i<1001 ;i++) k+=i; //2013clk 即値cmpが使われている。 for (i=1 ;i<=1001 ;i++) k+=i; //2055clk前後 これは1001まで足してる 何か知らんけど、1増やしたら急に40clkも遅くなった。 まあ、1ループ0.5clk程度。 読みにくいし書きにくいので、速度重視の場合でもあまり意味がないね。
>932 ちょっと待った、コンパイラ依存とかの前に最適化オプションONにしてる? VC++6.0で/O2(デフォルトのRelease設定)で、 int main() { int i, k = 0; for (i=1000 ;i>=0 ;i--) k+=i; return 0; } をコンパイルすると事実上 >xor eax, eax >ret の2命令のみになる。(Cの呼び出し規約関連の初期化が別途入るが) int k; をグローバル変数にしてやると、 >mov eax, 3E8h という代入までは行われるが、上記程度のループは完全に展開されるよ。 この手の話題を扱うなら、せめて使用コンパイラとコンパイルオプションくらいは晒さないと。
>>932 じゃないけど俺はこんな風にして-Sでコンパイルしたけど
int aaa()
{
int i, k = 0;
for (i=1000 ;i>=0 ;i--) k+=i;
return k;
}
>>933 *ループの*速さの話をしてるんだから、
最適化してループがなくなっちゃうのは話違うっしょ。
ダウンループの利点は、速さもあるだろうけど、
ロジックそのものが単純化される*ケースがある*のが利点だと思う。
うまく使えると嬉しくなる小技の1つ。
漏れはダウンカウンタを意識するときは上の様には書かないな。 for(i = 1000; --i >= 0; ) k+=i; と for(i = 1000; --i > 0; ) k+=i; とを比べてみてくり。
ダウンカウンタの場合は、signedとunsignedでも結果が違った希ガス。 #今日は忙しいから実験はパス。 まぁ、アセンブリくらい読んでからレポートしてくれと。
Toolkit2003、/O2 /G7、PenMで測定でした。/G6でもsubがdecになるだけ。
kをprintfしている。結果埋め込みされるようだったら1000をnにするとかで対応。
>>935 >ロジックそのものが単純化される*ケースがある*
速度に振った最適化は、コードが汚くなるイメージもあるけど、
むしろきれいになるのが本来の姿だよな。
>>937 unsignedだと、
for (i=1000 ;i>0 ;i--) k+=i; //1552clk
判定はdecの後jneでしている。
符号なしの場合、i>0という条件が、i!=0と同じことになるんだね。
どういうことれすか? > 命令が一つreplayに入ると実行ユニットに1サイクルの待機状態が発生する。 > それだけでなく、一つの命令がreplayに入るとたいていの場合いくつかの命令を 道連れにする。 > 極めつけとしては、たった一回のキャッシュミスで長さ数千の命令列が数百回もreplayを回る例さえ作ることが出来た。 > 命令列が何回もreplayループを回るという状況について詳しく見てみよう。 > 不思議に思うかも知れないが、これが起きるのは仕事熱心なスケジューラのおかげなのだ。
rePlay : トレース最適化
942 :
デフォルトの名無しさん :2005/12/21(水) 07:50:12
もしほぼ同じ命令数になるなら、ブランチフリーにした方が実行速度の期待値はアップすると言えますか?
>>939 なるほど、こういうことが書いてあったわけね。
でも、キャッシュミスを起こす命令が1個なのに数百回もreplayを回るってのは
訳がわからないな。
>>941 トレースキャッシュにまで手を加えるの?
以前Noothwoodでメモリベンチをやったときは、
L2のシーケンシャルリードが8clk/64byteを切っていたぞ、って
「FPU,MMX,SSE命令は基本的にreplayを使わない」のか。
今度mov eax,[esi] とかで試してみよう。
>>942 普通分岐をなくしたら命令数増えない?それとも、分岐して実行されない命令数も含めてか。
分岐予測が当てにならない場合は、1回平均10clkくらい損するだろうから、
1回の処理が10clk増える程度で済めば分岐なしにしたらいいと思う。
どちらに分岐するかによって処理時間が変わるのが防げるのも嬉しいしね。
キャッシュの動作。ライトバック方式の場合。 L2のみへプリフェッチするときは、メモリから直接L2に行ったりもできるか? ロードありストアあり、キャッシュラインの追い出しもある実際のコードで プリフェッチ命令を使うのは難しい。 ストアでprefetchntaが効くのは、追い出し先のL2をもプリフェッチしておくからかな。 Load L1ヒットすればL1を読む L2ヒットならL1へ転送してそれを読む メモリからL1へ転送してそれを読む Store L1ヒットすればそこに書く L2ヒットならL1へ転送してそこへ書く メモリからL1へ転送してそこへ書く (L2かメモリから)L1へ転送 L1が満杯なら、L1の中で最も古いラインがL2にないか、あっても変更されているときL2へ転送 (L1から)L2へ転送 L2が満杯なら、L2の中で最も古いラインが変更されているときメモリへ転送
946 :
デフォルトの名無しさん :2005/12/21(水) 14:04:00
948 :
デフォルトの名無しさん :2006/01/03(火) 11:02:59
prefetch{nta|t0|t1|t2} でプリフェッチするにあたって、 キャッシュラインの幅ってどうやって見分ければいいんでしょうか? 32バイト、64バイト、128バイトのプロセッサがあるようなのですが。 また、そのとき必要なCPUサイクルってのはメモリのレイテンシに 影響されますよね?
久しぶりにCodeAnalyst動かしてみた。 結構リザベーション・ステーションが満杯になってストールする事が あるのね。逆にパイプラインがうまく働いてくれてると気持ちいい。
950 :
デフォルトの名無しさん :2006/01/04(水) 12:26:43
256ビット同士の排他的論理和をとって メモリにストアしたいとおもっています。 pxor xmm4, xmm0; movntdq [edi], xmm4; pxor xmm5, xmm1; movntdq [edi+16], xmm5; pxor xmm6, xmm2; movntdq [edi+32], xmm6; pxor xmm7, xmm3; movntdq [edi+48], xmm7; と交互に書くのと、 pxor xmm4, xmm0; pxor xmm5, xmm1; pxor xmm6, xmm2; pxor xmm7, xmm3; movntdq [edi], xmm4; movntdq [edi+16], xmm5; movntdq [edi+32], xmm6; movntdq [edi+48], xmm7; と分けて書くのとでは前者の方が早いのでしょうか?
951 :
デフォルトの名無しさん :2006/01/04(水) 12:27:18
すみません、256ビット同士の排他的論理和ではなく、 512ビット同士の排他的論理和でした。
実測してみては?
953 :
デフォルトの名無しさん :2006/01/04(水) 12:46:15
皆さんこういう場合の計測ってのは、 かなりの回数ループさせてRDTSC読んでって ことをやってらっしゃるんですか? 途中でコンテキストスイッチングが入ったりして、 うまく計測できないんですが・・・ つまり、計測しても分散が大きすぎて。 もしかして何らかの特別な計測用ツールを 使ってらっしゃいますか?
>>953 SetPriorityClass(handle, REALTIME_PRIORITY_CLASS);
を使うと、ほとんどコンテキスト・スイッチングを阻止出来る。
但し、これはデバイス・ドライバのCPU時間まで横取りしてしまう
ため、万が一暴走するとリセットするしかなくなる。
そこに気をつければ大丈夫。
このロード命令が16個あるループは、L1ヒットならPenMでもPen4でも16clk/loopで回る。 lp: ;prefetcht0 [esi+64] mov eax,[esi] ; アクセス順変えでは、ここをmov eax,[esi+64] に変更。 mov eax,[esi+4] ・・・ mov eax,[esi+60] add esi,64 dec ecx jnz lp L1ミスL2ヒットの場合だが、PenMでは25clk/loop。 プリフェッチを使うと20clk/loop、アクセス順変えで19clk/loopまで速くできる。 Pen4では、23clk/loop。 L2からL1へのプリフェッチは仕様上使えない。アクセス順変えで17clk/loopになる。 帯域の差でPen4が勝っている。てか、ロードに依存する命令がないからPen4でも速いのか。
そこで、movをaddに変更。これで、ロードに次の加算命令が依存するようになる。 lp: ;mov ebx,[esi+64] ; movによるL1へのプリフェッチ。prefetcht0 [esi+64] の代替として働く。 add eax,[esi] ; アクセス順変えでは、ここをadd eax,[esi+64] に変更。 add eax,[esi+4] ・・・ add eax,[esi+60] add esi,64 dec ecx jnz lp PenMでの結果は変化なし。 Pen4のL1ミスL2ヒットで、23clk/loop。これは変わってない。 アクセス順変えで22clk/loop。movをaddにすることで3clk遅くなっている。 movによるプリフェッチ(プリフェッチ結果に依存する命令がない点でアクセス順変えと異なる)を 使うと、18clk/loopになる。17load/loopなので満足できる速さだ。リプレイはしてないだろう。 プリフェッチなどを使わない通常のコードでは、ループ先頭でL1ミスするが、 そのときにOoOして代わりに実行できるロードは次のループ(64byte先)までやってこない。 なのでOoOが効果的にできなくてL2帯域が引き出せない。 これを解決するのがprefetcht0などのプリフェッチ命令。アクセス順変えも、この効果がある。 普通、アクセス順変えではループ先頭でL1ミスしても、L2からL1へ転送してる間に 前回のループ先頭でプリフェッチしてあるデータへのL1ヒットのロード命令を実行できるので L2レイテンシをゴッソリ隠蔽することができる。 ところがPen4の場合はL1ミスに気づくのが依存するadd命令を発行した後だったりするので、 投機実行を破棄してやり直しの手間がかかる。何と言うか、アクセス順を変えた意味がない。 L1ミスしてL2からL1へ転送している間に、依存していない命令をやってれば害はないのだが、 依存している命令をL1ヒットしたつもりで発行してしまうと、リプレイで遅くなる。 プリフェッチなしで23clkが変わらないのは、ロードに依存するadd eax,[esi+4] が、 [esi+4]もL1に乗ってないので投機実行できず、リプレイも起きないからだろう。
HTオンでSuperPI100万桁の2個起動やったら73秒と73秒だった。
1個起動だと53秒なので、L1L2共有にも関わらず1.45倍のユニット稼働率だ。
>>899 のコードは23clk/loop。psでもpdでも同じ。
#ここまでのPen4は、Noothwood-3.06GHz、PC1066 512MB。
>>948 >>858 ,
>>865-869 を参照。
ラインサイズをダイレクトに返してもらうのはPenMでも無理なので、eaxに2を入れてcpuidを使う。
そうすると、eax.ebx,ecx,edxの各バイト16個に情報が返り、
例えばその中に2ch(にちゃんねるじゃないよ)があったらL1のラインサイズは64byte、とか。
詳しくはIntelの命令セットリファレンスのCPUIDのところを見てくれ。
実測方法を考えるのも面白いよ。
(2^n)byte毎にメモリアクセスして、nと所要クロックの関係から推測するとか。
>>949 どういうコードでどうなったか詳細キボンヌ。
>>957 リザベーション・ステーションの件ですか?
CPUはAthlon64で、VS2003でコンパイルしたマージソートのプロジェクトを
食わせたら、所々で起きてました。
mov ecx, xxxxxxxxっていうメモリから即値を読み込む所で決まって起きて
いました。リザベーション・ステーションは、今からユニットにデコードしたmicro-OPS
(AMDではMacroOPS?)を溜めておく所ですが、あまりにも単調な命令ばかり
続くと、リタイヤメントの所で引っ掛かってしまい、溢れるようです。リタイヤメント
は実行ユニットと違い、インオーダーですからね。いろんな依存が絡んでくるん
でしょう。
x86の32bitモードでもワーキングレジスタ数は少ないですから、リネーミング をしても溢れてしまうんでしょうね。 x86-64になれば、レジスタ数がぐっと増えるので、リタイヤメントに伴うストール は減るのではないかと期待しています。その代わり、コンテクストスイッチング が重くなりますけど。
>>958 ありがとうです。
単純な命令が一気に流れ込むと3MacroOPS/clkのリタイヤ限界を超えるのかな。
>>959 はよくわからないけど、リネームするとリタイヤが重くなったりするの?
俺もAthlon機が1台欲しいな。。
>>950 xmm0やxmm1が計算済みなら前者が速そうだけど、実際はどうだろうね。
理論では簡単に判定できないタイプだと思うので、実測がおすすめ。
>>953 ループ回数を適度に減らし、1ms以下で完了するようにすればOKかと。
俺は1万clk程度で終わる測定ならPCで音楽を聴きながら測定したりもするが、全然平気。
961 :
948=950 :2006/01/04(水) 15:00:31
>>957 THX。
2ch(にちゃんねるじゃないよ)ってなんのことかと思いましたが、
Intel の命令リファレンスみて理解しました。 0x2c が
「L1キャッシュ 32K バイト、
8 ウェイ・セット・アソシアティブ、
64バイト・ライン・サイズ」
ってのを意味していたんですね。これで prefetchx命令の
配置を切り替えることができそうです。
といっても、ラインサイズが64バイトのプロセッサで
32バイトの処理ごとに(過剰に)プリフェッチした時の計測値と
64バイトの処理ごとにプリフェッチした時の計測値で
ほとんど差が出なかったので、切り替える意味があるのかどうか・・・
>>960 リネームしても、RAWハザード依存は消せないので、コンパイラの癖に
よってはストールを引き起こす場合がある、という事かもしれません。
実際、他のプロジェクトもいくつかCodeAnalystに食わせてみましたが、
長いストールはミスブランチとDATA TLB Missを除いてあまりありませ
んでした。たまたまそのマージソートのプロジェクトだけが癖を持っていた
ようです。
そうですね、Athlon64は、AMDサイトから落とせるCodeAnalyst
(無料、登録必要)が動かせるので、 一台あったら面白いと思いますよ。
>>962 いや、レジスタが少ないことによってストールしてるなら
リタイヤはネックにならないと思ったので。
リタイヤをボトルネックにするには、かなりの最適化が必要だよ。
ネックがリタイヤじゃないとすれば、ハザードで実行ユニットが遊んでしまい、
デコーダから流れてきた命令が溜まっているという状況ですね。
そういえば、Pen4-3.06で測定していて思ったが、
コンパイル速度がDothan-1.1よりずっと遅いのだ。
正確には測ってないけど、倍は違う。
他の要因があったのかな?
>>963 うーんそうかもしれません。コンパイラはVS2003のC++で、最適化をONに
した時とOFFにした時では、だいぶパイプラインの様子が違います。レジスタ
変数を使わなくなると、メモリのReadWrite命令が増えますね。
実際に実行時間を測定すると(QueryPerformanceCounter()等で)、
最適化ON/OFFで大きく変わるものと、あまり変わらないものがあります。
L1/L2キャッシュも関係してくるので、単純な事は言えないのでしょうが・・・・
Pentium4はトレースキャッシュの容量が割と小さく、しかもmicro-OPSの
サイズが大きいので、ただでさえ小さいL1キャッシュをさらに小さくしていると
聞きました。実際、セカンドマシンはPentium4 3.2GHzですが、Athlon64
に比べるとDivXのエンコードは結構健闘していますが、それ以外のすべて
のシチュエーションで遅いです。体感速度も”もっさり”しているのを感じます。
Athlon64は、L1コードキャッシュ・データキャッシュ共に64KBと、Athlon時代
からの伝統(?)で大きいせいか(Latencyは3ですけど)かなりキビキビ感じます。
元々PenMは得意だったのと バスクロック向上やFPUとかのチューニングはいっていると 明言されてるんだし当たり前では PenMって消費電力で圧倒、性能もバランスがよく 欠点はエンコ系だったのがそれがYonahで改善されて 現在最も全方位なバランスのいい石になったと思う マルチスレッドの最適化の場合アセンブリレベルでのチューニングより 動並列化させるかの設計のほうが重要だから 割と面白い
967 :
948=950 :2006/01/05(木) 18:49:34
>>954 >SetPriorityClass(handle, REALTIME_PRIORITY_CLASS);
>を使うと、ほとんどコンテキスト・スイッチングを阻止出来る。
これ、同様のことをLinuxでするには
プライオリティを一時的に挙げればよい、ということでしょうか?
Yonah発表でマイクロアーキテクチャ公開されないかな?
>>967 LinuxカーネルのスケジューラではCPU占有できなかったはず。
というわけでカーネルモジュール使えww
970 :
948=950 :2006/01/05(木) 20:24:45
>>969 が〜ん、カーネルスペースにまで手を出す
勇気と技量がないんで、やめときます(笑
RTカーネル使えばできなくもないが 俺の覚えてる限り、RTにロクな実装がない。 root で動かす限り、カーネルモードモジュールは難しくないべ。
>>969 Linuxは、ソフトウェアアフィニティだからな。
>>969 FreeBSDならrtprio(2)、Linuxだとsched_setscheduler(2)で
リアルタイム優先度に変更してやれば似たようなことできるっぽい。
さあて、そろそろスレのまとめ(
>>171 みたいなの)を作るか。
ログを保存してあるのはいいけど、自分でもどこに何書いたかわかんないし。
次スレは「x86命令の所要クロック計測スレPart2」でいいかな。
ってもうすぐ980か。次スレの1に何を書くかとか議論したかったのにできん(ニガワラ
>>975 ないと思うけど。
ていうかこの分じゃスレのまとめも貼れないまま埋まってしまうな。困った。
まとめ制作は長くて大変だし、いっそ今新スレを立ててしまおうか。
新スレで進行してれば旧スレが止まるからゆっくりまとめ貼れるし。
所要クロックでんでん(なぜか変換できない)は 実情に即さないスレタイなので もっとパイプラインとかスーパースカラ臭がする名前とか もっと厨臭いスレタイきぼん
アウトオブオーダーとかでもつければ良いんでね?
でも最終的には
>>1 が所要クロックを測定して確かめてるじゃん。
スレのまとめ。専用ブラウザ使えばポップアップできます。 >15-18 MMXとSSEのQ&A >22で組み込み関数の話は出てるよ。>137-148は気づいていたのかな。 >23 キャッシュの仕組み >27-31 PentiumMのSSE2のクロック数 >34 μopフュージョンについて >35 K7/K8のデコーダ >40 P4/PMのSSE/MMX比較 >41 P6のL2はエライ >43-44 CPUの内部構造 >47 P4とK7のキャッシュレイテンシ/LoadBench(リンク) >52 パイプラインの比喩(リンク)。>58はコンビニ。 >61-62 K8の128bit pandとandpdは違う?/K8のLoadは64bit*2/clk >65,67,69,75,77,85 SIMDとALUのQ&A。 >68 吉野家コピペ >73 mulpsを入れると速くなる謎。 >78-81 ロード・ストアする派とレジスタで何とかする派 >81-117 分岐。実験結果は>81,86,111,113 >84 初心者のためのアセンブラリンク >87-97 乱数について盛り上がった >99-110 内部構造を予測しつつ測定法を吟味 >114 RISCの分岐処理など >116-117 予測ミスのペナルティがパイプラインの段数より少ない理由を予想 >118 ライフゲームを作った感想 >123 Prescottの触り心地 >128-131 MMXの並列動作。よく考えたらMMX2はユニット限られてた。 >132,500 キャッシュラインをまたぐペナルティ >133-135,153,167 プリフェッチについて >149,154 lddquはps[lr]ldqで実装されてる。 >152 Pentium4の触り心地 >154-165 デュアルコアの話
メモリアクセスの季節。 >167,170 プリフェッチの実験@PenM >172 3つのDoublePath命令のデコードは2clk >182-186 Pentium4とCeleronとコンパイラの質問 >187-192,>196-199 自己書き換えアセンブラ、C、Java、色々な最適化 >200 Visual C++ Toolkit 2003はタダで使える >216-221,>228-229 for (i=0; i<1000; i++) q+=p[i];のコンパイル結果検証 >222 キャッシュのWay数の実験 >234-250 68kとかの昔話 >233,240 トリップ検索 >261-280 C#のトリップベンチ >292-293,>500 ランダムリードの実験(ロード命令同士の依存性なし) >301 Banias-1.5GHzのloadbench >308 新しいオモチャって何だったんだろう・・・ >314-317 複雑なソフト、進む仮想化、語り >332 BIOSでL2キャッシュを無効にしてみた >342-348,>362,>368-383 CPUとGPUの違い >364-366 メモリレイテンシの測定(依存チェーンあり) >397,398,649 divの実験 >400 Cの整数除算はコンパイラが乗算に最適化してしまうこともある >409-413 SpeedStepを試す >414 宇宙ヤバイのコピペ >415-424 x86に、CellのSPEみたいなのはどうか >425-434 ビッグエンディアンの利点/カコイイ >435 QueryPerformanceCounterとrdtscでSpeedStepの実験 >446-458 pcwebのメモリベンチ >457-473 中間言語、Java、GC >476,478,481,491 1がメモリベンチを作ってみました >493-497,499,501 メモリアクセスの並列実行って何よ? >503 閉塞感が漂ってくる。いわゆるネタ切れ。
雑談、パーシャル、トレース。 >513 x86CPUのレイテンシとスループットの表(リンク) >515-517 1がメモリベンチを改変 >518-529 pcwatchのベンチ記事に難癖をつける/ベンチとは何か >530-544 Yonahの情報。結局単純に帯域倍というだけだったかな >545-546,549-550,564,582-583 依存関係を避けたい派とメモリアクセスは極力減らす派 >547,553,556,562,565,575 PentiumMはこんなところが速い! >566-572 どんなアプリに対して最適化すべきか >584 movdquは分解した方が速い >592 YonahのCPUコアの拡張 >593-610 その後ちょい雑談 >613 μopsフュージョン >614-629 SpeedStep/EISTについての妄想たち >636-638 YonahのL2帯域が糞速いけど実際どーよ? >639-647,>653-654 Pen4のSIMDユニットは何bitで周波数はコアクロックの何倍か >650-651 addpdのレイテンシがどう工夫しても3にしか見えない(公称レイテンシは4) >655-665 やめたいスタック式FPUとやめられない互換性80bit/実行ユニットと演算器 >666-677 パーシャルストール >675,680,690,693 movzxに関する致命的な勘違い >678-679 パーシャルフラグストールの実験 >694-696 ワロタ >699,702,706,711 パーシャルアクセスに際しての追加μopは何者 >700,701 SIMDでハンドコーディングの時代です >703-709 分岐ヒントのプリフィックス >713,714,730 トレースキャッシュの功罪/Meromはトレースじゃないっぽ >716-729 トレースキャッシュってuops用の命令キャッシュと何が違うの? >733-747 IA-64とNetBurst/64bitの互換性
Yonah、Merom、色々なアーキ。 >749,750,756 クロックゲーティングを見ようとしたが見えず >751-763,965-966 YonahのSuperPIがやたら速い件/Athlonの排他キャッシュの是非 >764,>796-800,807,>886-889,891 1がメモリベンチを改変。K6-2/K6-2+/Pen3 >765 PenM用チップセットたち >766-780,786-791 AthlonX2も交えてSuperPI関連 >781-784,792 クロック数の表。有名どころへのリンクもあり >792-795 昔の石は最適化のしがいは最高でしたよ >800-804 あの時代のK5 >812 SSE命令がフュージョンするとどうなるか >813 キャッシュラインの捨て方、擬似LRU(least recently used)置換アルゴリズム >830-836 ページカラーリングについて >837-843 アラインメント違反は例外が発生するんですか? >844-851,877,880 L1/L2をできるだけクリアしたいのですが >852,>855-859 Pen4のパーシャルレジスタ >853,858,860,861,863 prefetch*命令でプリフェッチされるのは何バイト単位? >865-869,957 キャッシュラインのサイズってどうやって調べればいい? >870-875,879 パワレポのYonahベンチ >876,881-885 Yonahのベンチお届けです >890,>892-897 Pen4で、ストア命令は2つのμOPに分解されるとは限らない >898-900,957 マンデルブロ集合 >901-925,928 MeromのSpeculative Load/Pen4の投機ロード/IA-64のld.sとの違い >932-938 ダウンカウンタのループ >942,944 同じ命令数なら、ブランチフリーにした方が実行速度はアップする? >939-943,947,955-956 前に貼られてたxbitの記事/Pen4のreplayの実験 >945 キャッシュの動作 >949,958-960,962-964 リザベーション・ステーションの件 >953-954,960,967,969-973 コンテキストスイッチングが入って計測できない
OoO 2issue
われながら、よく連投規制にかからなかったものだ。 このスレでの積み残し。 キャッシュラインをまたいだときの挙動 movとprefetcht0の違い VBでnasm使って状況依存のコード生成 PenMでL2の寝ているブロックを起こす遅延 P4のL2を切る(BIOSで切れない)
次スレではYonahの結果がたのしみ うめ
(・∀・)
そういやMSRに関する詳細な公式の資料ってあったっけ? Appendix.H?
991 :
デフォルトの名無しさん :2006/01/08(日) 13:59:04
うめ
992 :
デフォルトの名無しさん :2006/01/08(日) 14:00:18
しっかりうめんかい
993 :
デフォルトの名無しさん :2006/01/08(日) 14:03:47
うめ
u m e
u m e
u m e
u m e
u m e
u m e
1000 :
デフォルトの名無しさん :2006/01/08(日) 14:20:32
このスレッドはHLTしました。 新しいスレッドをたててくさい。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。