基本的なアーキテクチャその2

ところで筆者の連載の中で、昨年から今年にかけてちょっとCore Microarchitectureの掘り下げを行った。メインとなるのはこちらで、上手く最適化するとConroeではx86命令換算で5命令/Cycleの処理が行える、というものだ。ソース及びバイナリは現在も入手可能にしてあるので、ご自分で試したり、内容をチェックしていただく事も可能だ。

さてこのプログラム(Util29)では、

(Test1) 理論上、5命令/cycleで廻るプログラム
(Test2) Test1で、EDXレジスタも使うように改変
(Test3) Test2のループにnopを1つ追加
(Test4) Test2を改変して、5命令(MicroOpsで7命令)となるループにする
(Test5) Test2を改変して、6命令(MicroOpsで9命令)となるループにする
(Test6) Test2を改変して、7命令(MicroOpsで11命令)となるループにする

の6つのケースを測定している。

この結果を、Yorkfieldに対して行ったのがグラフ40である。ついでなので、

・Pentium M 1.60GHz(Lenovo ThinkPad X32/Windows XP日本語版)
・Core Solo U1400(1.2GHz)(富士通 Lifebook U FMV-P8230/Windows XP Tablet Edition 2005 日本語版)
・Core2 Duo E6700(2.66GHz)+Intel Q33搭載マザー(Windows Vista 32bit英語版)
・Core2 Quad Q6600(2.4GHz)+Intel 975X搭載マザー(Windows Vista 32bit英語版)
・Athlon 64 X2 5000+(2.6GHz)+NVIDIA nForce570搭載マザー(Windows Vista 32bit日本語版)

の環境でも同じデータを取り直して追加してみた。ちなみにKentsfieldはCore2 Ext.Q6850、YorkfieldはCore2 Ext. QX9650と表記している。テストは10万回のループで行い、10回実行した後の平均値としている。さて、結果をみるとこれまた綺麗に並んでいるのが判る。これを見る限り、デコーダ部などの構造もConroeをそのまま継承していると判断して差し支えないだろう。

ところで最初に戻ると、45nm世代ではFast Radix-16 Dividerの搭載が大きく取り上げられているが、単独でこれを評価できるようなプログラムは存在しない。というわけで、作ってみたのがUtil31(Util31.exe)である。ソースはこちら(Util31.cpp)で、1024×1024=1048576回づつ、単精度(Float)と倍精度(Double)の浮動小数点の除算を行うのに必要な所要Clock数をrdtsc命令を使って取得する、というものである。ちなみにVisual studio.net 2005を使った場合、Release Buildで普通に最適化をかけると、肝心の浮動小数点演算が「無駄な処理だ」とばかりに全部最適化されてしまったので、Debug Buildを使うことにした。アセンブルの結果はこちら(Util31.asm)に示す通りで、肝心の除算部はFloatの場合、


; 26   : 			floatBuf = (float)lpCnt1 / (float)lpCnt2;

	fild	DWORD PTR _lpCnt1$[ebp]
	fidiv	DWORD PTR _lpCnt2$[ebp]
	fstp	DWORD PTR _floatBuf$[ebp]

といった具合にやや無駄は多いが、とりあえず評価には問題なさそうだ。

さて、結果はというとグラフ41に示す通りである。ループ内部にdiv以外の命令も含まれているから、実際の所要Clock数はもう少し減ると思うが、それにしてもYorkfieldでは大幅に処理のスループットが上がっている事が確認できた。純粋にdiv命令だけで比べれば、ほぼ倍近いスループットになっていると考えても問題ではないだろう。ただ、それでもAthlon 64 X2 5000+と比較すると負けているというあたりは、それだけK8の除算が高速という事を示しているとも言える。つまり除算に関しては「Conroeに比べて倍になった」と言うよりは「やっとAthlon 64に比肩できる性能になった」と言うべきなのかもしれない(そう考えると、まもなく登場するPhenomがFPUをDual Issueにするのは正しいアプローチであろう。Single Issueでスループットをここから更に倍にするのは大変だろうからだ)。