問題は、Conroeの時に異様にスコアが悪かったPrefixed CMPの結果(グラフ24~27)で、以前の結果とまるで様変わりしている。実はこれは、ベンチマーク側の問題。以前はRightMark Memory AnalyzerのVersion 3.65を、今回はVersion 3.72を使っているのだが、実はVersion 3.70で"Minor changes to prefixed instructions decode tests"なんて項目が入っている。実際、ソースコードを比較するとVersion 3.65のDecode.cppが、
const BYTE CodeBlock_CMP_0_8BYTE[8] =
{
0xF3, 0x67, //
0x81, 0xF8, 0x00, 0x00, 0x00, 0x00 // cmp eax, 0x00000000
};
const BYTE CodeBlock_CMP_8_8BYTE[8] =
{
0xF3, 0x67, //
0x81, 0xF8, 0x7F, 0x00, 0x00, 0x00 // cmp eax, 0x0000007f
};
const BYTE CodeBlock_CMP_16_8BYTE[8] =
{
0xF3, 0x67, //
0x81, 0xF8, 0xFF, 0x7F, 0x00, 0x00 // cmp eax, 0x00007fff
};
const BYTE CodeBlock_CMP_32_8BYTE[8] =
{
0xF3, 0x67, //
0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F // cmp eax, 0x7fffffff
};
なのに対し、Version 3.72のDecode.cppは、
const BYTE CodeBlock_CMP_0_8BYTE[8] =
{
0xF3, 0xF3, //
0x81, 0xF8, 0x00, 0x00, 0x00, 0x00 // cmp eax, 0x00000000
};
const BYTE CodeBlock_CMP_8_8BYTE[8] =
{
0xF3, 0xF3, //
0x81, 0xF8, 0x7F, 0x00, 0x00, 0x00 // cmp eax, 0x0000007f
};
const BYTE CodeBlock_CMP_16_8BYTE[8] =
{
0xF3, 0xF3, //
0x81, 0xF8, 0xFF, 0x7F, 0x00, 0x00 // cmp eax, 0x00007fff
};
const BYTE CodeBlock_CMP_32_8BYTE[8] =
{
0xF3, 0xF3, //
0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F // cmp eax, 0x7fffffff
};
に書き換えられている。要するに0x67、つまりAddress Size Overrideを使わないように書き換えられたわけだ。これが何に関係するかというとこちら。要するにCore Microarchitectureでは「使ってはいけません」命令を使わないようにしたという話である。おそらくはVersion 3.65をCore 2で動作させてあまりの成績の悪さに「そもそもAddress Size Overrideを指定するようなベンチマークってどうよ」という議論になったのではないかと思う。そこで、無難に0xF3に書き換えられた結果、通常のDecode Pathを通るようになり、スコアも通常のCMPと同じ程度に改善した、という話だろう。
実際、RMMA V3.65を引っ張り出してYorkfield上で試したら、やはり2.3Bytes/cycle弱という正しい(?)成績が得られた(グラフ28)。このあたりからも、Decode段の基本的な構造が一切変わっていない事が伺える。