2ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

x86命令の所要クロック計測スレ

1 :デフォルトの名無しさん:04/12/21 15:08:57
PentiumMにて
addpdは4-2(レイテンシ-スループット)
imul 4-1

Pen4、Athlonなどデータを集めてみる

2 :デフォルトの名無しさん:04/12/21 15:10:08
      ∧∧    / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
     (,,  )  <  >>2ゲットしようと来てみれば
     .(  つ   |  こりゃまた とんだ駄スレだなぁ オイ
     | , |    \____________
     U U

 |  まあ せっかくだからやっといてやるよ   |
 \  ハイハイ 今だ>>2ゲットズザー っとくらぁ /
    ̄ ̄ ̄ ̄ ̄ ̄V ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

            ∧∧
           (゚Д゚O =3
      ⊆⊂´ ̄  ソ ヤレヤレ

ドッコイショ・・・・・・・・・
 ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄
     ∧∧          (´;;
    (゚Д゚ ,)⌒ヽ    (´⌒(´
     U‐U^(,,⊃'〜... (´⌒(´⌒;;

ハァ、ダルッ・・・帰るか
 ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄
  ポ  ∧∧  ポ
  ン  (゚Д゚ ,) . ン
   (´;) U,U )〜 (;;).
(´)〜(⌒;;UU (´ )...〜⌒(`)

3 :デフォルトの名無しさん:04/12/21 15:14:48
(・3・) エェー OS上で正確な測定が出来るのかYO

4 :69式フリーPG ◆hND3Lufios :04/12/21 17:37:18
そこでMS-DOSですよおとうさん

5 :デフォルトの名無しさん:04/12/21 19:52:21
http://appzone.intel.com/scripts-util/download.asp?url=/jp/developer/jpdoc/ia32.pdf&title=IA-32+命令のレイテンシとスループット&fullpg=3&site=jp

コレじゃダメ?

6 :デフォルトの名無しさん:04/12/21 23:24:02
PentiumMはまた他と異なるからじゃないかと

7 :デフォルトの名無しさん:04/12/22 00:46:13
それなら、>>1はそうとわかるように、スレタイと>>1の内容を書くべきだったね。

8 :1:04/12/22 11:10:47
>>3
できるよ。

>>5
Intelのマニュアルは持ってるが、Pen4しか詳しくない。
PenIIIも概略はのっているが、細かいクロックはない。
PenMのSSE2はみたことないし。

P4以外のSSEは、おそらく2μopで、それぞれのμopが並列実行されたりするから
内部構造を意識しないとクロックがわからない。
実行ユニットの数、レイテンシ、スループットをうまく求める必要がある。

9 :1:04/12/22 11:16:19
PentiumM
addsd 3-1(レイテンシ-スループット)
addpd 4-2(addsd2回に相当。連続して行うと実質4-1)
sqrtsd 57-57

10 :デフォルトの名無しさん:04/12/22 20:57:50
PentiumMのSSE2は糞っていうのをどこかで見たな。

計測プログラムを公開して、色んなCPUで実行してもらうのが、いいんじゃない?

11 :デフォルトの名無しさん:04/12/22 23:35:01
>>10
PenMのSSEはNetBurstより圧倒的にレイテンシもスループットも良いんだがな
乗算やシフトもIntel系の伝統を破っていて不思議と速い
実クロック以外に糞と呼ばれる要素あるんかいな?

12 :デフォルトの名無しさん:04/12/23 03:38:27
AMDのCPUにはこれ使え。
ttp://www.amd.com/jp-ja/Processors/DevelopWithAMD/0,,30_2252_869_3604,00.html
パイプラインのストールの様子も分かり、とても面白い。

13 :デフォルトの名無しさん:04/12/23 03:49:01
>>11
SSEじゃなくてSSE2

14 :デフォルトの名無しさん:04/12/24 15:17:48
ベストケースのレイテンシ・スループットはAMD, Intelともに
ドキュメントがある。しかし、それが何の役に立つというのだ?

ちうわけで>>12のようなシミュレータの出力を眺めつつ
あっち立てればこっち立たずの局所最適化に明け暮れることになるわけだ。

15 :デフォルトの名無しさん:04/12/25 02:38:46
スループットって何?

スループット1なら、最も条件が良い時に1クロックで実行できる。
スループット2なら、2クロックで実行できる。
ってことだと思っていたのだけど、間違ってる?

論理演算は、64ビットのMMXがスループット1で、128ビットのSSE2がスループット2だから、
どっちでやっても変らないや、と思っていたのだけど、実際にやってみると、SSE2のほうが速い。
もしかして、コーディングがヘタ糞で、ストールしまくってるのかな・・・。

16 :デフォルトの名無しさん:04/12/25 12:36:21
メモリアクセスのレイテンシはいっしょ
ロード&ストア回数が少ないほうが速くて当たり前

17 :15:04/12/25 20:58:07
メモリアクセスのレイテンシは隠蔽されないのですか・・・。

18 :14:04/12/26 01:38:12
>>15
PentiumM, AthlonのMMX ALUは、スループット1/2
依存関係のない2つの演算が同時に2個実行できる。
(Pentium4 は スループット1 のハズ)
たいていのSSE演算は、いずれのプロセッサもMMXを2つ束ねて
実行しているようなものなので、スループットは半分になる。

レイテンシに関しては、メモリアクセスのレイテンシは
ベストケースでL1キャッシュにヒットしたとき。
メモリアクセスのレイテンシは、他に実行しているロード/ストアに
引きずられたりするので、予測するのはけっこうメンド。

コアループをここに貼ってくれれば添削はできる。

19 :15:04/12/26 04:59:15
解説ありがとうございます。

せっかくの添削の話ですが、
アセンブラではなくCで書いてコンパイラにスケジューリングさせてるので辞退させてください。

20 :デフォルトの名無しさん:04/12/26 15:26:13
コンパイラは確かに優秀だが
仕様上どうしてもできないことがある
漢なら__declspec( naked )で書くんだ

21 :1:05/01/11 14:54:37
>addpd 4-2(addsd2回に相当。連続して行うと実質4-1)
>>9のこれは間違いだった。
3-1を2つで3-2が正解。
上位と下位で並列性が生まれ、少しレイテンシが減る。

今はVC++6のインラインアセンブラとnasmで計っているが、
分岐ミスのクロックからパイプラインの長さ計ろうとしても
いまいちはっきりせん。
14段ぐらい?

22 :デフォルトの名無しさん:05/01/11 20:42:10
そういや、VCは不思議な挙動をするね。

インラインアセンブラで書く → その前後でコンパイラの最適化が無効になる
intrinsicを使って書く & 組み込み関数のインライン展開OFF → intrinsicを含め、コンパイラが最適化してくれる
intrinsicを使って書く & 組み込み関数のインライン展開ON → その前後でコンパイラの最適化が無効になる

リリース・ビルドでは
組み込み関数のインライン展開ONよりもOFFのほうが速く、
デバッグ・ビルドでは
組み込み関数のインライン展開ONよりもOFFのほうが圧倒的に遅い


23 :1:05/01/12 12:29:22
VB高速化のため、VCの__asmで書きDLL化したのをVBから呼び出している漏れ。
21の言っていることがよくわからない。
悔しいのでキャッシュの仕組みでも書いてみる。
話がPIIIなのは昔考えたことだから。


キャッシュというのはアドレスを言われたらすぐそのデータを差し出さなければならない。
PentiumIIIのL1キャッシュでのこの時間はわずか3clk。
キャッシュのどこにどのアドレスのデータがあるかを把握していなければならないのは当然だが、
突然言われたアドレスのデータが16KBものデータの中からどこにあるのかを調べて
データを転送するまでたったの3clkで完了させるというのは、
データの配置に制限をかけて検索しやすいようにしなければできないことである。

そこでL1キャッシュは4ウェイ・セット・アソシエイティブ、キャッシュラインサイズ32byte、
キャッシュライン512本で容量が16KBのキャッシュになっている。
まずL1キャッシュは512個のキャッシュラインに分かれている。
16KB÷512個でそれぞれが32byte。

ここには必ず32byte境界にアライメントされた連続データが入る。
これが4個ずつ128グループになっている。
アドレス値の5〜11bitには、7bitあるので128通りがあるが、
各グループがその128通りに割り当てられる。
そのグループ内のキャッシュラインには必ず割り当ての7bitをアドレス値の5〜11bitに持つデータが入る。
すると、このアドレスのデータがほしいと言われたときに、アドレスの5〜11bitからグループを特定し、
その中4つのキャッシュラインについて一致するアドレスがないか調べればいいことになる。
これなら3clkでできそうだ。

24 :1:05/01/12 12:33:56
って22の間違いね。
>21の言っていることがよくわからない。

まあ、アセンブラのおかげで、Cが内部的に何をやっているのかは
けっこう理解しやすくなった。
22がそんな難しいことを言ってないというのはわかるが
アセンブラ使いのVB厨つうことで勘弁。

25 :デフォルトの名無しさん:05/01/12 13:27:20
>>24
インラインアセンブラを含む組み込み関数(intrinsic)をインライン展開すると
最適化が効かなくなる。
→普通は速くなるはずのインライン展開が、却って遅くなる原因になることもある。

ってことでしょ。

26 :デフォルトの名無しさん:05/01/12 13:47:06
EAX,EDX以外のレジスタを使うとちゃんと保存してくれてるんだよな
エライもんだ

27 :1:05/01/18 12:34:02
>>25
サンクス。こっちの指定が大域的な最適化を阻害するわけか。
そりゃそうだわな。コンパイラ作った人えらいなあ。

調べた(PentiumM)
命令 レイテンシ スループット

MOVDQA 1 1
MOVDQU 1 1
MOVD 1 1
MOVD 1 1
MOVDQ2Q 1 1
MOVQ2DQ 1 1
MOVQ 1 1
PADD(B/W/D) 1 1
PADD[U]S(B/W) 1 1
PADDQ 2 2
PADDQ 2 2
PMADDWD 4 2
PMUL(L/H/HU)W 4 2
PMULUDQ 5 2
PMULUDQ 4 1
P(AND/ANDN/OR/XOR) 1 1
PS(L/R)LDQ 3 3
PS(L/R)L(W/D/Q) 2 2
PSRA(W/D) 2 2
PCMP(EQ/GT)(B/G/W) 1 1
PACK(SSWB/SSDW/USWB) 2 2
PUNPCK(L/H)(BW/WD/DQ) 2 2
PUNPCK(L/H)QDQ 1 1

28 :1:05/01/18 12:35:52
続き

PAVG(B/W) 1 1
PSADBW 5 2
PEXTRW 4 2
PINSRW 2 2
P(MAX/MIN)(UB/SW) 1 1
PMOVMSKB 1 1
PSHUFD 2 2
PSHUF(L/H)W 1 1

29 :1:05/01/18 12:38:51
OV(A/U)PD 1 1
MOVSD 1 1
ADDPD 4 2
ADDSD 3 1
MULPD 7 4
MULSD 5 2
DIVPD 62 62
DIVSD 32 32
SQRTPD 114114
SQRTSD 57 57
ANDNPD 1 1
ANDPD 1 1
ORPD 1 1
XORPD 1 1
CMPPD 4 2
CMPSD 3 1
[U]COMISD 1 1
MAXPD 4 2
MAXSD 3 1
MOVMSKPD 1 1
SHUFPD 2 2
UNPCKHPD 3 2
UNPCKLPD 3 2

30 :1:05/01/18 12:39:42
CVTPD2DQ 4 2
CVTPD2PI 2 2
CVTSD2SI 4 1
CVTDQ2PD 4 2
CVTPI2PD 4 2
CVTSI2SD 4 1
CVTPD2PS 5 2
CVTSD2SS 4 1
CVTPS2PD 3 3
CVTSS2SD 2 2
PINSRW 2 2
P(MAX/MIN)(UB/SW) 1 1
PMOVMSKB 1 1
PSHUFD 2 2
PSHUF(L/H)W 1 1
CVTDQ2PS 4 2
CVTPS2DQ 4 2

以上。全部SSE2でした。

31 :1:05/01/18 12:43:46
実行ユニットがガラ空きだったときのベストケースのクロックです。
SSE2は2μopのようなので、MMX2命令(1μop*2)の方が
デコーダには優しい場合もあり。

32 :14:05/01/18 14:14:24
thx.
予想通りだな。ちなみにK8も似たような感じかな、
SSEはMMX×2なので。

かといってこんだけの情報でオプティマイザ作るのは至難の業
次はMMX命令の計測 pls. (たぶんP6系と共通だろうが)

33 :1:05/01/19 13:05:15
orz...
Excelでまとめたのをそのままコピペしたらあかんわな。連投&&間違い多くてスマソ。
2回書いてある命令がかなりあるが、無視してくれ。
pmuludqは、下はMMXレジスタが対象のときのクロック。

>>10
自分でも試行錯誤して計ってるからなあ。配布できるようなものを作る自信もないし、
アセンブラで叩いて肌で感じる、CPUごとのクセみたいのを知りたいなあ。

>>11
PMのSSE・SSE2は、P4と大分性格は違うもののIPCは同じ程度と予想している。
PMは整数・論理演算が得意で小回りがきく。
P4はメモリから高速転送して浮動少数点演算が得意。かな?
ていうかPMは実クロックこそが糞なのだと思われ。SSE2では(実性能で)P4に張り合えないでしょ。

>>12
それ激しく面白そうだが、何?

>>14
自分はマンデルブロ集合の描写速度で理論値に迫りたいと思ってこの道にはまった。
確かに、「楽しいから」「知りたいから」以外、役に立つということは少ないかもなあ。

>>18
その「スループット1/2」という表現だと、「レイテンシ1・スループット1/2の演算器が1個」だよね。
実際は「レイテンシ1・スループット1の演算器が2個」なので厳密には違うと思う。
(18の言わんとしていることは正しいと思うが表現が気になっただけ)

>>26
VCのインラインasmはホント親切だね。そういうことは大分後で知ったよ。
VB+VC__asmって一番ぬるま湯なアセンブラ環境やも知れぬ・・・。

34 :1:05/01/19 13:21:01
>>32
K8の情報激しくキボンヌ。
SSE命令を2つ同時デコードできるかとか、
SSEの単精度と倍精度の差とか。

ちなみにPentiumMの乗算だと、単精度2個で4-1、倍精度1個で5-2。
倍精度だと、拡張精度のFPUと同等で、あまり速くない。

MMXだとP6と一緒みたいです。
ただ、μopフュージョンのおかげでメモリ周りがP6より速い。
例えばmovq [edi],mm0という命令は普通だと
「ストアするアドレス[edi]の計算」と「データmm0をストアバッファへストア」
の2つのμopに分解される。これをくっつけたまま処理する。
すると、デコーダはこの命令を複数μopに分解しないで済む。
1つの命令を複数のμopに分解するのはデコーダにとって相当に大変らしく、
これでこの命令はデコードに際し1μop扱いとなる。
当然リオーダバッファも1エントリしか占有しない。
実行ユニットに送られるときに分離され、それぞれ処理される。
OoOなのでこの処理は同時でなくてもいい。
結果は元のリオーダバッファに戻され再び合体、両方の処理が終わった後で
命令はリタイヤされる。リタイヤも1μop扱いなので楽ちんだ。

特に、P6ではリタイヤがボトルネックとなり、最大でも
3μop/clk(デコーダは6μop/clk吐けるのに)だったので、
PMは「思い通りのスピードが出る」名石だと思う。

35 :14 ◆TimpoiKAMI :05/01/19 17:29:25
いつも使ってるコテトリップつけると、ストーカーヴァカがやってくるので(汗

>>34
SSEのデコードが、K7/K8でもっとも違うところですね。
K7(Palomino)では、動けばいいやって感じの VectorPathだけど
K8では、SSEはDouble pathといって、Decoderを2つ同時に駆動するような
感じになるのね。だから、Double path命令は、2命令同時発行はできないけど
Double path+DirectPath は可能(なハズ)。

文章では、AMDサイトに Optimization guide(英文)があがってるので、参照されたし。

uops fusionに関しては、K7の頃から似たような感じの実装があった。
issue stageまでは一緒にスケジュールされる。

Retirement が3ってのがいちばんボトルネックになりうるというのを知って
愕然とした、俺であった。合掌。

36 :デフォルトの名無しさん:05/01/20 18:44:14
>>33

>>12で紹介されてるのはAMDのフリーウェアで、
ターゲットの実行ファイルに対して、
CPUのパフォーマンスカウンタの値を表示したり、
CPUシミュレータによってパイプラインの状況を1命令ずつ表示したりできる。

37 :デフォルトの名無しさん:05/01/24 23:35:22
>>35
DoublePathでも論理演算とかはFADD、FMULに並列に送ることが
可能じゃないの? 最適化マニュアルをみるとThroughputは1になっているし。

38 :14 ◆TimpoiKAMI :05/01/25 00:21:33
>>37
Yes, FADD, FMUL で同時に喰うから、スループット1だね。
Load も、たいていの場合だと 64bit x2 がイケるし…

Store は、64bit x1 なんだな、これがネックになりうる。

39 :1:05/01/25 10:07:59
>>35
>uops fusionに関しては、K7の頃から似たような感じの実装があった。
P6対K7でK7優勢だったのはこのおかげだろう。
確か、「メモリ読み書きとALUのセット」が3つあるんだよね。速すぎ(^^;
その上FPUが強力だし、よくP6で張り合えたものだ。P6がよかったのはL2キャッシュの性能?

>Retirement が3ってのが
デコーダも実行ユニットもしっかり考えて作るのになぜかIPCの壁があって、意味不明だった。
マニュアル読んでコレダ!と思ったよ。なぜか他所では見たことないが。
あのマニュアルはIntelに不利な点を隠すように書いてあるから、読みづらいったらない。

>Optimization guide
お、いいなこれ。ありがと。英語は読むのに時間がかかりすぎだが・・・。
もっとも、Intelの直訳マニュアルも意味不明だった。

>>32かといってこんだけの情報でオプティマイザ作るのは至難の業
手動で最適化できる知識を身に付けたいというのは大きな動機だったなあ。
しかしオプティマイザ作るってのはやり方の見当もつかん。
前も書いたが最適化の効いたコンパイラ作る人えらい。

>>36
サンクスコ・・・。やってみたが、StartSimulationを押すと即落ちる(XPで青い画面初めて見た)。
AMDのCPUじゃないとできないとか?APICがないとか出るがそれか?
ヴ〜パイプラインの様子見てえぞゴルァ!!

40 :1:05/01/25 10:11:54
>>10
>PentiumMのSSE2は糞っていうのをどこかで見たな。
遅レスだが、これはまるも製作所のことではないだろうか(戯言の04年11月9、11日参照)。
MMXをSSE2にしたら、PMは遅くなりP4は速くなったという話。
この人が使っている「psadbw」という命令が最悪(SSE2化で使い勝手が悪化した命令の1つ)。
P4ではSSE2で高速化しているが、PMの倍の帯域を持つL1キャッシュの力を引き出したのと、
糞性能(PM/P6の半分程度)のMMXを使わなくなった効果だろう。
psadbwを使う状況では、PMは素直にMMX版でいくしかないと思われ。
>>11の言い分は「P4よりPMが速い」なので正しい。ただ、キャッシュのスループットは例外。
MMXよりSSE2が遅くなるのはPMでもレアケースのはずだが、不満の声を聞くのが
動画処理(SIMD系命令本来の用途)をしている人からなのが意外だった。

>>37>>38あたりはOptimization guideよく読んで考えよっと。

ついでに。
このスレの主眼となるクロック計測だが、「addpdが4-2」で終わりじゃない。
「addpdは2μopに分解され、クロックは両方3-1で、実行できるユニットは1個」まで調べる。


41 :14 ◆TimpoiKAMI :05/01/25 10:30:37
>>39
> その上FPUが強力だし、よくP6で張り合えたものだ。P6がよかったのはL2キャッシュの性能?

初代K7と河童の最大の違いだね、L2は。低レイテンシ高スループットのL2は、
正直うらやましかった。今でもL1, L2とも、K7はP6系よりレイテンシ高い。

> サンクスコ・・・。やってみたが、StartSimulationを押すと即落ちる(XPで青い画面初めて見た)。

AMDコードアナルはAMD専用っぽいっす。プロファイリング用のドライバが
AMD-Specific Registersいじってるんだと思う。
俺に必要だったりするのはパイプラインシムだけだったりするんだがな。
あとのプロファイリングは RDTSC で事足りてるし。

俺のメインマシンである Crusoe ノートに入れたらやっぱり市んだので。

42 :1:05/01/25 11:47:41
>>41
即レスありがと。K7のレイテンシってどのくらいなの?
調べたが、P4とかはよくCPU-Zのが晒されてるんだがAMDは見かけない。
そもそもP6のL2バスが256bitのハーフスピードで4byte/clkのスループット
というのからして理屈がわからないのだが。

>AMDコードアナルはAMD専用っぽいっす。
残念。まあ仕方ないか(夢のようなソフトなんだが)。

さて。
クロック測定には、内部構造の知識も必要なので書いておく。
CPUの速さを決めるのは、キャッシュ性能・命令のフェッチ・デコーダ・命令の所要クロック・
実行ユニットの数・分岐予測・パイプラインの段数・OoO性能・リタイヤユニット・・・など。
PentiumMでは具体的にどうなっているかを解説する。

43 :1:05/01/25 11:48:47
キャッシュは、L1がデータ32KB,命令32KB、L2が2MB。巨大です。
L1がレイテンシ3、スループット8byte/clk。L2はレイテンシ10、4byte/clk?
速さについては>>23も参照。詳しいデータが欲しい。Intelはキャッシュが強い印象がある。

命令のフェッチ(L1命令キャッシュから読む)。何か16byteごとに持ってくるらしい。
なので16byte境界をまたがないように命令を置くといい。

デコーダ。3個ある。その内、複数μopの命令をデコードできるのは1個だけ。
つまり4μop、1μop、1μopと来たクロックには6μopも吐けるが、
2μop、2μopと来たらクロック当たり2μopしか吐けない。
よって1μopでない命令は連続しないように配置するとよい。
ここでμopフュージョンが効く。メモリへ書く・メモリから足すなどが1μopとなった。

命令の所要クロック。このスレの住人様(俺かよ)お願いしまつ。レイテンシをうまく隠蔽しよう。

実行ユニットの数。5個ある。0〜4の番号を付けると、
0はALU(整数・論理)・移動・浮動小数点乗算。1はALU・浮動少数点加算・移動。
2はメモリから読む。3はメモリへ書くアドレス計算。4はメモリへ書くデータをバッファに入れる。
メモリは読むより書く方が手間なんですね。処理を違うユニットに分散させれば最大5μop/clk。
ここでのμopは、フュージョンしたのを分離したμop。

分岐予測。今のCPUはパイプラインが深い。作業を細分化して流れ作業なわけです。
その作業の最初が命令のフェッチで、分岐はそのフェッチする場所を変える命令なので
早い内に変えることを予測して作業しないと効率悪すぎです。
今までのパターンから予測する他、ループ検出器なんかも付いていて強力らしい。
当然パイプラインの段数は少ない方が良い(クロックは上げにくくなるが)。

44 :1:05/01/25 11:51:39
OoO。アウト・オブ・オーダーの略。
レイテンシが長い命令の結果待ちμopなどがあったら、先に別の命令を処理しちゃおうという機能。
デコードが終わった段階で、μopたちはリオーダバッファとかいうのに格納される。
この中から今すぐ実行できる命令を選んで実行ユニットにガンガン送り出す。
バッファの数や送り出しの決め方なんかが性能を左右するのか?

リタイヤユニット。リオーダバッファから実行済みの命令を見つけて、
「順番通りに」結果をレジスタやメモリに書き込み、消していく。
最大3μop/clkでリタイヤさせることができる。


ってここに来る人はこんなのわかってるか・・・。
でも昔の俺はこういうのを猛烈に知りたかったのよ。

45 :14 ◆TimpoiKAMI :05/01/25 12:09:14
>>44
俺もマイクロアーキテクチャを真剣に調べるよーになったのは
ここ1年くらいのことなんで、マターリ逝こうや。お互いにな。

46 :デフォルトの名無しさん:05/01/25 13:55:31
>>44
PenMのレイテンシ/スループットは英語版の最適化マニュアルおとせば
主要なのは載ってるよ。

47 :デフォルトの名無しさん:05/01/25 14:18:47
>42
ここにP4とK7のロードレイテンシの比較が。
ttp://www.geocities.co.jp/SiliconValley-Oakland/8071/index.html

48 :14 ◆TimpoiKAMI :05/01/25 14:31:38
>>47
横槍失礼。見てみました。
データシート記載のものとほぼ同じ数字のようですね。

プレスコは…(ry

49 :デフォルトの名無しさん:05/01/25 15:34:50
>>46
x86がほとんど載っていない。

50 :デフォルトの名無しさん:05/01/25 17:37:33
>>49
しかし、>>1が欲しいのは>>27以降の書き込みをみるかぎりx86/x87ではなくて
SIMD系のデータらしいが…。
Pen4に関してはもっと詳細なソースもあるが、ここでは秘密にしておく。

51 :14 ◆TimpoiKAMI :05/01/25 18:12:43
まぁP6以降スーパースケーラx86石専用スレつーことでヨロ

52 :デフォルトの名無しさん:05/01/25 19:09:54
[x86]CPUアーキテクチャについて語れ![RISC]
http://makimo.to/2ch/pc5_jisaku/1082/1082357989.html#155

こんな説明の仕方もあるのかw



53 :1:05/01/26 10:49:37
>>45
俺走りすぎてる?(^^;
まあ、たまにしか来られないのでこのぐらいやらないと。
・・・と思ったら、俺のレスの割合多いな。orz

>>46
そうか。以前探して、無かったので、PMは無いという先入観ができていたようだ。サンクス。

>>47
これはイイ!しかしP4のL1はすごい。そういうのに特化した設計だから当然と言えばそうだが。
Prescottはキャッシュレイテンシが増えても、実際の性能がそこそこ出るのはなぜだ?
キャッシュ容量は増えてるが、内部的にも改善のある希ガス。

>>49>>50
俺は全て知りたいが、古いマニュアルに載っていなくて未知数だったSSE2を特に知りたかっただけ。
整数命令は使った経験が多いので、比較的挙動がわかる。
IntelのFPUは加算3-1、乗算5-2でPPro〜PenMまで変化ないと思うが、
加算と乗算の並列実行やfxchのコストなど、詳しい資料があれば是非見たい。
並列実行はPMになった時点で有効になったと見たがどうか?

つうか秘密にされると知りたくなる罠。

>>51
ま、そうだね。俺がアセンブラ始めたのが河童-128k。Celeronにしては、いい石だった。
VBを始めたのはPenIIで、BASIC始めたのはポケコンだった。
ポケコンで機械語できなかた雪辱をやっと(w

>>52
俺もたまに実生活でパイプラインが浮かぶ。スーパースカラの方が多いが。
両手で作業してるとき、右手と左手をUパイプとVパイプに見立ててP5ごっことか。

54 :デフォルトの名無しさん:05/01/27 02:01:29
勉強になります!

55 :デフォルトの名無しさん:05/01/27 13:37:35
両手で作業してるとき、右手と左手をUパイプとVパイプに見立ててP5ごっことか。
両手で作業してるとき、右手と左手をUパイプとVパイプに見立ててP5ごっことか。
両手で作業してるとき、右手と左手をUパイプとVパイプに見立ててP5ごっことか。

56 :デフォルトの名無しさん:05/01/27 19:35:38
>>55
>>1はかなりCPUに頭を侵されている。重傷だとおもったw

57 :デフォルトの名無しさん:05/01/27 20:28:17
可愛そうに・・・「させられ体験」をしているなんて、間違いなく統合失調症だな。

58 :1:05/02/01 14:29:56
>>54
わかった点や疑問点なんかも書くと更に嬉しいぞ。

>>56
頑張ってアセンブラの勉強をしていた頃は、かなりの事象がCPUの動きに見えてたなあ・・・。

>>57
マジレスでスマソ(スレタイからも脱線だが)。
人間は相対的に物事を捉える、言葉で物事を考える、とすれば、
CPUの仕事と自分の仕事の類似点があったら、アセンブラの経験を生かした捉え方ができる。
誰でも、P5のUVパイプの比喩でなくとも、もっと一般的な何かにたとえて捉えているにすぎない。

俺はコンビニのレジをやったことがあるのだが、おつりを取るときに、
距離の関係で、1円玉は右手で取れない、500円玉は左手で取れない(取れなくはないがw)。
つまり、片方のパイプでしか実行できない命令がある。

また、10円玉4枚を取るときのこと。
10円を入れる所が1個しかないので、2枚/clkの手を2本持っていても2clkかかってしまう。
依存関係はないが、実行ユニットの競合が起こってしまう。
8byte/clkのキャッシュでも、mov eax,[esi]/mov edx,[esi+4] には2clkかかるような感じ。

店員が2人で1つのレジをやっているとき。
確かに1人でやるよりは速いが、小額の客ばかりだとあまり変わらないことも多い。
客:タスク、客に対する様々な作業:スレッド、店員:CPU、
レジの個数:ソフトの仕様、お金の授受:外部記憶のアクセス。
1人の客に対して複数のスレッドがある時間は短いため、デュアルCPUを生かせない。
素直にレジ2つ使えば(ソフトをデュアルCPU向けに最適化すれば)速くなる。
ただ、このソフトをシングルCPUで実行すると、レジを行ったり来たりのオーバーヘッドがある。
だが、お金を出すのが遅い客ばかりだと、このソフトの方がいい場合もありうる。
(本当にやったら客に失礼すぎ)
店員がHT対応(2つのレジに手や目を分散できる変態。頭いいのが前提)だったら問題ないが。

59 :デフォルトの名無しさん:05/02/02 01:17:09
>>58
やっぱり、病気ですから。
もっと抽象的な捉え方するなら兎も角、特定のCPUのアーキテクチャと捉える辺りがもうね。

60 :デフォルトの名無しさん:05/02/02 01:47:44
その程度だったら精神科いけば直るよ

61 :1:05/02/02 11:37:34
あすろんについて。
K8でxmmレジスタに対するpandとandpdのクロックが違うのはなぜ?同じ動作なのに。
DoublePathなのは1.5命令/clkと書いてあったが、1個のデコーダで2clkてことかな。
P6のデコーダの1つは1clkに最大4μopを吐くが、
K7/K8は、それよりは少し弱いデコーダが3つあるということか。
2μopの命令が連続するとP6は弱い。μop自体K7の方が大きいし。

つーかロードが2命令/clk出せるのがうらやましい。
確かにPenMと同等かより上の高性能だが、Intelのとは
内部構造が別物だね。

Crusoeの叩き心地とかも知りたいが・・・。

62 :14 ◆TimpoiKAMI :05/02/02 11:59:42
>>61
>K8でxmmレジスタに対するpandとandpdのクロックが違うのはなぜ?同じ動作なのに。
>DoublePathなのは1.5命令/clkと書いてあったが、1個のデコーダで2clkてことかな。
フシギだねぇ。似たような動作なのに。
どちらもデコーダは DoublePath だから、実質的にデコードは1命令/clk
その後、PAND類は、FADD/FMULへissueされるが、
ANDPDはFMULへのissueのみなので、その分スループットもレイテンシも
大きい、そういう理解でいよう。

>P6のデコーダの1つは1clkに最大4μopを吐くが、
>K7/K8は、それよりは少し弱いデコーダが3つあるということか。
スケジューラに叩き込まれるまでに macroop になるようだね。
marcoop は、1〜2uopで構成されてると推測。

>つーかロードが2命令/clk出せるのがうらやましい。
けっこーこれができない条件があって、シミュレータでも実機でも
ストールを見ることができるよ。だからこそ、Load が 64x2 連続で
逝けまくってるときって楽しくてしょうがない。実際にはLoadするばかりでなく
Store(こちらは64x1)も混在するから、このときにいろいろ引っかかりが出てくる。

>Crusoeの叩き心地とかも知りたいが・・・。
俺は現役の Libretto L2使い。ほい。
Crusoe Exposed: Reverse Engineering the Transmeta TM5xxx Architecture
http://www.realworldtech.com/page.cfm?ArticleID=RWT010204000000
http://www.realworldtech.com/page.cfm?ArticleID=RWT012704012616

63 :1:05/02/02 13:28:42
>>62
andpdもALU使えよ・・・てのは素人考えなのだが。

しかし手元にないCPUを調べるのは、ある意味むなしいな。確認ができん。
1kHzくらいでいいからエミュレータ欲しい。

64 :デフォルトの名無しさん:05/02/03 14:57:15
age

65 :デフォルトの名無しさん:05/02/06 13:57:30
整数用のALUとSIMD用のALUって、別に存在して、同時に動くの?

なんか、SIMDの計算の間に、整数用の命令を挟んでも所要時間がほとんど変化しないよ。

66 :デフォルトの名無しさん:05/02/07 14:07:37
あーおもしれー

67 :1:05/02/08 09:37:06
>>62
Athlonでの>>65を考えて気づいたが、AthlonではMMXすらFPU側なのだね。
andpdはFADDを使いたいときに有効かなあ。
これは(AGU+ALU)*3とFADDとFMULが同時に稼動できるの?
DirectPath Singleのでかい命令をガンガン入てけばとんでもない性能になるな・・・。

>>65
Athlonは上述の通り、別にありそうな気がする。
PMだと、共通に使うALU(64bit以下の論理演算を1clkに1回できる)が2個あるだけに見える。
正確には、別にあるけどポートが競合して同時には稼動しない。
たくさんある実行ユニットは、パイプラインを共有しているものがあり(整数ALUとMMXALUとか)、
競合すると同時には実行できないのだ。
使用CPUとそのコードを晒してくれれば何が起こっているか分析したい。

あと、同じレジスタに続けて書き込むと2clkストールするとPIIIのマニュアルに書いてあった。
そのストールの間に整数命令を実行できたとか?(レジスタリネーミングで回避できないんかな)
PIIIはandpsが2-2だったんだよね。片方のALUしか使ってないかも。
P4も片方かな。P4はどんなμopに分解してるのかわからん。P4使いいないか。

pand xmm0,xmm0を8個の後dec ecx/jnz。これをPenMで9clk/loop。
1ループあたりALU(2個ある)行きのμopが18個なので9clk。
ALUの数で理論値を出しているので、ここでは整数命令を入れると必ず遅くなる。
理論値は出せたものの、結構シビア。使用レジスタによってコロコロ変わる。
xmm0,xmm0 xmm1,xmm1 xmm2,xmm2・・・とすると11clk/loop。意味不明。
ここで3と4の間にand eax,ebxをはさむと12clk、nopをはさむと10.66clk。誰か説明ぷりーず。。

68 :paddusb:05/02/08 09:39:30
このあいだ、僕のかよってるCPU行ったんです。PentiumIII。
そしたらなんか命令がめちゃくちゃいっぱいで入れないんです。
で、よく見たらなんか別スレッドが来てて、エンコード中、とか書いてあるんです。
もうね、アホかと。馬鹿かと。
お前らな、新作アニメ如きで普段やってないエンコしてんじゃねーよ、ボケが。
まほらばだよ、まほらば。
なんかでかい命令とかもいるし。1命令4μopでCPUか。おめでてーな。
よーし複雑命令デコーダ使っちゃうぞー、とか言ってるの。もう見てらんない。
お前らな、実行ユニットやるからデコーダ使わせろと。
CPUってのはな、もっと殺伐としてるべきなんだよ。
リオーダバッファに入った奴同士、いつ実行ユニットが競合してもおかしくない、
足すか足されるか、そんな雰囲気がいいんじゃねーか。マクロ命令は、すっこんでろ。
で、やっと入れたかと思ったら、隣の奴が、ロード・ストア同時で、とか言ってるんです。
そこでまたぶち切れですよ。
あのな、キャッシュバンクずらして使うなんてきょうび流行んねーんだよ。ボケが。
得意げな顔して何が、ロード・ストア同時で、だ。
お前は本当にそのμopリタイヤできるのかと問いたい。問い詰めたい。小1時間問い詰めたい。
お前、同時にできるぞって言いたいだけちゃうんかと。
PenIII住まいの僕から言わせてもらえば今、僕らの間での最新流行はやっぱり、
MMX、これだね。
MMXとMMX2。これが通の最適化。
MMXってのはレジスタが長めになってる。そん代わり小回りが効かない。これ。
で、それにMMX2(SSE整数命令)。これ最強。
しかしこれを実行すると次にFPUを使うとき切り替えが必要という危険も伴う、諸刃の剣。
素人にはお薦め出来ない。
まあお前、ビデオエンコードは、Pentium4でも使ってなさいってこった。

69 :デフォルトの名無しさん:05/02/08 10:41:31
>>67
たとえば
http://sourceforge.net/projects/md5crk/
など。

x86の論理演算とMMXの論理演算またはSSE2の論理演算を混ぜてる。

70 :1:05/02/08 11:08:57
>>69
コードはどこ?


71 :69:05/02/08 12:11:50
>>70
CVS

CVS知らなかったら、とりあえず
http://cvs.sourceforge.net/viewcvs.py/md5crk/
から覗いてみて。

72 :1:05/02/09 12:09:19
すまん。全然わからん。orz
できればここにコードを貼ってほすぃ・・・

73 :1:05/02/09 12:13:41
別の話題でも。

色々調べて思ったのは、同時にμopを発行できる実行ユニットの数を増やすのは大変だということ。
Athlonの、マクロ命令の段階でスケジュールして振り分けてしまうのは、今更ながら感心。
(スケジュールを2段構えにして負荷を軽減)
デュアルコアよりも、実行ユニットを倍に増やしたHTの方がいいじゃん、とか思ってたが
これはOoO周辺を作るのがすごく大変なのだろう。
lp:
addps xmm0,[esi]
addps xmm1,[esi+16]
addps xmm2,[esi+32]
addps xmm3,[esi+48]
add esi,64
dec ecx
jnz lp
これはPMで11clk/loopなのだが、mulps xmm1,[esi+16] を追加挿入すると10clkになる。
まあ、addを全部mulに置換すると理論値の8clk/loopを叩き出すわけだが。
add系が不思議に遅い。

74 :デフォルトの名無しさん:05/02/09 12:22:08
>>1
漏れは>71じゃないが、そのURIにディレクトリ構造がそのまま見えているのだが。
coresをクリックしてみるくらいできないわけじゃなかろうに。

75 :1:05/02/09 12:50:28
>>74スマソ。
ディレクトリが見えてるのはわかってたが、
適当にクリックしても何も出てこなかったのだ。

今やって、できますた。ありがd
信じられないだろうが、>>73の前に30分ほど試行錯誤してできなかった。

ちょっと見た感じ、SSE2整数と32bitALUを混ぜると
デコーダ的にも悪くないし、
レイテンシの隠蔽にもなるのでイイと思う。
理想状態でALUが余ってなくても現実はストール多いので、
色々な命令を混ぜると速くなるだろう。ソフトパイプラインだね。

76 :デフォルトの名無しさん:05/02/09 17:19:23
>>73
糞ですねw

77 :デフォルトの名無しさん:05/02/09 23:39:03
SSE2だけの演算でも、
MD5みたいに同じレジスタに頻繁にアクセスするものは、
複数まぜることでレジスタストールのペナルティを逃れて性能がアップする。

78 :デフォルトの名無しさん:05/02/10 02:09:30
普段はそれをやろうとしてもレジスタが足りなくなるな。
うまくいくと気持ちいい。

79 :14 ◆TimpoiKAMI :05/02/10 02:34:34
俺がやってる分野は、L/Sネックなんだよなー
だから、AMD64でやったら明らかに効率が上がった。

80 :デフォルトの名無しさん:05/02/10 06:11:22
>>78
レジスタ足りなくなってロードストアしても、それでも速かったりするんですよ。
ロードストアが空いてれば同時に実行できちゃうから。

81 :1:05/02/15 11:25:55
>ロードストア
メモリは遅いというイメージが離れないんだよなあ。
整数で汎用レジスタが足りないときはmovdでMMXに退避させたりしたことがあるw
確かにmovはALU食うからロードストアが空いてたらそっちがいいんだよな。

しかしSSE/2の最適化を詰めていくとPM弱いな。
小回りはK8以上だと思うが、メモリ帯域や重い乗算平方根に対して力なし。
AMDの√×÷は神の領域だが、P4にすら負ける細腕PM・・・。


分岐をちょっとやってみた(いつものようにPentiumM)。

ループの中にif〜then〜elseみたいな構造を作り、
条件分岐で分岐してもしなくても3clk/loopのコードを用意した。
0〜7fffhのランダムな整数が閾値以上かどうかで分岐する/しないを決める。

ここで閾値を0や8000hにすると3clk/loop。
4000h(分岐は完全にランダム)にすると12.5clk/loop程度になった。
単純に予測ミスのペナルティを出すと、2回に1回の予測ミスで9.5clkの差なので、
なんと19clkもの損をしていることになる。
これがパイプラインの段数なのかはわからないが、思っていたよりかなり大きい。
短いループなので予測ミスの他、ループ処理にも影響があるだろう。

分岐(する/しない)を交互に繰り返すパターンを食わせると4.5clk。
予測はすべて的中していると思われるが、やはりパイプラインが乱れるのだろうか。
最近のCPUらしく分岐予測ミスは痛いようだ。
(ループなど、完全に予測できる分岐に関してはP6に比べて速くなっている)

82 :デフォルトの名無しさん:05/02/15 13:03:58
そんな短い処理だと分岐が確定する前に次の分岐が何個も来てしまう
同じ位置の分岐をパイプラインの中に何個も貯めこんで履歴テーブルは大丈夫なのか

83 :1:05/02/15 13:16:55
確かに、パイプラインの中に分岐命令が多数流れている。
分岐を含めて6命令を3clkでやっているのはすごい。

20clk/loopくらいのでやり直してみるわ。

84 :1:05/02/15 13:58:28
初心者のためのアセンブラリンク。
http://www.fides.dti.ne.jp/~tokai/vc/mmxab2.html
Cがわかっていれば、この辺をコピペして動かしてみる。
http://ray.sakura.ne.jp/asm/
基本的な整数命令を覚える。
http://homepage1.nifty.com/herumi/adv.html
FPUやSSEなど。最適化の色々な話がある(つーか分岐の話はここにあったな)。

85 :14 ◆TimpoiKAMI :05/02/15 19:14:59
久々のカキコでしかも亀レス。

>>63
AMD64だったら、MMX論理演算も整数ALU使えyp とか思ってみたり。
ていうか、128ビット演算のSSE2はあまり速くないし(MMXのおよそ半分)
64ビット演算のMMXはレジスタ本数少なくって虐げられてるし、
64ビット演算の整数ALUは…ANDNがない(ワラ

>>65
・デコード条件制約
・発行条件制約
・じつはヘンなトコでストール
だったりする可能性があるので、シムでプロファイル取ってみれ。

>>67
>DirectPath Singleのでかい命令をガンガン入てけばとんでもない性能になるな・・・。
俺が測ったときは、DoublePathはデコーダをふたつ占有してますた。

>>81
俺が言うところのL/Sってのは、実行ユニットとキャッシュのインタフェイスね。
通常用途だとAMDでもBaniasでもキレイに働いてくれるんだけど、
カリカリにチューンし出すと、L/Sが真っ先に参ってる希ガス。

分岐は詳しくないのでパス。ただ、二重ループの内側を
CMOV にしたら、ちょっと速くなった。

86 :1:05/02/16 10:46:32
>>85
そうか、Athlon64はその名の通り整数レジスタが64bitあるんだ。
初め32bitの書き間違いかと思ったよ。整数とSSEが16本ずつとは・・・、
非64bitで使っていたら、MMXを使わないMMXPentiumぐらいもったいないぞ!
・・・MMXはandnがあるけどnotがないんだよねえ。

ところでDoublePathは一般的な言葉?
検索しても日本語ではこのスレぐらいしかかからない(w
(今やってみたらなぜかここもかかんなくなってた)

長いコードにしてやってみた。
結果は分岐の向き固定で22clk/loop、ランダムで26clk。
いや、たった8clkのペナルティで済むわけないんですが・・・。
交互にしたときも22clk/loop。

よく考えたら>>81の短いコードだと、予測失敗のときに、多数の予測分岐が破棄される。
でもパイプラインの段数分損するの自体は変わらないと思う。
パイプラインが10段程度というのはありえないのだが・・・。

87 :デフォルトの名無しさん:05/02/16 12:45:04
>>86
ランダムのつもりでも実はパターンを読まれていた

88 :1:05/02/16 13:07:30
>>87
質がよくないとは聞いていたが、
C標準のrand関数はそこまで性能が悪かったのかw

でも最近の分岐予測って精度はいいんだけど人間には全然予測できないなー。

89 :デフォルトの名無しさん:05/02/16 17:28:35
>>88
良い乱数と言えばMT

90 :デフォルトの名無しさん:05/02/16 18:41:54
>>86
関数呼び出しの時にパイプラインが破棄されてたって案はダメでつか?

randって関数でそ。無条件分岐とリターン(これも分岐)があるはず。

マクロ版randってのもあるんだっけ。
どういうコードだろ?

91 :デフォルトの名無しさん:05/02/16 19:13:30
>>90
randは乗算一個なんで・・・


92 :デフォルトの名無しさん:05/02/16 22:27:07
>>91
MT ってそんなに簡単だったんだ!!

93 :デフォルトの名無しさん:05/02/16 23:37:01
結局乱数テーブルの質じゃないの?

94 :デフォルトの名無しさん:05/02/16 23:37:15
randは線形合同だから

95 :デフォルトの名無しさん:05/02/17 03:27:39
VC6のCランタイムのソースを見ると、
return ((x = x * a + b) >>16) & 0x7fff ;
と書いてあるね。aとbは定数ね。


96 :14 ◆TimpoiKAMI :05/02/17 08:56:06
いまどき線形合同法で実用に耐える乱数列が得られると思ってる香具師ぁいねえよな?
これ以上は擦れ違いなので別擦れに誘導してくれ。

97 :たぶん 14 ◇TimpoiKAMI のストーカー:05/02/17 16:58:47
同じくスレ違いだが、MT使っても安直にstd::time()関数をseedに使ってる香具師も
問題だとか言ってみる。
ソフトの起動時刻が大体わかれば擬似乱数系列のクラックも可能になります。
もち定数なぞ問題外。
seedの値だけど、私はWin32APIでいくと、timeGetTime()か、QueryPerformanceCounter()
の下位DWORDあたりを使ひますね。あといろいろ組み合わせてみたり。
これだけで解析はだいぶ困難になります。
つか、ほんの数回呼び出す程度ならstd::rand()でも十分実用範囲。

>>86
> 非64bitで使っていたら、MMXを使わないMMXPentiumぐらいもったいないぞ!

レジスタ論理数の制約のあるx86のコード体系自体がもったねーす。
MSの圧力でAMD互換になる前のIntelの64bit拡張がPentium 4の128本ある物理GRを
ある程度自由に使える仕様だったとしたら(妄想)、かなり遊び倒せた希ガス。
(しかしPrescottの実物がアレじゃいくら命令セットがよくてもどうしようもない気もした)

あと、MMX/SSE*にpnorやpxnorが欲しいと思うの漏れだけか脳?
同じモノ作っててもPPCのAltiVecだとNOR命令があるのでずいぶん書きやすく感じる。
それ以前に3オペランド命令主体でレジスタ32本あるのがかなり大きいと思うけど。

わたしわHacker's Delight厨なので、速度云々じゃなくFP_MUL使ったら負けかなと
思っている。
PenMの性能で困ったことがないのは整数演算主体だからだろうな。

98 :14 ◆TimpoiKAMI :05/02/17 18:43:06
>>97
スレ違いカキコ&未知との遭遇を記念して、
ultimotrip@hotmail.com
を、私のMSN Messengerメンバリストに追加いたしました。

以降、マタリ進行お願いします。

99 :97:05/02/17 22:12:42
話題を戻す方向で。

>>81亀レスになるのだけど

> (ループなど、完全に予測できる分岐に関してはP6に比べて速くなっている)
これはこいつの効果やね。
ttp://www.intel.co.jp/jp/developer/technology/itj/2003/volume07issue02/art03_pentiumm/p05_branch.htm


> でもパイプラインの段数分損するの自体は変わらないと思う。
> パイプラインが10段程度というのはありえないのだが・・・。

うちもこのへんの仕組みは全然詳しくないのですが、たとえば、分岐命令の条件となるフラグ値を
早めに確定させるように命令を再スケジューリングし、フラグが確定し予測ミスが判明した時点で
投機した命令のステージだけを破棄し、パイプラインの全ステージを破棄しなくてすむような
機構にしてるってことは有り得る?
これだとストールのクロックサイクル数はパイプラインの段数より確実に短くなる。

Pentium Mのパイプラインはかなり謎が多ひ

100 : ◆DDDDDDDDao :05/02/17 23:06:22




    ???(゚∀゚)???

101 :97:05/02/17 23:40:38
で、とりあえず「乱数系列を完全に読まれてる」説について勝手に検証

VC++の疑似乱数の範囲は0〜32767で
乱数値が >= 0x4000 のときとそうでないときで分岐してるのでしたよね
ようはこいつと一緒なわけでしょ。

   std::rand() & 0x4000 != 0

rand()のおもっきし古典的な実装だと、下位ビットの出現が規則性を持ってしまう、たとえば0と1が交互に出現する
ってことは有り得たらしいのだけど、実際有効なのは乱数の有効桁の最上位1ビットだけなのでどっちにしろ関係無し。

で、うちもためしに乱数の最上位1ビットだけ1000回くらい出力してみたけど、規則性は見られなかった。
たぶん乱数系列自体と同じ周期になりそーな気がします。
いくらなんでもPenMの分岐予測機構が全部これを先読みしてるってことはあり得んでそ。


詳しいことはこのへんにのっとるようです
http://www001.upp.so-net.ne.jp/isaku/rand.html

102 :デフォルトの名無しさん:05/02/18 00:51:27
投機実行で上手く先読みされているのかもしれんな
乱数を実数演算で作って書き込んだメモリの特定ビットを参照させたらどうかな

103 :90:05/02/18 04:34:34
測定前に、あらかじめ、乱数値を一通り求めてテーブル化しておいて、

測定中は、テーブルから乱数を読むだけにした方がよくない?

104 :デフォルトの名無しさん:05/02/18 12:22:59
そうするとキャッシュヒットしないメモリアクセスが
入ることになるから、命令実行時間の計測には向かん
のじゃない?

105 :デフォルトの名無しさん:05/02/18 13:40:34
予測アルゴリズムを逆手に取って常に外れ続けるパターンを作ろう

106 :97:05/02/18 14:01:31
とりあえず1氏の実験結果から分岐の処理にかかわるPenMの中の人の動き
を好き勝手想像してみました

妄想1.
分岐予測ミスのチェック、および投機されたパイプラインの破棄
は、分岐より前の、分岐条件の値が確定した時点で行われる。
投機された命令は破棄されるが分岐より前の命令は破棄されない。
このため、分岐予測ミスのペナルティは必ずしもパイプラインの
長さと一致しない。

妄想2.
1.の機構を有効利用のため、分岐先の決定にかかわる命令
(およびそれに依存する命令)は優先的にリオーダされる。

妄想3. 
分岐Aのあとにすぐ分岐Bがあり、分岐Aについてのプロファイル
結果が予測に効果を発揮しない場合、一時的に投機が中断される。
つまりこの状態では分岐のたびに必ずストールする、古典的なCPU
と同じ振る舞いになる。

1.および2.について、もし正しいなら、依存関係のある命令を連発して
分岐条件の決定がクリティカルパスになるようにし、故意に分岐の直前まで
確定させなくしてやると、違った値が出る可能性はあると思う。

3.については、電力馬鹿食いのPen4より更に強力な分岐予測機構を
搭載してまで命令投機の無駄を減らそうとしてるわけだが、
やたら強力な分岐予測機構を積んでもそれが大して役に立たない状態で
無理矢理パイプラインに命令を突っ込み続けてもかえって無駄が多い。
場合に応じて投機自体を止めることは、開発者の語る「投機の無駄を
無くすことで電力の消費を抑える」というアプローチにはなんら矛盾しない。

107 :90:05/02/18 19:17:59
>>104
キャッシュ1ラインが128ビット分でしょ、
で、分岐に使う乱数値が16ビット整数。
キャッシュミスは、最大でも8回のうち一回。

また、テーブルのサイズが過剰でなければ、
作ったテーブルがまだ二次キャッシュ上に残っている間に実行できるから、
キャッシュミスによる影響も小さくなると思う。

少なくとも、レジスタリネームとかでCPUコア内に
データが残ることによる先読みよりは、実行時間の正確さが上がらないかな?

108 :97:05/02/20 01:05:58
1次キャッシュはミスさせるのかよ


つか、MT19937も基本的に4byte×624のテーブル参照(詳しくはソースを見れ)なので
多分PenMのL1データキャッシュ32KBにすっぽり収まると思うのですが。
何ならテーブルを念入りにprefetchやってやるとか?

109 :90:05/02/20 02:38:55
テーブルを大きく取りすぎたら1次キャッシュからはずれてしまうけど、

可能ならば、1次キャッシュから外れない程度の、
小さめのテーブルを使う方が正確にはなると思う。

P4でもPenMでもAthlonXP/64でも、
どれの1次キャッシュにも収まるサイズだと、
比較しやすくていいかな。

110 :1:05/02/22 11:33:56
うかつ、測定ミス。
前置してあるC上で配列に乱数などを入れるコードを変えたときに、
測定対象コードのアライメントが影響受けるということをすっかり忘れていたのだ。

測定はint d[1000]に乱数などを予め入れてから行っているのだが、
実は、同じはずのd[i]=i%2とd[i]=i&1(交互に分岐)のクロック数が違ったので混乱していた。
詳しい原因はわからないが、アライメントの違いで5.5clkと18clkの差が出る。
しかも、コードがアライメントされた16byteに収まっている場合でもこれが起こるのだ。
そういえば、不明な低速化原因が「音楽聴きながらだから」だったこともあったなぁ・・・


なんだか考えたことはここまでのレスでみんな言われてしまったな。
こちらの説明不足も多かった。すんまそん。
乱数は配列に入れて、オールL1ヒットなので問題なし。>>88はギャグだとわかっているよな?
ていうかrand()を予測できる分岐予測があったら神(w
>>101実験サンクス。特定ビットが規則性を持つという一抹の不安は正直あった。

>>99>>102みたいな動的スケジュール説はちょっと考えていた。
>>106を参考に実験しよう(時間ないので後で)。つか普通にOoOするだけでOKな気もする。

PM以外のCPUの話題、ないっすか(むしろそっちが知りたい)。
「測定の環境・スキルはあるが面倒」という人いないかね。汚いけど測定ソース貼る?

結局、無意味なテストコードを速く実行するためのCPUじゃないので、
何かで必要な処理を限界まで最適化して、何がボトルネックかを調べる方がいい気がする。

Prefetchは、分岐とは別に興味があるところ。
L1、L2の帯域・レイテンシやロードバッファ・ストアバッファの数が既知のとき、
連続したメモリに簡単な演算をするのに必要なクロックを計算で出せないだろうか。
ストール中に別の命令を実行するため、リオーダバッファの数も影響しそうだ。

111 :1:05/02/22 11:35:03
さて、新規にコードを書き直してアライメントも揃えてやってみた。
分岐あり5clk、分岐なし10clk。交互が7.5clk、ランダム13.3clk。
素直に計算するとペナルティは11.6clk。ちょっと少ないねえ。
分岐なしではmulを1回余計にやらせるのだが、そのときALUが片方空いてるからか?

そう思って、mulをor*8(4clk)に変えてみたらペナルティ11clk。
で、>>105のP6向けパターンが>>84のリンクにあって、それを食わせると、
ランダムより3clkほど速く、mulのではランダムより1.5clk速いとなっていた。
かなり外してはいるようだがランダムより速い。必ずどころか半分も外してないようだ。
d[i]=i%nでn回に1回分岐方向を変えてみると、過去4回の履歴で予測する傾向はP6と同じ。
しかし、ループ検出器というのがあって(詳細は>>99のリンク先にある)、
これが本来の目的じゃないのに反応して少し精度が上がった感じもする。

次に、発想を変えて、1回だけの分岐で測定。
P6では、前方分岐はしない、後方分岐はすると予測するのがデフォルト。PMもそうだろう。
これはループがないため安定した結果。13〜16clkのペナルティで、ほとんどが14か15clk。
パイプラインの段数はこの辺で間違いないだろう。

ループ検出器の仕様も知りたい。ダウンカウンタの空ループ(lp:dec ecx/jnz lp)は、
P6で2clk/loop。PMではecx=64までは2clk程度で、65から急に速くなる。

μopフュージョンとループ検出器は、PentiumMを知らない頃から欲しかった機能で、
Baniasが出たときには本当に嬉しかった。
>>97、最後の1行。
惚れてる女の悪口言われると気分がよくないものです。
確かにマンデルブロ集合のSSE2ではパワーのなさを痛感したが、あばたもえくぼ。

112 :1:05/02/22 11:37:12
>>106「予測(投機)しない」について。
PentiumMの設計思想は「タスク当たりの必要エネルギー量の最小化」にあり。IPCじゃない。
パイプラインの各段が同じ消費電力(1[電気])で、リーク電流などがないモデルで考えると
予想が半分外れる最悪の状態で、予測をやめると消費電力はどう変わるか。
(全部外れるのは予測器が予測できると勘違いしてる→CPUは最悪と思っていないので除外)
n段のパイプラインでm命令ごとに予測できない分岐が来るとき、2m命令当たりの数字、
予測する:n+2m-1[clk] 2mn+n(n-1)/2[電気]、予測しない:2n+2m-2[clk] 2mn[電気]。
ここで、静的な電力(リーク電流・CPU以外の電気)をa[電気/clk]とすると、
2aがnより小さいなら、予測(投機実行)しない方がタスク当たりの電気を減らせる。
つまり、mには依存せず、システム全体の静的電力が動的電力の半分以下ならいい。
DothanULV-1.1@dynabookSSSXでは、静9W、動4Wだった(静は設定で6.5Wまで減らせる)。
これだと無意味だ。通常電圧版なら、静10W、動20Wとかになるか?これでもギリギリ必要ない。
ひょっとして外れたとき投機実行の破棄のコスト(計算外)がすごいのか?
リオーダバッファの占有率も変わるし、計算モデルが現実とかけ離れていたんだろうな。
ただ、「予測しない」によって電気を節約しても、それで遅くなるのだから、
「クロックと電圧を下げる」という強力な技にはそう簡単には勝てない。
#静:PCアイドル時SpeedStepオフの消費電力。動:「CPU負荷100%、その他は静と同じ(ファンも回さない)」-静

113 :1:05/02/23 10:56:26
>>106の測定結果。
分岐する:15.5clk、分岐しない:30.7clk、ランダム:30.1clk、交互:23.4。
いやピッタリ14.0clkのペナルティです((30.1-(30.7+15.5)/2)*2)。無意識に捏造したな>俺。
これは偶然だが、パイプラインは14〜15段ほぼ決定でいいかな?

俺は106の妄想1が非常に難しく感じられた。パイプラインの長さと一致しないのなら
OoOコアにおけるパイプラインの長さって一体何なんだ、と。
リタイヤはインオーダーだが、命令がリオーダバッファにいる平均clk数を何が規定する?
ひょっとしてリオーダバッファが混んでいるときは実質パイプラインが長くなるのか。
それだと>>81の19clkも納得できる。こじつけ臭いけど。

で、追試。
上の測定はmulを3回、分岐しないと更に3回というコード。mulは実行に時間がかかる命令だ。
そこでこれをadd15回に変えてみた。する:16.3、しない:31.8、ランダム:30.6。
ペナルティ13.1clk(少ないナ)。ここで依存関係をなくすと、ランダム:27.0。30.6-27.0=3.6。
mulの場合は依存関係あり:30.1、なし:27.0だった。差は3.1。
3.6と3.1は、誤差の範囲で一致、だろうか。
mulの方が、長い実行時間中にフェッチ・スケジュールできて差が広がると予想したが外れた。

114 :97:05/02/24 13:15:43
妄想に行き着いた過程を説明いたします。
ちょっと前、Visual C++ + Prosessor Packで、たとえばこんなコード
書いてたとき

/*
MMX系組み込み関数大量
*/
if (i == j) {
//foo
}

最適化ONにしてアセンブラの出力見たら、i == jの評価が
MMX命令の前のほうまで移動してたんです
MMX命令はフラグレジスタを書き換えないから、前のほうに
置くことができるのだ、と。

  じゃあそもそも何でこんなことやるの?

分岐予測・投機実行のないRISCだと分岐毎に必ずストールするのだけど、
いわゆるソフトウェア・パイプライニングというやつで分岐条件を
早めに確定させ、分岐のペナルティを隠蔽するテクニックが使えた。
これと同様の原理が、ひょっとしたらP6コアでも通用するんじゃないかな、と

つまりi == j の評価を先に行うことで分岐のペナルティが無くなるのでは?と。
少なくともゲイツコンパイラはそう判断したのでは?と。

ただし、x86命令は大概命令実行毎にフラグレジスタを書き換える
ような仕様だから、もしそうであっても大抵のケースでは扱いづらい気がする。
Intel謹製のやつだとどういうコードを吐くのかしら

115 :デフォルトの名無しさん:05/02/24 14:07:38
volatile

116 :1:05/03/01 13:26:19
正直、俺は最近アセンブラを“使って”はいない。
プログラミングを始めた頃はカオス・フラクラル系の絵をPenIIとVB5LEで描いていたが、
PenMでFPUを使う(100倍速くなった)今ではマンデルブロ集合も見飽きた。皮肉なものだ。

>>114
なるへそ!妄想1が理解できますた。
ていうか俺がまるっきり106を読めてなかったことに今気づいた。恥ずかすぃ。

110のこれも間違いだな>つか普通にOoOするだけでOKな気もする。
なぜなら、投機実行が「フラグを見ない分岐予測」によってのみ行われるとしたら
フラグが先に確定していても、jccをフェッチした直後には正しいフェッチはできず、
jccを実行して初めて正しいフェッチの場所がわかる。

しかもそのRISCの仕組みは「フラグを見る分岐予測」ですらないのか。
分岐後の命令は、あくまでも確定してからパイプラインに流すのね。

で、実験。
1回の前方分岐・MMXがダミー処理のループ、共にフラグを早く確定させても変化なかった。
(i == j)を先に持ってくるのはi,jの入ってたレジスタを早く解放したいからなど、他にも考えられるが
PMにはなくても、P4やK8ではそういう仕組みが入っているのかもしれない。
まあ、Intelが速くしたいのは、手で書いたアセンブラじゃなくてVC++の吐いたコードだろうけど。

おそらくPMではjccが実行されるまでは投機実行の破棄は行われない。
それでも>>113のように3clkほど速くなることについて考えてみた。
14段のパイプライン、1clkで3命令フェッチ・2命令実行、リオーダバッファ40個と仮定する。
80命令ごとに外れる分岐が来るコードを食わせる。以下、脳内シミュ。

117 :1:05/03/01 13:27:13
time00:今、パイプラインは投機実行を破棄したばかりでからっぽ。
time01:3命令をフェッチ。
time14:パイプラインが埋まる。2命令を実行中。ROB(リオーダバッファ)に3命令。
time15:ROBに3命令入ってくるのに2命令しか出て行かない。ROBに4命令。
time51:ROBに40命令。もう入れないのでパイプラインが一時止まる。
time52:ROBに40命令。2命令ずつ実行中。
time53:分岐を実行、予測ミス発覚。time0に戻る。

80命令を54clkで実行。予測ミスがなければ40clk。ちょうど14clkの損。これじゃダメ。
依存関係を調べて分岐を先に実行する。そのためのROBだ。するとこうなる。

time40:OoO発動。実行できる命令は他にもあるが、フラグに関する命令を先に実行。
time41:そして分岐を実行、予測ミス発覚。ROBに30命令。
time42:投機実行は無駄になったが、ROBには24命令生き残っている。それを2つ実行。
time43:改めて3命令フェッチ。ROBには22命令。内2つ実行中。
time53:ROBの最後の2命令を実行。
time56:パイプラインが埋まる。2命令を実行中。ROB(リオーダバッファ)に3命令。
time84:time42と同じ。

80命令を42clkで実行。2clkしか損してない!
この損はtime54-55でROBが空だったため。ここでネックになったのはROBの数ではない。
命令フェッチの能力だ。フェッチ・デコード能力は過剰でも役に立つんだねえ。
time42-43でROBの命令数が6減っているが、これは2つがtime42に実行され4つが破棄された。

実際は、長いループにランダム分岐を入れてみても、どうしても7〜9clkのペナルティがある。
これが8clk前後で一定なのを説明できる理由が思いつかない。
まさかtime42での4命令のリタイヤごときで8clkはかからないだろうし。
ROBが一杯のときは性能が落ちるのかな。

118 :1:05/03/01 13:31:05
これを考えた後、コンビニに行った。
「またお越し下さいませ」を、おつりを渡す前から言ってる店員を見て、
「そこはインオーダーだろ〜」と思ってしまった。


久しぶりに何か作ろうと思って、ライフゲームをやってみた。
VBのインタプリタで1.8fps。Cで36fps、MMXで57fps、SSEで56fpsだった。
表示部だけだと79fpsなのだが、かなり隠蔽できる気配。グラフィックのclk数はわけわかめ。

SSEは、paddb xmm0,[edx] が16byte alignでなければならないのが痛かった。
レジスタが余っていたのでMMXは1回アンロール、計算部だけならSSEより2割速くなった。
(なのになぜfpsは1しか違わない・・・)

アンロール前のMMXとSSEは互角。MMXをアンロールすると2本束ねてSSEと同じ動作になる。
この状態で、デコーダもメモリアクセスもMMX有利となる(P4だとSSE有利と思う)。

実はSSE2の整数命令主体のコードを書いた経験がほとんどなかったのだが、
やってみると64bitの壁を感じた。MMXが16本あればSSE2整数は要らないと思った。
Load/Storeが128bitいけるCPUじゃないと、本当にただの「2本束ねたMMX」だ。
結局PenMのSSE2整数は、こんな感じ↓
小回り効かない(・A・)イクナイ & レイテンシ隠蔽できる(・∀・)!!イイ


ていうか面白い!昔MMXの256*192くらいで遊んでいたが、今回はXGAをフルに使ってみた。
初期配置を512*1の線にすると、300世代くらいまでフラクタルな感じになる。
菱形に広がるクラスタの縁に沿って列をなし進むグライダーが壮観。
その後もきれいなシンメトリーで、トーラス世界(ねじり)なのでグライダー同士がピタリ激突する。
スレチガイスマソ

119 :デフォルトの名無しさん:05/03/01 22:44:46
うんこ

120 :デフォルトの名無しさん:05/03/01 22:47:22
よくVBで作る気になったね

121 :1:05/03/02 11:34:36
>>120
おいらの基本はVBなので。
アセンブラ直書きが難しいときは、Cで書いてそのコード見ながらアセンブラを書くが、
昔はVBで書いてからCにコンバート、アセンブラ化なんてやってたのう。

nasmでSSEをアセンブルし、VCでDLLを作成、それをVBで呼び出す。
表示するAPIもVBで呼ぶ。てかVCでGUI作れね。


次はアライメントかな。P6では、キャッシュラインをまたぐと9clkほど損した。
ただ、キャッシュラインをまたぎさえしなければズレたアクセスも特に問題はないみたいだった。
P4とかじゃズレたら即死しそうだけど。
(別にP4を貶すわけじゃない。PenMの「性能/電力」の高さは、
絶対性能の低さに甘んじているからだと思うので)

ところで糞P4使いは、いないのかい?
倍速ALUや高スループットのキャッシュ、ぶっちぎりの絶対クロック。
アセンブラレベルでご機嫌とれば、かなり化ける希ガス。
心配なのはライトスルーのL1Dataや等速ALUの遅さ、MMXとFPUは捨ててる感じだし。

122 :デフォルトの名無しさん:05/03/02 14:53:22
>>118
ソースあpしる VBのも

123 :デフォルトの名無しさん:05/03/02 23:25:08
>>116
いや妄想に付き合っていただき感謝
まあゲイツコンパイラの気まぐれの気もしたのだけどね。
GCCもそうなのだけど、PentiumでいうUVパイプライン最適化
ってやつがあんまり利いてないっていうか
ちょっと式が複雑になるとスタックフレーム生成しまくりやがる。
実はcl.exeの最適化エンジンってレジスタ数の多いRISC
由来だったりとか?

最近Prescottマシンに触れる機会があってMMX/SSEバリバリ
のソフトでベンチマークとってみたけど、
同クロックのNorthwoodに比べて、確かに処理能力は落ちてる
のだけど、レイテンシ増大の割にはあんまり低下してないと思った。

NorthwoodでHT enableだとただでさえ小さいL1キャッシュを
分断するので逆効果になるケースがあったけど、
Prescottだとキャッシュの増分、効果は得やすくなったと思う。
ただロード・ストアまわりが・・・

124 :14 ◆TimpoiKAMI :05/03/03 03:48:36
コテ名乗れ。 あぼ〜んできないじゃないか。


>>1
誠にすまんが、このスレはしばらくROMに徹しさせていただく。
進展がないようだったら巡回から外す。

125 :1:05/03/03 10:47:52
>>124
む、それは残念。97よ、おまい何したんだ。
関係ないが、漏れも来週を最後に数週間来られないかもしれん。
何か話し続けといてちょ。

>>122
次来たときうpする。

>>123
コンパイラ作成はかなり大変で、しかたなくメモリアクセスが増えてると思っている。
SIMD対応コンパイラでも大して速くなったという話を聞かないし。
単純なロジックなら人間、複雑な大域最適化はコンパイラじゃないかな。
その辺の知識はないのでハズレかもしれんが。
プレスコは、よりHT向きになった石だね。レイテンシ増はHTで隠蔽できそう。

ところで、だれか上の吉野家コピペに反応してくれ。
けっこう時間かけて作ったんだからさ。

126 :デフォルトの名無しさん:05/03/03 13:15:29
複雑な大域最適化なんて今のコンパイラにはなおのこと荷が重いだろ

127 :デフォルトの名無しさん:05/03/03 13:57:28
10年ぐらい前のmipsコンパイラでも当たり前にやってた
気もするけど。

128 :97:05/03/03 23:28:19
じゃあネタ振りでも
http://www.hackersdelight.org/HDcode.htm
のMMX/SSEを使った高速化について。
とりあえず64×64. 128×128の転置行列を作る。
で、基本的なアイディアとして、

1.サンプルコードと同様、素直にシフトと論理演算の組み合わせ
(原著によれば完全にアンループするとRISCで3886命令程度なるらしい)

2.とりあえず8/16/32bitシフトしてマスクして重ね合わせの部分は
pupk[hl][dwb]でインタリーブすれば同様のことできるじゃん
(去年の4月ごろ考案)

3.そーいやSSEにpmovmskbあるけど、マスク演算無しで
8bitずつビットの間合いを詰められるぜ?(最近おもいつく)

で、気合い入れてコード書いてみた割にはあんまり期待しただけの
パフォーマンスは出なかったのね。
思うに演算ユニットが並列動作してねーんじゃないかと。
まあマイナー命令連発だからな。
8×8bitだとmovqでMMXレジスタに一気にロードしてpmovmskb
+左論理シフトを繰り返す方法がダントツ最速ですた。

てか、このへんの命令ってどんな命令と並列動作できんのかしら?

129 :デフォルトの名無しさん:05/03/04 00:21:27
>>128

MMX演算ユニットって、
用途の限られたユニット二つで構成されてるでしょ?
MMX命令の大半は、どちらか片方でしか動かない。

ちゃんと工夫しないと、並列動作は無理だと思う。

130 :デフォルトの名無しさん:05/03/06 02:55:44
http://homepage1.nifty.com/kaneko/glhair.htm
だれかこいつをスバラシく高速化してみてくれ。得意だろ?

131 :1:05/03/08 13:09:06
>>128
0x80getおめ。
転置行列は2次元FFTで使ったな。Cでそのまま書いて全く最適化してないが。
pmovmskbはビットインバースのインクリメントで見て面白いと思ったが、
「8bit間合いを詰める」とはまた面白い捉え方だ。本当にイイ命令だなあ。

並列実行云々を論ずるのであれば使用CPUを書かないと。
PenMならpmovmskb(MMX)はpaddと同じ負荷しかない(1-1 add/mul)。
K8は3-1 add/mul。これも一応並列実行できるが、デコードが1命令/clkしかできない。
P4は7-2。SSEの128bit pmovmskbも7-2。使えるユニットは1個。P4はMMX自体糞。

思うに128はAthlonを使っていてデコーダがネックになったと見るが、どうか。

>>129
MMXで並列実行できないのは、P6,PM,K7,K8ではmul系同士ぐらいしかないんじゃないかな。
P4のMMX/SSEは、そもそもALU・mov系以外との並列実行ができないのでダメだし。
基本的に、fadd系がaddユニットのみ、fmul・int mul系がmulユニットのみ、ALU・mov系が両方、
という感じだろう。
P4は、2倍速ALUは速いが、SIMDはmov系以外並列実行できない。
というか2つのユニットが合体したものが1つあると言った方が正しいか。
だから、MMXは遅くても、SSE/2では問題にならない。

http://haiiro.info/up2/file/8226.zip
ライフゲーム、うp。自分用フルセット。

>>130
濃緑研究所はなつかしいなあ。初めて行ったのが更新されなくなってからだけど。
SSEをコンパイラまかせにしているんじゃ、遅いだろう。
単純にアセンブラにすれば相当速くなるだろうが、長いアセンブラは頭がこんがらがるのよね。

132 :1:05/03/08 13:10:09
PeniumMのL1Dataはキャッシュラインが64byteになっている。
8KB分のintの総和を求めるコードでロード性能を計測。MMXだと当然8byte/clk。
ここで、アライメントを崩してやる。すると半分の速度(8load/16clk)になった。
MMXレジスタが8byteなので、8(=64/8)回のロードにつき1回キャッシュラインをまたぐ。
つまりキャッシュラインをまたいだ8byteのロードは9clk。P6と同じだ。
またぎさえしなければ一応ペナルティなし。

次に32bitの整数レジスタでやってみる。4byte/clk「弱」。
MMXでは完全に隠蔽できていたループのオーバーヘッドが、なぜか隠せていない。
同様の実験をして、またいだロードはおよそ11clkだったが、addが負荷になっている感じ。
movだけでやるとこれも11じゃなくて9clkっぽい。

そしてSSEのmovdquで実験。結果は9clkより少し大きい感じ。
#8byte alignであればペナルティはない。8byteのloadを2回している状況証拠。
#9clkというのは、(16byteではなく)その8byte loadのこと。

ストアの計測もした。一応ゼロフィルのコード。
movdquだが、おしなべてmovdqa(8byte/clk)の倍遅い。またいだクロックも20clkと倍。
MMXだと普通に8byte/clk。またぐと15clk。clk数が大きくて不安定なのはSSEと同じ。
32bit整数だと10clk。movdも同じだった。


そもそもキャッシュラインをまたいでいるときはどうやって転送しているのだろう。
SSE3にlddquというmovdqu(load)と同等の命令がある。
16byte alignのloadを2回行って合成するため、「またぐ」心配がないのが存在意義。
常に倍のloadをするので、「そもそもが遅い命令である」というのは忘れないように。
さて、わざわざlddquという命令を作ったということは、movdquでまたいだときには
「2回読んで合成」ではないと考えるしかない。
・・・じゃあどうやってんだよ。ダメだと判明してから2回読むから遅いとか?

IntelのP6最適化マニュアルには「6〜12サイクルのストールが生じる」とあった。
対症療法は書いてあるが、原因部分が書いてない。

133 :1:05/03/08 13:11:11
間違い!上で整数レジスタが微妙に遅かったのはeaxにだけ足していたからだ。
MMXではmm0とmm1に分けていた(すみません、ひいきしてました)。
アドレスの計算が依存チェーンを長くしているので普通のOoOじゃ原理的に隠蔽しきれないか?


Prefetchもやってみた。
上述の足し算コードで、paddd xmm0,[esi] の前にprefetcht0 [esi+64]を置く(64byte毎)。
すると、L2は4byte/clkだったのが5.33byte/clkまで上がった。ちょっと感動。
ただ、これが上限である理由がわからない。もっといけるのかな。
キャッシュラインを意識した使い方をする必要がある。

ところが、prefetcht0 [esi+64] をmov eax,[esi+64] で置換したら5.8byte/clkまで上がった!orz
おまいは一体何のためにSSEで実装されたのかと小一時間・・・
それはさておき、L2の真の実力が8byte/clkあるとすれば
prefetcht0 では64byteごとに4clk、mov eax,[ ] では2clkの無駄がある計算だ。
(movは3clkだが、実際にeaxへ転送する1clkを引いてある)

つうかPenMにはHWプリフェッチがあるはずだが、こんなわかりやすい処理でも
HWプリフェッチなしのP6と同じってどないなっとんねん。
・・・と思ったらそれはメモリからL2への話か。確かに、L1へ勝手にフェッチされたら嫌かも。

ライフゲームにprefetcht0使ったが、遅くならないようにするのがやっとだった。
キャッシュラインまたぎまくりだから仕方ないか。
次はL1Dataが8Wayであることの見えるコードでもやろうかね。

134 :デフォルトの名無しさん:05/03/09 01:12:10
キャッシュを考慮したプログラムは興味あったから参考になるなぁ。
ところでプリフェッチは意味ないのかね?

http://www.ueda.info.waseda.ac.jp/~ishizaki/pukiwiki/pukiwiki.php?prefetch%A4%CB%B4%D8%A4%B9%A4%EB%BC%C2%B8%B3
上のページでは効果出てるから使ってみようかと思ってたけど。
Pen4だと効果あるのかな。

135 :1:05/03/09 10:26:41
>>134
プリフェッチは正直わからない。
やらないよりは速いので、効果はちゃんとある。
mov eax,[ ] はeaxを汚染するので、一応prefetcht0の存在意義はあるのだが、
実際の転送を行うmovよりも遅いのは説明がつかない。
転送終わるまで指くわえてるのかな。


>>126
局所的なコードの目的をつかんで必要な命令だけ書くというのは人間の独擅場。
ただ、Cで10行とかになってくるだけで人間アセンブラは思考停止になるので(俺は)、
長いコードでは相対的にコンパイラに負ける。
俺が初めてMMXのライフゲームを作ったときはCコンパイラに負けた。
当時経験が少なかったために冗長なコードしか書けなかったのだ。


16byte境界を表示してくれるアセンブラのエディタが欲しいな。

136 :1:05/03/09 12:29:29
メモリの読み書きは、全てL1キャッシュに対してのみ行われる。
メインメモリからL1への転送は、常にキャッシュライン毎。1ラインをフィルする。
L2は、役割としてはメインメモリと一緒、ひらすらL1へキャッシュラインのバースト転送を行う。

ネタと言えば、
命令キャッシュのアライン・ROBの数・必ず分岐予測を外す方法・L2キャッシュへのプリフェッチ
頭痛くなってくるな。じゃ、さよなら。

137 :デフォルトの名無しさん:05/03/09 19:01:31
今時のCコンパイラは賢いよ。

SIMD命令でも、組み込み命令を使ってコンパイラに最適化させても、かなりの速度が出るよ。

138 :デフォルトの名無しさん:05/03/10 02:19:29
それはVCとかでなんか指定すんの?素人でスマン。

139 :デフォルトの名無しさん:05/03/10 17:45:01
>>138
何も指定しないでいい。

むしろ何か指定すると、最適化が阻害される。

140 :デフォルトの名無しさん:05/03/11 01:50:47
_mm系の命令を普通に使ってるほうがアセンブラでSSE使うより
高速なのかな。

141 :デフォルトの名無しさん:05/03/11 21:19:25
インラインアセンブラで書くと、コンパイラの最適化の対象外になります。

インラインアセンブラで書いた命令だけでなく、その前後までもが最適化されなくなります。
(インラインアセンブラの部分をまたいでの最適化が行われなくなる。)


142 :デフォルトの名無しさん:05/03/12 02:23:20
素人は組み込み関数使っておけって事だね。

143 :デフォルトの名無しさん:05/03/12 03:41:49
そして、
組込み関数をインライン展開する
という一見速くなりそうなオプションは、この場合のみ、逆効果になる。

なぜなら、インライン展開されたコードは最適化されないから。

144 :デフォルトの名無しさん:05/03/12 03:43:49
リリース版だと組込み関数は、そのままSIMD命令になるのに、
デバッグ版だとライブラリ関数の呼び出しになるので、
やってられないくらい動作が遅くなって、デバッグに差し支える。

なので、デバッグ版ではインライン展開してしまったほうが、いいかも・・・。

145 :デフォルトの名無しさん:05/03/12 08:15:03
>>139

おなじVCといっても、LearningEditionとBasicとPrpfessionalで
最適化の規模が段違いでそ

LEでは、確か、まったく最適化してくれないんじゃなかったっけ?

146 :デフォルトの名無しさん:05/03/12 08:28:55
でも今はVC Toolkit 2003(Pro相当)がタダで手に入る。

147 :デフォルトの名無しさん:05/03/12 20:02:25
そうなんだ・・・。

MSDNエンタープライズ版で送られてくるのを使ってたので、エディションの違いは気にしていなかったよ。

148 :デフォルトの名無しさん:05/03/12 21:00:31
>リリース版だと組込み関数は、そのままSIMD命令になるのに、
>デバッグ版だとライブラリ関数の呼び出しになるので、

あぶねー。そんな事しらずにデバッグ版で最適化試すとこだったよ。

149 :97:05/03/13 13:01:58
>>132
> movdqu OR lddqu
その合成処理って例の8ビット単位しかできないシフト演算で実装されてるんじゃねーかなと
思った。なんであんな中途半端な命令の実装にしたのか考えてみたがそれしか思い浮かばない。

MMXのpq[lr]lq×2でもいいから1bit単位のシフトは用意しておくべきだな。
俺多用するから

150 :デフォルトの名無しさん:05/03/13 13:31:42
整数の絶対値命令と丸めモード固定のfist系命令が無いのは許せん

151 :97:05/03/13 15:20:07
すんまそん>>149訂正psrlqとpsllqね。

80 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.02.02 2014/06/23 Mango Mangüé ★
FOX ★ DSO(Dynamic Shared Object)