x86命令の所要クロック計測スレ
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNGaddpdは4-2(レイテンシ-スループット)
imul 4-1
Pen4、Athlonなどデータを集めてみる
01531
2005/03/24(木) 12:23:27mov eax,[ebx] というのは、[ebx]周辺をプリフェッチする昔ながらの手法。
あらかじめロードバッファに[ebx]のロードを突っ込んでおけば、しばらく後で使いたいときに
もうL1キャッシュに乗っているのだ。1つのロードで1キャッシュラインを移動できるのがミソ。
これとprefetcht0 [ebx] は、eaxを汚染しないということぐらいしか違わない。
使い方は、キャッシュラインのサイズが64byteでメモリ(またはL2)のレイテンシが20だったら、
64byteの処理毎に、ロードの20clk(以上)前の位置にプリフェッチ命令を入れる。
>>137-
組み込み命令っていいね。
今まで「アセンブラ使えよ」とか思っていたが、アセンブラには最適化を阻害するという弱点があり、
ループ内の一部だけインラインアセンブラとかやると絶望的に遅かった。
この弱点なしで明示的にSIMD命令を使えるのはいいなあ。
>>149
pslldqがバイト単位って知らなかったよ。今度、命令リファレンス通して読んでみようかな。
それにしても、「P6以降はクロック計算できない」「OS上では測れない」と言うヤシが多すぎ。
015497
2005/03/26(土) 04:29:38どーやら間違いない模様。
movdquは、おそらくmovdかなんかのより細かい単位でロードし組み合わせてるものと予想。
lddquは、ロード回数が少なくなる反面、256bitの連続した領域に対して読み込みが
発生するため、依存関係によりかえって遅くなるケースもあり得る模様。
だから使い分けのために2つの実装を用意した、と。
YonahでSSE*にもμOPsフュージョンが適用されるそーだけど、これは
Athlon64なんかと同じく、「あまり遅くならない」程度の効果と見るべきでせうか。
ユニット数据え置きでL/Sを128bit化してくれるとかなり使い甲斐もあるのだが。
浮動小数の強化については単純にユニット増加と見てますが。
0155デフォルトの名無しさん
2005/03/26(土) 13:01:25作り方によっては大幅性能UPで使いやすくなりそうだなぁ
今後は1命令の単純なスループットとかより
マルチコアによるキャッシュの取り合い具合とか
マルチスレッドに対応した効率のよいアルゴリズム変更のほうが
重要になっていく希ガス
0156デフォルトの名無しさん
2005/03/26(土) 14:27:280157デフォルトの名無しさん
2005/03/26(土) 18:25:34キャッシュの統合とかそういうのもあるし
0158デフォルトの名無しさん
2005/03/26(土) 18:57:16キャッシュスヌープするんかな?
015997
2005/03/26(土) 19:23:23YonahはL2がシェアードになってます。レイテンシ増えるんだろうな(欝
0160デフォルトの名無しさん
2005/03/27(日) 01:06:03ただ、Pen4系列だけしか早くならないのでうまみが無い。
日本では省スペースデスクトップもPenMばかりだからな。
デスクトップとノートと同じパーツが使えるんで仕入れの関係かもしれん。
マルチコア全盛になればシングルスレッドのチューニングが
ばからしくなるかもしれない。
016197
2005/03/27(日) 01:34:24確かに馬鹿らしくもなる。
ただ、マルチコアはシングルスレッドでの性能アップは十分意味あると思うけど。
1コアあたりの空きユニットを埋める手段は従来の最適化手法の延長なわけだから。
0162160
2005/03/27(日) 02:26:18シングルスレッドしか考慮しない人とマルチスレッドでアルゴリズムを
ちゃんと考えられる人との差が大きく差がついてしまうと。
シングルスレッドでガリガリにアセンブラでチューニングしたところで、
JavaやC#等でマルチスレッドで動かしたほうがはるかに早くて
開発効率もいいということがありえそうだからね、と。
0163デフォルトの名無しさん
2005/03/27(日) 19:55:300164デフォルトの名無しさん
2005/03/28(月) 02:16:00スレッド同期のオーバーヘッドだって馬鹿にならないと思う。
現実的には、キャッシュの共有とか考えてまで、コーディングしてらんないよ。
スレッド間で同期したって、OSが違うスレッドと同時に走らせてくれたら台なしだしね。
016597
2005/03/28(月) 06:01:51スレッドの依存関係を極力断ち切れ(鉄則)
ループを小分けしてやって並列実行させる以外何にも変わらん。
マルチコアコンピューティングはアルゴリズム云々じゃなくて力技。
各コアに負荷を均等に分散すればあとはインストラクションレベル最適化が全体の
パフォーマンスにおいてかなりのウェイトを占めるのは何も変わらず。
01661
2005/03/29(火) 10:24:11movdquはmovq2回じゃないかな。それでP4・PM共に大体クロック数の辻褄が合う。
ていうかmovqがアライメント関係ないので、movdまで細かくする意味がない。
それにしても、なぜ16byteの読み込みだと急にアライメントを要求されるんだろ。
信号線が128bitで、アライメントの合ってないmovqのときは128bit中の64bitを使うのかな。
>lddquは、ロード回数が少なくなる
むしろ将来的にはmovdquが(movqのように)1回のロードになるかも知れず、
lddquは原理的に2回ロードするので、回数ではlddqu不利と見るべきではないかと。
lddquはキャッシュラインをまたいでも遅くならないというだけの命令なので、
平常時はシフト・合成の手間の分だけ遅いはず。
依存関係とはストア・フォワード機能がらみのことか?
(ストア命令がリタイヤする前ならストアされたデータを高速にロードできる)
>YonahでSSE*にもμopフュージョンが
朗報ですな。
まあ、K7でVectorPathだったときも、スループット2の命令を1clkでデコードしてたんだからね。
理論性能がそれほど上がるわけではないが、タイトなループが思い通りに回ってくれる予感。
浮動小数の強化は気になる。やはりユニット増加か。
単純に倍の個数載せれば128bit演算のスループットが1になる(すげえ)。
ただ、これはハードの負担が大きすぎる。ただでさえデュアルコアでトランジスタ倍増なのに。
もうひとつ考えられるのは、mulsd/mulpdの強化。
PMのmulsdはfmulと同じクロックで、mulpdのスループットは4(K8/P4の倍)とかなり遅い。
80bitと64bitで浮動小数の計算コストってどのくらい違うんだろう。
でも、YonahのコアはDothanと同じじゃなかった?
>>165
禿しく同意
01671
2005/03/29(火) 10:25:35paddd mmx,[source] で、640,000byte分のintの総和を求めるコード。
64byte/loopで普通にやると147800clkくらいかかる。L2キャッシュで4.33byte/clkは大したもの。
次に、ループの先頭にprefetcht0 [esi+128] を置くと、120500clk。5.31byte/clk。
それをmov eax,[esi+128] にすると、110500clk。5.79byte/clk。
で、新アイデア。余分なプリフェッチ命令を使わないプリフェッチ。
ループ先頭のpaddd mm0,[esi] をpaddd mm0,[esi+128] に変える。
多少ループの外に細工をすれば同じ結果が出せる。101100clk。6.33byte/clk。
これ以上はループをアンロールなどしても変わらず。64byte/10clkに壁がある感じ。
ちなみに、河童Celeronではどうやっても4byte/clkをわずかに上回る程度しか出なかった。
400KBのデータのコピーは、2.32byte/clk程度。どういじっても殆ど変化なし。
そもそもストアのスループットがL2で4byte/clk出ない。
そういえば、L2に書くためにはL2からL1にキャッシュラインを読み込まないといけないんだ。
mov [esi],eax / add esi,64 / dec ecx / jnz lp これがL2ヒットで19.7clk/loop。
たとえeax1個のストアでも、64byteのキャッシュラインをL1/L2間で往復させないといけない。
add eax,[esi] / add esi,64 / dec ecx / jnz lp これはL2ヒット時に6.1clk/loopで回る。
64byteのキャッシュラインを6clkで読めるのか?
P3のL2がオンダイになったとき、昔の記憶だが雑誌で「256bitを2clkでできる」と見た気がする。
ひょっとして転送自体は16byte/clkくらい出てて、レイテンシが問題になってるだけ?
そういやロードでもライトバックの手間はかかるな。ややこし・・・。
0168デフォルトの名無しさん
2005/03/30(水) 01:53:48コードを書いているのかさっぱりわからん。
短いやつならたまには載せて欲しいな。
01691
2005/03/30(水) 11:20:051μopなら3命令同時デコードだし、4μopなら1命令で4つもμopを送り出せる。
μopフュージョンは、この忌わしい2μop命令を1μopにしてしまう嬉しい機能。
Athlonは、みんなフュージョンした状態で流れていく感じだ。実行ユニットの配置がP6と違う。
なにしろadc [eax],ebx みたいのがDirectPathで3命令同時デコードできる化け物。
ただ、SSEは64bitごとに分割するのでDoublePathになっている。
AthlonがフュージョンできるのはLoad/Op/Store みたいなカタマリであり、
Op/Op とかLoad/Op/Load/Op とかはデコーダが分割しないといけない・・・とか勝手に予想。
上位と下位の並列性から、続けてaddpsするとレイテンシが1減るのはP6と同じだね。
P4ではその現象がない。本物の128bit演算器を積んでるのはさすがというべきか。
Athlon使いに質問だが、3つのDoublePath命令のデコードには何クロックかかる?
2clkか3clkだろうけど、どっちだろう。
ていうかどっちでも性能には大した影響ないか。
>>168
アセンブラは未経験だけど興味があるという人?
とりあえず>>131にライフゲームがうpしてあるので、その中のb.nasを見るとソースが出てる。
ソースの解説がほしいとか、VCでSSEを使うやり方を知りたいとか、質問があれば
俺が次来たときに(気が向いた範囲で)答える。
ていうか俺としては初心者歓迎。
「アセンブラを始めた人が読んで勉強になるスレ」になればなあって思いはあるし。
>>167の主要部分を貼っとく。↓
ポインタがesiで渡されて、それから256byteアラインされるという非実用的ルーチンだが。
一応eaxに総和が入るはず。PenMで110500clkのコード。
01701
2005/03/30(水) 11:20:54mov ecx,10000
pxor mm0,mm0
pxor mm1,mm1
and esi,0ffffff00h
add esi,256
align 16
lp:
mov eax,[esi+128]
paddd mm0,[esi]
paddd mm1,[esi+8]
paddd mm0,[esi+16]
paddd mm1,[esi+24]
paddd mm0,[esi+32]
paddd mm1,[esi+40]
paddd mm0,[esi+48]
paddd mm1,[esi+56]
add esi,64
dec ecx
jnz lp
paddd mm0,mm1
movq mm1,mm0
psrlq mm0,32
paddd mm0,mm1
movd eax,mm0
endproc
01711
2005/03/30(水) 11:30:1115-18 MMXとSSEのQ&A
22で組み込み関数の話は出てるよ。137-148は気づいていたのかな。
23 キャッシュの仕組み
27-30 PentiumMのSSE2のクロック数
34 μopフュージョンについて
35 K7/K8のデコーダ
40 P4/PMのSSE/MMX比較
41 P6のL2はエライ
43-44 CPUの内部構造
47 P4とK7のレイテンシ(リンク)
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 キャッシュラインをまたぐペナルティ
133-135,153,167 プリフェッチについて
149,154 lddquはps[lr]ldqで実装されてる。
152 Pentium4の触り心地
154-165 デュアルコアの話
017214 ◆TimpoiKAMI
皇紀2665/04/01(金) 15:14:13>Athlon使いに質問だが、3つのDoublePath命令のデコードには何クロックかかる?
>2clkか3clkだろうけど、どっちだろう。
シムの上では2クロックに近くなるようだ。
DoublePath2つのうち1つが、1クロック遅れて出てくる感じ。
実機では、MMXとくらべてあからさまな差が出なかったので、
(すくなくともK7のVectorPathとくらべて)デコーダの負担は少なくないだろう。
ていうかカリカリに書くと Retirement unit がボトルネックになるねぇ。
017397
NGNGBanias→Dothanは本質的に単純シュリンクしてキャッシュ増やしただけと思ってるのですが
Yonahは激しく別物になる気がします。デュアルコア化とは別に浮動小数ユニット強化を
うたってるので、やはりユニット増加もあり得るのでわ?
ここから電波垂れ流し↓
リアル128bitのAltiVecは良かとね〜
でも実機無いのよ PearPCはストレスたまりまくるぜい
で、クロック数正確にカウントできないので資料読みながら脳内シミュレート、これ最強。
SSE2はなんつーか、Octet-WORDじゃなくてDouble-QWORDなのが腹立つのよ
えっと、base64エンコードっぽいものをAltiVecとSSE2でやろうとたくらんでます。
16並列で処理いぇい
0174デフォルトの名無しさん
2005/04/05(火) 01:39:1901751
2005/04/05(火) 12:59:25「YonahのコアはDothanと同じ」という記憶があったが、新規のコアじゃないってだけか。
L2キャッシュが共有2MBで増えてないから、コアのロジック部だけ2つ積んでもおつりがくるね。
この前、μopフュージョンの効果はそれほどでもないようなことを書いたが、
浮動小数の強化もあることを考えると話は違ってくる。
SSEのμopフュージョンと浮動小数の強化は、ペアで実装されて力を発揮するものだろう。
SSE命令のスループットが向上して初めてデコーダが深刻なネックになる。
>>172
なるほど、シムがあったか。
2clkでできるのか。サンクス。つまり、DirectPathのデコードに関して
「Doubleは3個のデコーダの内2個を使うので(Singleが来ないと)1個は遊んでしまう」
わけではない、ということだね。
「デコードはDoubleでも簡単だけど出口が3つしかない」という感じかな。
リタイヤがボトルネックになるとはどういうこと?
デコードもリタイヤも、3macro-op/clkで同じだから、パイプラインがスムーズに流れていれば
ネックになりようがないと思うが。
ストアでキャッシュラインをまたいだときは、ストアユニットが9clk消費するだけかな。
軽く実験したが、どうもわからん。
他の処理をたくさん入れると、あと1〜2clkというところまでは隠蔽できる。
ただ、10clkの処理を入れても5clkしか隠蔽できなかったりもする。
別のμopを発行してるわけではなさそうだが、何か素直じゃないclk数のかかり方だ。
017614 ◆TimpoiKAMI
2005/04/05(火) 13:07:30もの凄い勢いで空になることはないのだ(K7にて確認)。
デコード順に、デコードされた列が同時に retire する。
で、retire 前の ops が溜まりすぎると、decoder がストールする。
L/S は、同時駆動の問題があって、どうしても理想スループットで流す
ことは困難なので、せっかく out-of-order であるコアも、
retirement ネックになってしまう…っていうのはこちらでの事例。
01771
2005/04/05(火) 13:45:42ただ、そうなるとデコード能力よりもリタイヤ能力が低いP6/PMなんぞは
もっとストールしてることに・・・。
リタイヤがin-orderなのは知ってたが、今までまともに考えてなかったな。
分岐ペナルティの隠蔽などをまた考えてみよう。
01781
2005/04/06(水) 11:51:25分岐ミスの隠蔽も、リタイヤというよりOoOでの実行順序の選び方が重要そうだし。
017997
2005/04/08(金) 23:13:04http://www.intel.com/cd/ids/developer/asmo-na/eng/microprocessors/ia32/pentium4/optimization/20243.htm?page=1
がんがれ14の中の人
018097
2005/04/08(金) 23:31:46Pentium MだとAthlonみたく依存関係の解消のためにロード・ストア頻発させたりする必要があんまり無い分、
逆に効率が良くなる面ってないっすか。そもそも内部命令数を押さえ込めばユニットの少なさをカバーできるのでは、と。
0181デフォルトの名無しさん
2005/04/09(土) 00:52:16これみてるとデスクトップ系もPentiumM系をTDPあげてクロック上げたやつ
にしてだすっぽいな
PentiumM系の研究は今後ますます重要になるはず
つーか、すでに日本ではほとんどのPCはすでにPentiumM系か
0182デフォルトの名無しさん
2005/04/11(月) 10:15:08Pentium4に最適化されたコンパイラを使った場合に、
同じコアのCeleronとPentiumで吐き出すコードが違うことってあり得ますか?
また、プログラムは単純な計算の繰り返しとして、
同周波数・同コアのPentium4とCeleronで
計算速度に有意な差は出てくるのでしょうか?
ここでいうコンパイラは、VC++2003で「/G7」オプションをつけた場合です。
よろしくお願いします。
0183デフォルトの名無しさん
2005/04/11(月) 12:27:53コンパイラオプションに、CeleronとPentiumの指定なんてないぞ。
あとコンパイラが出力するコードくらい自分の目で見ろ。
018497
2005/04/12(火) 04:07:08現行CeleronとPentiumの演算性能上の違いってのはキャッシュ容量の差くらいだからね。
そーだね、Celeronだとデータ配置アラインメント無視してでもL2キャッシュにヒットさせたほうが
効率いい場合もある、くらいかな。
VS2005ではIntel C++にあったIPOが搭載されるので、各CPUの特性に合わせたコードは
吐かせやすくなるのではないかと思いますが。
うとりっぱーでL2キャッシュが小さいCPU用のバイナリ吐くオプションもあったかな。
これはコード上で明示的にやってマクロで切り分けてるだけだけど。
Celeron用最適化コードなんてそれくらいしか見たこと無いな。
余談だが、一度試したことあるけど、crypt-core MMX版だけGCCで吐かせれば、
ほとんどVC++上でビルドできた。snprintfみたいなPOSIX依存関数をどうにかして、あと
正規表現はPCREか鬼車あたりに差し替えればいいんちゃうかな。
01851
2005/04/12(火) 13:06:26うちのPC、なぜかVS6.0がインスコできず。CDからコピったVC++6.0SP0だからSSEが使えん。
でも、そういうマクロ使えば測定ラクだね。今後の測定に生かそう。
・・・つってもネタがな。
命令のアラインやROB関係は、何か「見えない」からやる気が起きないんだよな。
完全に分岐予測の裏をかくのはやってみたい。
あとはメインメモリからのプリフェッチか。L2が2MBもあるからコンソールで手軽にできない罠。
>>181
NetBurst哀れだな。最後まで叩かれ役のアーキテクチャだった。
アセンブラでP4最適化すれば、絶対クロックの高さも考慮に入れれば
性能/価格はK8以上、じゃないかなあ・・・。
もちろん手で最適化できる規模のアプリなんて少ないんだろうけど、
ベンチの結果を見るにつけ、無駄なストール食わせまくるタコベンチなんじゃないかと心配する。
まあ、発熱という弱点があるから(NetBurst降板の理由もこれだろう)俺はPenMだけど。
次買うのはMeromの予定。デスクトップだったらAthlonがいいかな、触ってみたいし。
TDPが100Wになっていいとしても、現状のDothanは大したクロックで回らない気がする。
つまり、(各種ベンチでの)絶対性能でP4(つーかK8)に勝てないコアであると。
PenMは製造コストとかもかかってそうだしね。
今度Meromがデスクトップに来るのは、
モバイルより高くできるTDPを、クロックではなくコア数で生かせるようになったからだと推測。
(クロックを倍にするとTDPは8倍(単純計算ね;)になるが、コア数を倍にしてもTDPは倍で済む)
まあ、NetBurstの寿命と言っちゃえばそれまでだが。
PentiumMは、「遅くない」CPUという感じ。
演算器の数やクロック(つまり理論性能)は平凡だが、様々な遅くなる要因を少しずつ改善。
結果、一見P6だが速さは別物、しかも省電力というナイスなCPUになったが、
腕力はP6程度なのでK8のパワーやP4のクロックにはどうしてもねじ伏せられてしまう。
01861
2005/04/12(火) 13:09:05>吐き出すコードが違う
どんなCPUでコンパイルしようが、コンパイラの吐くコードは全く同一に決まってるだろ。
それとも、最適化の対象がPen4かCeleronかによってコードは変わるか、という質問か?
それなら変わるけど、コンパイラのオプションにはないだろう。
>計算速度に有意な差は
Pen4とCeleronの違いは、HTの有無・FSBクロック・L2キャッシュ、だけだと思う。
「単純な計算」がCeleronのL2に収まる程度のメモリしか使わないなら全く同じ速度。
そうでないならガクッと遅くなるはず。
Pen4とCeleronのL2容量がそれぞれ1MBと256KBだったとして、
例えばCeleronでL2ヒットしない処理だったら、処理単位を256KBより小さく分割するとか
入念なプリフェッチを行うとかすれば速くなる。
ただし、そういう小細工のオーバーヘッドでPen4での速度は逆に遅くなる場合もある。
まあ、メモリ上の処理を局所的に済ますのは基本じゃないかね。
昔マージソートを書いたとき、マージの回数だけ全体を舐めまわすコードにしたが、
再帰とか使ってキャッシュ上のソートを終わらせてから次のデータに移った方が速いだろう。
わかりにくいね。
つまり、データを0,1,2,3,4,5,6,7、キャッシュサイズを数字4個分とすると、
01234567 01234567 01234567 と処理するよりも、
01230123 45674567 01234567 の順番でやった方が速いということ。
上のだと、また使うキャッシュ上の0123を追い出して4567の処理をやってるから効率が悪い。
でも下のコードは再帰使うから面倒で(つーか難しくて)書かなかった。
てか182、レスはもらえてるけど欲しい情報は得られた?(w
VC初心者スレからいきなりこんなとこに誘導するのもどうかと思うが。
俺は/G7オプションとか言われてもわかんないし。
0187デフォルトの名無しさん
2005/04/12(火) 14:38:44P4にくらべて中間言語系が恐ろしい速度でまわる
JavaのサーバーVMがC言語ネイティブより早くまわる場合がある理由が
実行時に統計取りつつインライン展開やプリフェッチ命令生成とか
面白い技術が大量にはいってるんだな
そういうのがネイティブコードでつくれると楽しそうだが
自己書き換えってhotspotのもっとも原始的な技術だったのかもしれん
01881
2005/04/12(火) 14:48:55なんてのを考えたことがある。まだうまく行ってないけど。
しかしJavaがCより速いことがあるとは、Cにとっては皮肉だなぁ。
018914 ◆TimpoiKAMI
2005/04/12(火) 15:02:17それが最適化していいかどうかの判断になりうる、というのはある。
FORTRAN, Pascal などは、アグレッシヴな最適化をかけやすかった。
Cは自由度が高すぎる故に、ヘタに高度な最適化をかけると
作成者の意図しない(=作成者の書いたとおりとも言えない)コードが吐かれる
というのも、よくある話。
>>187
コアの効率がいいというのもあるけど、L1キャッシュがVM(インタプリタ)を
効率よくカバーしててツボに入っているのかもしれないね。
ていうかP4のつくりが問題外、ってのは言及したらダメ?
>>188
NTカーネルも、Unix系も、実行形式の .text は読み込み専用ページに置かれるから
自己書き換え可能なコードをつくるためには、自ら「読み/書き/実行可能」な
領域を作ってあげてそこにコピーし、場合によってはリロケーションも行って
あげる必要があるよ。
それから、近い場所の自己書き換えは、レジスタの節約になるかもしれないけど、
命令キャッシュフラッシュとか、果てはパイプラインストール/フラッシュが
起こる可能性がある(マイクロアーキテクチャによって違う)ので、
使う際にはよくよく吟味してくれたまい。ていうか実験して報告汁。
0190182
2005/04/12(火) 15:05:34Pen4(2A)とCeleD(2.66)の2台のマシンがあり、どちらの方が速いという話をしていたのですが、
VisualC++2003のコンパイラはPen4に最適化されているから、
Pen4の方が速いと、自分より詳しそうな人が言っていたので、疑問に思い質問させていただいた次第です。
この2つのCPUで比べたら、
L2キャッシュの差が出ない程度のプログラムなら、クロックの分当然Celeronが速い、
L2キャッシュの差が出るプログラムでも、クロックを考慮すればCeleronの方が速い場合が多いと
考えたのですが、こういう認識でよろしいでしょうか?
吐き出すコードが違うというのは、
VC++2003は、Pentium4とAthlonに最適化されており、
Pen4とAthlonでそれぞれコンパイラしたときには、
それぞれに最適化された違うコードが出てくると考えたのですが、
Pen4とCeleronは基本的に同じものであり、
出てくるコードも基本的には同じものであるという認識でよろしいでしょうか?
(NorthwoodとPrescottの違いはありますが、AthlonとPen4のような違いはないはずですよね?)
→これも、そのコンパイラの作りによるのかもしれませんが
0191187
2005/04/12(火) 15:17:13JavaのアトミックパッケージはCPUの命令を積極的に使ってくれ
という面白いクラス群だが、こういうのを使えばSSEとか自前で最適化
が余裕になるのかなぁと思ったり
現状でも勝手にSSEが使われたりはしてるけどね>Java
少ないメモリでユーザーに負担をかけないで扱いやすかったCは
今となっては非常に厳しいというか、こまかいのやりたかったら
アセンブラと併用せよというスタンスだよね
結果C部分とのやりとりで最適化の範囲とかに制限が出て
あまり代わらずとかいったかんじも多い
VS2003もってないんだけど、C言語での最適化指定ってどの程度できるもんなの?
0192デフォルトの名無しさん
2005/04/12(火) 17:02:45自己書換やると命令キャッシュが悲惨なことになるし、
RISCにとっては、即値ったってロードするし・・・
JavaがCより速いのは、
最適化を阻害する要素を色々と排除してることと、
無駄なコードが減ること、
その2点だと思う。
Javaだと簡単に書けることが、C++だと色々と気を使って処理たくさん書くしね。
0193192
2005/04/12(火) 17:11:35>>190
四の五の言ってないで実機で試せ、というのがこのスレの信条ですよ。
>>186をよく読み直したほうがいい。
コンパイラを走らせるCPUと、出力されるコードのターゲットのCPUは、関係ない。
たとえば、SSE2を使ったPentium4用のコードを、
SSE2を持たないAthlonでコンパイルして出力することも、普通にできる。
というか、少しはVC++の設定画面とマニュアルを嫁。
実際にやってみれば、すぐわかることだぞ。
0194デフォルトの名無しさん
2005/04/12(火) 18:32:030195デフォルトの名無しさん
2005/04/12(火) 18:33:12スレ違いだが、クロスコンパイラなら、コンパイルするCPUと、吐き出すコードの
CPUが全く違っていてもいいね。gccなんかでは当たり前。
0196デフォルトの名無しさん
2005/04/12(火) 20:37:53Javaだと動的にプロファイルをとって、実行時間の
かかる処理を重点的に最適化できるからじゃないの?
loop unrolling とかってやりすぎると命令キャッシュ的
に逆効果になるけど、動的なプロファイルを行えば、
時間のかかっているところだけ重点的に unroll するとか
できるわけだし。
まあ昔の mips コンパイラも、実行結果のプロファイル
をファイルにセーブして、再度最適化し直すってことが
できたわけで、Cでもできないわけじゃないというか、
単なるロストテクノロジってだけかもしれんけど。
0197デフォルトの名無しさん
2005/04/12(火) 21:58:06http://logic.is.tsukuba.ac.jp/~kam/ppl_ss04/ishizaki.pdf
0198デフォルトの名無しさん
2005/04/12(火) 22:07:20GCがあることを速度的にメリットがあるという方向へもっていったのはすごい
最初すごく遅かっただけに、速度へのこだわりはすごいんだろうね
昔はi++よりi=i+1のほうが早いとかびっくりしたからなぁ
0199デフォルトの名無しさん
2005/04/13(水) 01:52:27原理的にできるからといって、実際にパフォーマンスが良いとは限らないと思う。
プログラムの最適化のために、プロファイルを取って見るんだけど、
Instrument有効にして走らせると、まるで止まっているかと思うくらい重くなるし、
しかも、それによってCPUのキャッシュのヒットの仕方が変化しちゃうから、
あんまりあてにならなかったりするよ。
020097
2005/04/13(水) 02:42:56SP4&SP5までなら対応のプロセッサパック入れれば使えますが。
SP6だとプロセッサパックが強制削除されるので仕様不可。
あと、Visual C++ Toolkit 2003も無償でDLできますね。Boostもほとんどビルド通るし。
漏れが良く逝くオフでコンパイラの話になると、IDEはStandard版でコンパイラだけToolkitにしてるって
人が多数ですね。
で、やっぱりWindows最強はゲイツコンパイラが最強な気がする。
Intel C/C++は、命令スケジューリングは最強だけどANSI C++な機能使うとなにかとトラブる。
テンプレート引数とか。
SIMD対応のコンパイラだと、まだ実用に足るとはいえませんが、こんなのもありまつね。
http://www.coins-project.org/
> TDPが100Wになっていいとしても、現状のDothanは大したクロックで回らない気がする。
> つまり、(各種ベンチでの)絶対性能でP4(つーかK8)に勝てないコアであると。
これは選別さえすればどうにでもなりそうな要素かと思ってますが。
http://www.gamepc.com/labs/print_content.asp?id=770ct479
ノート用CPUであるためマージンをとってあるだけで、TDPの縛りさえなければ定格電圧で
2.4GHz(Carmel, 7x5シリーズ)もしくは2.53GHz(Sonoma, 7x0シリーズ)動作する石が採れる
という話を聞いたことがありますが。
あと、意図的に抑える理由も十分あると思いますね。
Yonahでシングルスレッド性能も向上させて、インパクトを与える必要があるでしょうしね。
基本的にDothanは浮動小数以外は弱点の無いコアだと思ってますが。
L2キャッシュの容量も帯域もロードレイテンシの短さも十分強みだと思います。
PenMがオブジェクト指向の動的コードに強いというのは分岐予測まわりの効果だと思いますよ。
これもIntelのサイトに解説がありますた。
020197
2005/04/13(水) 03:22:42えっと、浮動小数でSSE/SSE2を使うオプションはあるけど、
たとえば__int64型を使ったら自動的にMMX使ってくれるとか、またループを自動的に
ベクトライズしてくれるとか、そのレベルの最適化機能は皆無。
IA32の基本命令オンリーでなら最適化性能は最高クラスと思ってますが。
あと、MMX/SSEを使うなら組み込み関数やそのラッパークラスがかなり便利ですね。
決して使い勝手がいいとはいえませんが。
呼び出し規約を__fastcallにすれば3つまでならMMX/SSE組み込み型の変数をレジスタ渡しできます
(それ以上、もしくは__stdcallや__cdeclだとコンパイルエラー)
0202デフォルトの名無しさん
2005/04/13(水) 07:52:35Standard版とVC Toolkitのコンパイラの違いってどこかに比較表ありませんか?
02031
2005/04/13(水) 09:37:52俺がやっていたのは、VBで配列にマシン語のサブルーチンを読み込み、APIで実行というもの。
自己書き換えではなかったな。スマソ。
その後、nasmを使ってVBのコードに埋め込んだアセンブラをアセンブルして
状況依存のコードを作るというのを試みたが、これはなぜか失敗。
それ以来ろくに追究もせずやってない。
>>190
そういう質問意図を最初に書いてればもっと的確なレスがもらえたと思うよ(ていうか回答しやすい)。
その認識でいいが、キャッシュの影響がどの程度か考えるのが難しい。
P4コアの場合、ベンチ結果見るとキャッシュの量はかなり重要。その程度のクロック差など引っくり返る。
それに256KBのL2で完結するアプリなんて、どっかのCPUベンチぐらいだろう。
>吐き出すコード
それは違う。まず言葉遣いに禿しく注意。
・VC++はP4に最適化されている=VC++でのコンパイル作業はP4でやると速い
・VC++はP4に最適化されたコードを吐く=VC++でコンパイルしたコードはP4で実行させると速い
下の意味で言ったんだと思うけど。
大体、開発マシンによって最適化対象が変わったら不便でしょ?
それはコンパイルオプションで指定するもの。
#まあ俺も以前VC++6.0でSSE命令がコンパイルできないのをCPUがSSE非対応だからだと思っていたがな。
>>193>>195にあるように、SSE非対応のCPUでSSE命令をコンパイルすることは当然可能。
クロスコンパイラ然り。例えばMacOS用のアプリをWindowsマシンで作れる。
>>84あたりを見て、182もクロック測定の道に踏み入れてはどうかな?(w
02041
2005/04/13(水) 09:39:24>このスレの信条
いいこと言うね。俺も口先だけで言うよりも、なるべく実験結果を貼るよう心がけてきた。
(最近あんまりやってないけどな)
ただ、(測定の)初心者には実機で試すのが意外と荷が重いのよ。いくつか書いとく。
まずVC++2003のマニュアルをよく読む。
CPUは、得意分野と苦手分野で性能が意外と変わる。一般のベンチではなく、
自分が書いてVCでコンパイルしたプログラムでPen4とCeleronの性能比較をすべし。
測定ルーチン作りたくなかったら、PCの前でストップウォッチを使え。
VC++6.0だと、プロジェクト>設定>C/C++>ファイルリスティング>マシン語コードとソースを含む
とするとコンパイルしたときに一緒にファイルが生成されてCのコードとアセンブラの対応が見られる。
コンパイラオプションを変えるとこのコードが変わるのかーとか思っているだけでもいいと思うよ。
何かコンパイラの吐くコードに興味が出てきたな。
VC++6.0に簡単な処理をコンパイルさせて、俺のアセンブラと速度や構造の違いを考察するとか。
試しに100から199まで足させてみた。PenPro最適化でこんな感じ。
xor ecx, ecx
mov eax, 100
$L528:
add ecx, eax
inc eax
cmp eax, 200
jl SHORT $L528
まあ普通だ。即値で比較してるのが気持ち悪いけど。カウンタにeaxてのも変な感じ。
また、この即値(100や200)は内部4byteである。この方が速いのかな。
02051
2005/04/13(水) 10:08:32いや、VC++が正規インスコできないからSP5も当てられないわけで。
リンク先のベンチ結果を見たが、PenMを2.7GHzにするとすごいんだな。さすが。
俺は価格の面でPenM-2.7GHzは不利なんじゃないかと思った。パイプラインも短いし。
NetBurstをやめるのに引っ込みがつかないから、
Pen4を追い越さないように意図的にPenMの性能を抑えるというのはあるかも。
>>180
PenMは、素直にアセンブラで書けば理論性能が出てしまうという組みやすいCPU、
というような認識だね。俺は。
Javaの仕組みはよく知らないが、JavaがCに勝つのは単にCを書いた人がヘボという気がする。
でもそれはCとアセンブラの関係と同じで、原理的にはアセンブラの方が速くても、
複雑なプログラムの場合アセンブラで書くと頭がこんがらがって遅くなってしまう。
適材適所っていうか、人間の頭が回る範囲で低級言語を使い、あとは素直に高級言語を使う
ってのがいいんだろうな。
0206デフォルトの名無しさん
2005/04/13(水) 11:01:30>190を誘導した張本人です。色々とご迷惑を。
で、このスレは基本的に読むに留まってますが、手元にgcc/vc7.1があることだし
最適化に関してはCのソースを貼ってくれれば追試しますよ。
尚、>204のコードでカウンタにeaxを使うのは単にeaxが一番壊れる機会が多いレジスタだからかも。
Cのロジックが変わると他のレジスタを使うかもしれません。
ecxも同様で、ロジックによってはesi辺りに置き換わる可能性が高そう。
#この辺はもう少しロジックが複雑じゃないとなんとも言えません。
即値が内部4バイトなのはどうなんでしょうね。gccでは1バイトの即値を使ってた気もするんですが。
#これも調査対象かな。
Javaが速い件については、>189の言う「自由度が低いから大胆に最適化しやすい」からでは?
総体的(≠相対的)にはCの方が速くなる余地があると思いますが。
02071
2005/04/13(水) 11:20:55いえ、ネタ提供ありがとうです。
とりあえず自分でVC++6.0と勝負して来週にでも結果貼るので、そんときはよろしく。
俺は自分以外の人やコンパイラの書いたアセンブラをあまり読まない(読めない)ので
レジスタの使い方なんかがすごく新鮮だった。今は完全に自分流だからな。
>自由度が低いから大胆に最適化しやすい
ちょっと話がそれるかもしれないが、自由度を削ると最適化しやすくなるのは確か。
カリカリにチューンしようとあがいてもこんがらがってまとまらないとき、
データの配置とかを(理論性能を削ってまでして)きれいにすると、
簡単にその制限内での理論性能を出せたりする。
0208デフォルトの名無しさん
2005/04/13(水) 13:35:26それに、速度を上げるためにコードをあれこれいじり倒すとなると、
アセンブラで書くよりも、Cで書いたほうが短時間で多くのパターンを試せるし。
0209デフォルトの名無しさん
2005/04/13(水) 13:48:43JavaがCより早いってのは適当にコードかくとわりあいよくでるよ
JavaとCはほぼ同じ構文なので書き方の差はうまれない
ハノイの塔とかソートとかかいてみそ
もちろんCが早い場合もあるが、速度的な差はほとんどないねぇ
0210190
2005/04/13(水) 17:20:46もう少し自分でも勉強してみます。
やっぱりまずやってみることですね。
021197
2005/04/13(水) 21:54:02Knuth本やHD(ハッカーのたのしみ)あたりの本を一通り読むと手動最適化のセンスが身に付くかも。
コンパイラの性能よりも使う人間のテクニックのほうが重要だったりします。
>>202
TKはVisualStudio Professional以上についてるコンパイラの英語版と同等。
Standardのコンパイラは最適化自体が出来ない。
Toolkitは専用スレもたってるしそちらのほうが詳しいと思われ。
あと、コンパイラ差し替えても使えるには使えるが、結構メンドイ、とのこと。
もしこれから購入を検討されてるのなら、2005だとStandardクラスにも最適化コンパイラが
含まれるから、それまで待つのもアリかと思いますよ。
Pentium Mは今年の中旬に780(2.26GHz)を出すとか。
番号的には790までで打ち止めな気がするので、Yonahが万が一延期になってDothanで引っ張ったとしても2.4GHzまでか。
Yonahは2.5GHz超えてくるという話だし、Meromを待たずしてPentium 4を食っちゃうかも。
0213デフォルトの名無しさん
2005/04/14(木) 21:24:23SSE2のサポートがちょっと変。
_m64 a[] = {
0xd76aa478d76aa478,
以下略
っていうのはできるけど、
__m128i a[] = {
0xd76aa478d76aa478d76aa478d76aa478,
以下略
ってのはできない。
_m128iの定義を見ると共用体で、
最初のメンバが__int8が16個なので、
__int8で初期化しないといけないようで。
0214●○●○●○ 9 7 ●○●○●○
2005/04/14(木) 23:58:05それハマったことがある。
そもそも__int128型が無いから仕方が無いとの結論。
うちは大体これでやってますが。
__m128i a[2] = {
{ 0xFFFFFFFFFFFFFFFFi64, 0xFFFFFFFFFFFFFFFFi64 },
{ 0x00000000000000000000i64, 0x00000000000000000000i64 }
};
intrinsic使うなら _mm_set_*系の組み込み関数使うのも便利かと。
C++でやる場合はdvec.hをインクルードして
static const Iu32vec4 n(a, b, c, d);
とかやっちゃったりすることもありますが。(定数化すればコンストラクションのオーバーヘッドなし)
0215●○●○●○ 9 7 ●○●○●○
NGNG実はリアル知り合いに某エミュの開発者がいるけど、VT(Vanderpool)対応が云々とかなんか楽しそうな話題を
しておりますね。CPU側のVMサポートがあるとかなりパフォーマンス面でも有利らしい。
現行Pen4ではまだdisableらしいですが。
02161
2005/04/19(火) 12:33:29PentiumMでのレイテンシ-スループットは、
fadd 3-1, addsd 3-1, addpd 3-2(内部3-1を2回。別の種類の命令相手だと4-2)
for (i=0; i<1000; i++) q+=p[i]; //double p[1000]の総和を求める
これをVC++にやらせると3065clk。
$L591:
fadd QWORD PTR _p$[esp+eax*8+8016]
add eax, 10
cmp eax, 1000
fadd QWORD PTR _p$[esp+eax*8+7944]
fadd QWORD PTR _p$[esp+eax*8+7952]
・・・6行分中略・・・
fadd QWORD PTR _p$[esp+eax*8+8008]
jl SHORT $L591
fstp QWORD PTR _q$[esp+8016]
#_p$ = -8000なので、_p$[esp+eax*8+8016]は[esp+eax*8+16]と同じ。
なんと10回もアンロールしてくれた。10*100=1000だ。
そこでちょっといじわるしてi<997(素数)にしてみた。すると、8回アンロールのあとに追加で、
$L591:
fadd QWORD PTR _p$[esp+eax*8+8016]
add eax, 1
cmp eax, 997
jl SHORT $L591
なんと8*124+5だ。コードに5が出てこないところにセンスを感じた。eax=997-997%8 なのがミソ。
俺ならfaddを5個書くが、こうすれば何個半端がでるか考えずに書けるんだな、と感心。
ていうか、機械のくせに997-997%8を計算してその個数のfaddを配する手間を惜しんでることに感動した。
(本当は1*5を5*1にアンロールしてもコードサイズが増えるだけで速くならないからだろう)
02171
2005/04/19(火) 12:34:15for (i=0; i<1000; i+=2) q+=p[i]+p[i+1];
$L591:
fld QWORD PTR _p$[esp+eax*8+8024] ;st = p[i+1] q
add eax, 2
cmp eax, 1000
fadd QWORD PTR _p$[esp+eax*8+8000] ;st = p[i]+p[i+1] q
faddp ST(1), ST(0) ;st = q+p[i]+p[i+1]
jl SHORT $L591
なんと2100clk(4clk/loop)。faddのレイテンシは3なので、これはすごい。アンロールはしてない。
まとめてから足すのでレイテンシ3をまともに食らうのがfaddp ST(1), ST(0)だけになる。
これはCで並列性を持たせて書いた人がえらいのだろう。
for (i=0; i<1000; i+=4) q+=p[i]+p[i+1]+p[i+2]+p[i+3];
調子に乗ってこんなことすると1700clkにまでなった。でもこれは謎。
$L621:
fld QWORD PTR _p$[esp+eax*8+8040]
add eax, 4
cmp eax, 1000
fadd QWORD PTR _p$[esp+eax*8+8000]
fadd QWORD PTR _p$[esp+eax*8+7992]
fadd QWORD PTR _p$[esp+eax*8+7984]
faddp ST(1), ST(0)
jl SHORT $L621
どう見てもレイテンシ3を3回食らってる。2500clk以上かからないとおかしいのになぁ。
ひょっとしてPenMはFPUのスケジュールが強化されてる?Athlonならどうだろう。
for (i=0; i<1000; i+=2){ q+=p[i]; r+=p[i+1]; }
これは2000clk。アンロールしてくれたらもっといくはず。
for (i=0; i<500; i++){ q+=p[i*2]; r+=p[i*2+1]; }
こうするとアンロールしてくれる。1700clkくらい。
02181
2005/04/19(火) 12:34:47for (i=0; i<1000; i+=2) s=_mm_add_pd (s, _mm_loadu_pd( &p[i]));
アライメントが合ってない状態でmovapdしてたのに気づかず長時間悩んだ。Cだと油断する。
$L1941:
movupd xmm1, XMMWORD PTR [eax]
add eax, 16
dec ecx
addpd xmm0, xmm1
jne SHORT $L1941
2300clkだった。変数のsはqとrをくっつけたもので、addpdはfaddを2回やっている。
実行ユニット的にはに上の2000clkのコードと同じなのだ。
で、更に並列性を上げる。
for (i=0; i<1000; i+=4){ s=_mm_add_pd (s, _mm_loadu_pd( &p[i])); t=_mm_add_pd (t, _mm_loadu_pd( &p[i+2])); }
$L1975:
movapd xmm1, XMMWORD PTR _t$[esp+8064]
npad 9 ;この9byte nop って意味あるのか?
$L1943: ;ここへジャンプしてループに入る。
movupd xmm2, XMMWORD PTR [eax-16]
addpd xmm0, xmm2
movupd xmm2, XMMWORD PTR [eax]
add eax, 32
dec ecx
addpd xmm1, xmm2
movapd XMMWORD PTR _t$[esp+8064], xmm1
jne SHORT $L1975
これが2400clk程度。遅い。どう考えてもmovapdが無駄なのだが。
直前にこれを書いた。
s=_mm_xor_pd (s, s); t=_mm_xor_pd (t, t);
このtの部分をt=s; としたら無駄なmovapdはなくなり、1900clkになった。
更にもう1回アンロールで1700clk。意外と伸びない。
02191
2005/04/19(火) 12:35:16FP_ADDフル稼働で1000clkが理論値。
>>73のコードが11clk/loopもかかる謎と同じっぽいな。ADD側のユニットが混むと妙に遅くなる。
最適化なしのコードは本当にCのそのまんまで笑った。
必ずメモリに書き戻してから次の計算するし、順番もCの規約通り変わってない。
さて、俺も書こう。まず素直にやって3200clk。
lp:
fadd qword ptr [eax]
add eax,8
dec ecx
jnz lp
FPUって謎多いよな。並列実行の方法は色々あるが、それをまぜたら少し速くなった。1600clk。
lp:
fadd qword ptr [eax+ecx*8-32]
fld qword ptr [eax+ecx*8-24]
faddp st(2),st
fxch st(2)
fadd qword ptr [eax+ecx*8-16]
sub ecx,4
fld qword ptr [eax+ecx*8+24]
faddp st(4),st
jnz lp
addsdを使ったが、1700clk。FPUと同じだ。
そしてaddpdを使って16byteアライン許しても1800clk。うーん遅い。
コンパイラの実験というよりFPUの調査になってしまった。
しかしこんな簡単な処理で4レス分も食うとは思わなかった。
クイックソートとかやろうと思ってたけど、やったら壮絶なことになりそうだ。
02201
2005/04/19(火) 12:35:50当時PenMは認知されてなかったみたいで自動的にPen4最適化となるらしい。
for (i=0; i<1000; i+=2){ q+=p[i]; r+=p[i+1]; }
$L1939:
movsd xmm2, QWORD PTR _p$[esp+eax*8+8008]
addsd xmm2, xmm1
movapd xmm1, xmm2
movsd xmm2, QWORD PTR _p$[esp+eax*8+8016]
add eax, 2
cmp eax, 1000
addsd xmm2, xmm0
movapd xmm0, xmm2
jl SHORT $L1939
3200clk。なんかタイミングが合ってない。まともに最適化できてません。なんでだろ。
for (i=0; i<500; i++) にしたらアンロールしてくれて1700clk。
ただ、これもxmm2にだけ足していくコード。なのにレイテンシ3を食らっていない様子。
上の2500clkかかるはずのコードと同じ謎だが、ここで謎が解けた、レジスタリネーミングだ。
10回に1回だけであっても依存関係を断ち切れば、ほぼ完全な並列実行が可能。
恐るべしリネームの威力。そしてROBの数。
コンパイラと勝負と言ったが、そもそも勝負できる類のものではない気がしてきた。
コンパイラが理想的なコードを吐くならアセンブラに勝ちはないし、
アセンブラでないとできない(原理的にCでは表現できない)手法を使うならコンパイラは必ず負ける。
もちろんコンパイラの最適化は完全じゃないし人間アセンブリにも隙があるから勝負にはなるけど。
完全で隙がない理想を見ているからかな。変なこと書いてスマソ。
Cレベルで高速化する技術なしにやったって、コンパイラ不利になるのは確か。
アセンブラはCPUのご機嫌とってればいいからまだマシだが、
CだとコンパイラというCPU以上に顔色の見えないヤツ相手に書くから大変。
02211 ◆.MeromIYCE
2005/04/19(火) 12:59:35Cができない頃は、マンデルブロ集合やFFT作るのにネイティブコードコンパイルは重宝した。
最適化フルオプションにしたのを逆アセ。
For i = 0 To 999: q = q + p(i): Next
xor eax,eax
lp:
cmp eax,edi ;edi==999
jg exit_lp
fld qword [edx+eax*8]
add eax,ecx ;ecx==1
fadd qword [ebp-0x38]
fstp qword [ebp-0x38]
jmp short lp
8000clk。即値は4byte。即値比較やincを使ってない。なんかCのよりRISCっぽ。
ちなみにCでコードサイズ優先だと8000clk。最適化なしだと26000clkかかる。
For i = 0 To 999 Step 2: q = q + p(i) + p(i+1): Next
xor eax,eax
lp:
cmp eax,edi ;edi==999
jg exit_lp
fld qword [ecx+eax*8]
fadd qword [ebp-0x38]
fadd qword [ecx+eax*8+8]
add eax,edx ;edx==2
fstp qword [ebp-0x38]
jmp short lp
これだと5600clk。Cではコードサイズ優先が4000clk、最適化なし15000clk。
VB5.0の速度優先はVC2003のサイズ優先に速度で勝てない。所詮は昔のVBか。
でもVB5.0Pro→VC++Standardではガクッと遅くなってしまうんだね。
02221
2005/04/19(火) 13:00:30コンパイラは、人間と違って頭(CPU)がこんがらがってしまうことがないから大域最適化向きだよ。
「C、C++の最適化について語るスレ」でも色々話されてるね。
今回の実験の並列性持たせるのは200で言われている。有名なのか。
関係ないけど212がわかりやすい。変な議論する前にバシッとこういうこと言えたらいいとオモタ。
275のレスはすごい。
それで思い出したが、キャッシュのWay数についての実験はまだなのでやってみよう。
で、キャッシュの実験。PenMのL1Dataは8Way,32KBとなっている。
イメージとしては、メインメモリ全体を32KB/8Way=4KBずつに切って重ね、
重なった同じ場所の64byteラインで8つまでがキャッシュに置けるって感じか。
lp:
add eax,[esi]
add esi,8000h ;32KB(8Wayが既知なら4KBでいい。どちらでも結果にはほとんど影響なし)
dec ecx
jnz lp
これでecxの値を変えてクロック測定。ecxが1〜20のときのクロック数は以下の通り。
1 3 3 7 9 11 15 17 33 36 42 46 48 78 86 94 103 119 131 148
ecx>=8ではかなりクロック数がふらつく。
ふらつく場合、最も少ない値を採用した。
ecx=8では、運悪くアドレス値を4KBで割った余りがesiと同じメモリを測定ルーチンが使うと
L1から[esi]が追い出され、L1ヒットしなくなる可能性が大きくなっている。
これでL1が8Wayであることが検証できた。
L1ヒット時は2clk/loopとわかる。また、使ったメモリが640KBなのでL2なら完全ヒット。
結果をプロットすると、[1-8][9-13][14-17][18-20]のきれいな4本の線になる。
まずecx=9の遅さが謎だ。2回のL1ミスで済んでない?
あと13と14の間に断絶があるのも不可解。78-48=30clkも増えてる。
02231
2005/04/19(火) 13:01:15「特定の道路(CPU)で速く走る車(コンパイル後のアプリ)を、実際に道路で試しながら作る」
これだとコンパイル作業をしたCPUに最適化される。
ていうかこういうコンパイラ誰か作らないのかな。コンパイルは重くなるけどけっこういいんじゃ?
あと、「VisualC++2003のコンパイラはPen4に最適化されているから、 (Celeronより)Pen4の方が速い(有利)」
かどうかというのが182の疑問の発端なわけで、これの答えはNoだと思う。
P4最適化というのはNetBurst最適化のことでキャッシュの量はさほど考えてないだろう。
/G7オプションとはP4最適化のことだな。これをつけるとinc eax がadd eax,1 になった。
P4のincはフラグでパーシャルレジスタストールを起こす。
>>189
FORTRAN, Pascalのコンパイラを書いたの?
俺はコンパイラもインタプリタも書いたことないから感覚がわからない・すごさがわからないよ。
>>208
どんなコードで負けた?
俺が作ったのはライフゲームやマンデルブロ集合(←SIMDで効果絶大)、せいぜいintのクイックソート程度。
小さいプログラムだからコンパイラには負ける気がしない。
Cだと短時間で多くのパターンを試せるというのは同意。まずはアルゴリズム、これ基本。
実際、実用のプログラムでアセンブラはほとんど使うべき場合がないと今さら気づく。
速度ネックな処理でアルゴリズムも詰めてあるのが前提で、開発期間や拡張性を考えたらねえ。
ていうか少し前までは本当に負ける気がしなかったし、コンパイラに負ける人は本当にヘタレだと思ってた。
でもそうじゃないんだよね。
FFTとかやろうとしたら手が止まる。アルゴリズムを完全には理解していないのが露呈する。
一応は理解してるからCのFFTなら書けるけど。今アセンブラで書いても勝てる自信がない。
アセンブラを書くって、Cを手でコンパイルするというより
理解したアルゴリズムをx86語で話す感じで、逐次処理の論理じゃなく全体構造のフィーリングなんだな。
そうでないと手書きasmのスピードにならん。
02241
2005/04/19(火) 13:57:32Cレベルじゃなくてアルゴリズムレベルの話。Cのコードもこの方がきれいになる。
>>209
そうなのか。俺はJava書いたことないので何もわからんです。
Javaってインタプリタってよりも、その場でコンパイルするコンパイラって感じだね。
Cに同じ最適化技術が入れられないのは「自由度が高い」からか。
ていうかJavaのが速いんだったらJavaをx86ネイティブにコンパイルとかできないの?(Javaの意味ないけど)
>>211
そのYonahのクロックまじ!?少なくともスミス3.2GHz*2なんかじゃ歯が立たないだろ。
TDP31W→1コア当たりのTDP15Wだからクロック据え置きだと思ってた。
それにしても長文過ぎる・・・orz
1000個足すだけの単純極まりないコードごときで。
022514 ◆TimpoiKAMI
2005/04/19(火) 14:06:54>>224
>ていうかJavaのが速いんだったらJavaをx86ネイティブにコンパイルとかできないの?(Javaの意味ないけど)
「gcc gcj」でぐぐれ。
02261 ◆fXdaP.6t26
2005/04/19(火) 14:21:56スマソ。あるのね。
アプリをCのソースで配布して各環境でコンパイルすれば一番だと思ったけど、
ソースコード強制公開になっちゃう。
02271 ◆fXdaP.6t26
2005/04/19(火) 14:25:530228デフォルトの名無しさん
2005/04/19(火) 16:47:49http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/317.txt
私には解説できませんが、見れば判ると思います。
997回ループは「最初の代入+4*249回」になってしまったので991回ループも試してみました。
どうやら、「3+4*247回」のようで、どうも4回アンループがお好きな様子。
手動アンループはドツボにはまりそうなので、未だ試してません。
0229●
NGNGC++.NET 2003の /G6オプションは レジスタ・メモリ間命令をかなり避けるような。
μOPsフュージョン大して生かせないんじゃねーかとか思ったり
で、G7なら速くなるかというと、そうでもないみたいで(Pen4の長いレイテンシを埋める最適化をしてるような)
このへんはまだPentium III向けの悪寒。2005でようやくモダンなCPUに追いついてくる気がする。
Professional以上ではPGO(前のレスではIPOと言ってたがこれは間違い)も搭載されるので
チューニングがきいたときの性能にはかなり期待できそう。
ちなみに今無料で落とせる2005のβはグローバル最適化が無効でかなり悲惨な出力になる罠。
0230●
NGNG>無料で落とせる2005のβ
こっちはStandard相当のね。最適化がついただけでも相当な進歩かと思われ。
MSDN限定のベータは幾分かマシ。
02311 ◆.MeromIYCE
2005/04/20(水) 10:48:06実験サンクス。
4回アンロールか。10回のもあるね。VC++で俺が見たことあるのは8回と10回。
アンロール回数っていうのは命令キャッシュ量依存なのかね。
add/cmp/jcc という流れなので非常に読みやすい。
まあ、P4以外ではFPUとALUの命令を混ぜた方がいいので若干最適化が甘いとも言えるかも。
アンロールの半端部分は先に足しちゃうんだね。
なんか人間の書いたコードみたいだと思った。
>>229
確かにP6はデコード・リタイヤネックが大きいからそういうコード吐くだろうね。
でも上でVCが吐いてるコードはfadd [mem] だな。FPUは命令分けるとかえって遅いとか?
測定はせずに、オプション変えてコードを眺めるってのもいいかもね。
02321◇MeromKX/1Q
2005/04/20(水) 10:51:18だからAthlon向けに最適化すればいいかと(PMじゃパワー不足かな)。
だけど/G7オプションの説明見ると「Pen4またはAthlon」ってあるのよね。
一緒にできるアーキテクチャじゃないと思うが。
やっぱMicrosoftはIntelびいきなのか?
足すだけはさすがに単純すぎた。
次は、最適なアセンブラ化がすぐにはわからない例でやってみたいけど、いいのがない。
昔クイックソートをCとアセンブラで書いたが、長くて読む気がせん。
(cmov使ったら遅くなった覚えがある)
再帰のマージソートかな。安定で、独自に発見したので愛着がある。メモリ倍食うのが痛い。
で、このスレの主題となるのはクロック測定。
それはつまりCPUの(この辺は物理的制限かなとか思いつつ)論理構造を知るということ。
(PenMと、1THzのPen4でエミュられたPenMは原理的に区別できない。THzじゃ無理?)
アセンブラやるまでL1キャッシュとレジスタの違いを知らなかった。
アセンブラをやるとCPUの仕組みがわかってくる(少なくともL1とregの区別はわかる)。
クロック測定をするとCPUに関して更に時間軸も見えてくる。
今のところ、命令毎のクロックや使用ユニットは大体わかった。
謎なのはキャッシュ。特にL2とL1の間のバス。当然メインメモリもだが。
PMのキャッシュについてはレイテンシがP6より大きいと言われるが、
河童Celeron-400より確実に性能はいい。L/Sバッファ周りかも知れないけど。
L2容量を減らしたせいか、たまにCeleronはキャッシュのWay数が半分だったりもする。
同じコアのキャッシュを削るという荒技なのでオーバーヘッドがあるのかしら。
02331
2005/04/20(水) 11:04:59期待したCPUコアの詳細については書いてなかった。
P6とK7が争ってた頃は、形だけでも実行ユニットの数やパイプラインの段数が書いてあったのになぁ。
まあ、Prescott31段!とか書けないか(w
Trip-MonaでAthlonの性能がやたら低いが、これはキャッシュだろうな。
多分、低レイテンシのキャッシュが256KBあるかどうかで数字が分かれるソフトなんだろう。
つーか1+8コアのCELL萌え。
x86も、従来コード向けで1コア確保して、小さいコアも4個乗せるとかダメかな。
従来アプリの高速実行というシバリがでかすぎる。ある程度捨てたP4でも酷評されるからな。
ただ、CELLみたいのって、外付けでもいいから欲しい。
あ、それはGPUか。
0234デフォルトの名無しさん
2005/04/20(水) 12:31:20さすがにそれは・・・
つーか、俺が始めたときにキャッシュなるものはなかった・・・
Cellは元々あれでビデオ描画やる予定だったのでああいうつくりになったかと
PS2よりは汎用性あるけど、所詮そこまでという感じのあくまでも延長線上に
あるもので、いわゆるマルチコアというくくりではないねぇ
スレッド切り替えで退避できないつくりでは
そもそもMAXが256KB
02351
2005/04/20(水) 12:54:11まあ、ポケコンやVBで育ったので勘弁してちょ。
Cellについては確かにそうだが、自分で遊び倒すという意味で萌えた。
できれば倍精度浮動小数があるとよかったな。マンデルブロ集合とかやらしたらめちゃ速そう。
0236228
2005/04/20(水) 13:31:39私ゃ逆に、マイコンから入って386辺りで挫折した人間ですが。
68KやSparc触りだすと、CISCアセンブラ書くのが億劫になってくるんですよ。
0237デフォルトの名無しさん
2005/04/20(水) 17:13:52>俺が始めたときにキャッシュなるものはなかった・・・
同意。
(つか、俺の場合、「まだ、『始めた』内に入ってない」といわれそうだが。)
Z80とか68000にはキャッシュがなかった。
(68020以降ならキャッシュもあったが。)
8086の「プリフェッチバッファ」って、
なんとなく、命令キャッシュの超簡易版みたいなもの?
(P4のトレースキャッシュとか、通常の命令キャッシュと違って、
ホントに先読みだけだけども。)
>>236
>68KやSparc触りだすと、CISCアセンブラ書くのが億劫になってくるんですよ。
68kはCISCだと思う。
0238デフォルトの名無しさん
2005/04/20(水) 17:18:18>236は68Kでアセンブラを書いているとは言ってないな。
68KやSparcだとそもそもアセンブラを使わないんジャマイカ?
0239デフォルトの名無しさん
2005/04/20(水) 17:55:360240●
2005/04/21(木) 01:54:02> Trip-MonaでAthlonの性能がやたら低いが、これはキャッシュだろうな。
> 多分、低レイテンシのキャッシュが256KBあるかどうかで数字が分かれるソフトなんだろう。
128KBの定数テーブルテーブルサイズを8byteずつランダムルックアップする感じだから
L2ロード性能依存と。
帯域も広くレイテンシも小さいPentium IIIマンセーなコードですな。
うちもあのサンプルコード見てSSE/Enhanced 3DNOW!で追加されたpextrw/pinsrwの使い方の
芸術性を見た、と言う感じですな。
utripperも基本的に同等のものですね。
この2つ、PrescottだとあのL2のレイテンシのせいでやたら遅いのでつが、
HT有効時二重起動でトータル40%くらい速度アップした。
でも普通にNorthwoodのほうが速いです(爆
0241237
2005/04/21(木) 14:36:35つーか、かなりの物作った。CISCという意識はなかった。スマソ
0242236=241
2005/04/21(木) 14:37:430243デフォルトの名無しさん
2005/04/21(木) 15:56:20CISC vs RISC論争の時、
内部が複雑なのでクロックを上げれない例として
引き合いに出されたのは、むしろ68040ではなかったかと。
80486に比べても、クロック・実効速度で大きく遅れてました。
結局、「複雑」ってのは、アーキテクチャよりも
むしろ、マイクロアーキテクチャの部分だったのでしょう。
0244デフォルトの名無しさん
2005/04/21(木) 16:24:02モトローラがインテル並のシェアがあったら大量の金つぎ込んで
いくらでもいいの作れたと思うが
040は486とくらべて実行速度で大きく遅れてる感じはしないのだけれども
060はPentiumにくらべるとバス周りがなぁ
でも、68Kはアセンブラによる最適化が異常に進んだおかげで
非常にいじり倒す人にとっては面白い石ではある
68000-16MHzは386-20MHzより大概早かった
まぁ当時はキャッシュ容量もほとんど無く、メモリのウエイトとか
レジスタ数が純粋に速度に貢献してたからね
そもそもZ80にくらべれば68000-10MHzは天国だった(ぉ
024514 ◆TimpoiKAMI
2005/04/21(木) 16:24:18※俺が使ってたのは XC68040
当時の68040は、同クロックの486より速かったというのは俺の感想。
ただ、-25 品には、x2クロックである 50MHz も与えてたんだよなー。
その後間もなく、486DX2 などで速さチギられてくワケだが。
ところでここ、何のスレだっけww
0246デフォルトの名無しさん
2005/04/21(木) 16:33:360247デフォルトの名無しさん
2005/04/21(木) 16:38:010248243
2005/04/21(木) 17:17:5968kは、むしろアセンブラ使って、
手動で最適化した方が良かった、って話。
だっけ?
0249デフォルトの名無しさん
2005/04/21(木) 17:44:09測定ツールをオープンソースで作って、結果を持ちよってまとめたほうがよくないか?
0250241
2005/04/21(木) 18:37:02んだんだ、ある装置の開発部隊にいたんだけど、うちらはアセンブラで隣はCだった。
そのCコンパイラのできが当時だから仕方ないかもしれないけれどよくなくて、
アセンブラで普通に書くほうが速かったと言うお話。
そう言えばPalmOSが68Kなんだけど、これがMacOS同様無効命令例外でAPIを呼ぶ仕様。
Cのランタイムなんてないからstdio.hやstring.h系の関数がAPIで実装されていて、
呼び出しがなかなか遅くて笑えた。
それで思い出したのだけど、8086のintってDOSでは幅を利かせていたけど今でも使われている?
INT3だけはブレークポインタで使っているんだろうけど。
#この辺りに如何に遠ざかっているかがw
0251●
2005/04/21(木) 20:59:59計測用マクロ集はIntelが公開してるじゃん。
http://www.intel.com/cd/ids/developer/asmo-na/eng/microprocessors/ia32/pentium4/optimization/20243.htm?page=1
あとは各自VCTKかあたりでコンパイルして実行と。
gccでも-masm=intelでコンパイルすればよさげですが。
理想ケースだけ測るより組み合わせで地道に計測したほうがよさげ。
>>250
>そう言えばPalmOSが68Kなんだけど、これがMacOS同様無効命令例外でAPIを呼ぶ仕様。
Sunもでそ。RISC系は大体そんな感じじゃないでつか。
ぶっちゃけきょうびstring.hの関数がVCの最適化で内部命令に展開できるってのもどうでもいいような話だったり。
普通にMMX/SSEで自前で書いたほうが速いし。
>それで思い出したのだけど、8086のintってDOSでは幅を利かせていたけど今でも使われている?
割り込みであれこれやるより、OSがCPU時間を割り当てるんで、スレッド起こして
処理するのがナウい開発技法かと。
特に意識しなくても、複数プロセッサが乗ったマシンであれば、OSが勝手に
プロセッサ毎にスレッドを振り分けてくれたりするので。
ドライバとか組み込みレベルならともかく、アプリレベルで使うことはまず無いと認識してます。
そもそも割り込み系の命令ってNT上じゃ特権無いと使えないんじゃ・・・。
0252デフォルトの名無しさん
2005/04/21(木) 22:47:22すると当然、割り込み命令を使うと「特権違反例外」を発生するから、
システムコール用に使うことだって、できなくはない...と思う。
OSの例外処理の仕様とか、システムコールの仕様とかに依存。
■ このスレッドは過去ログ倉庫に格納されています