その下には、模擬試験の問題があります。この表には、実際にはすべてのソリューションが記入されています。ただし、ソリューションが何であるかについて明確にする必要があります。(水平線の下の質問を読んでください)。
たとえば、A2 と A3 のソリューション行を理解したいと思います。
ご覧のとおり、A2 では次のような状況が発生しています。
- x * y
- xy * r
- xyr * z
それでは、それがパイプラインでどのようになるかを見てみましょう。
|1|2|3|4|5|6|7|8 |9|10|11|12|13|14|15|16|17|18|19|20|21|
| | | | | | | | | | | | | | | | | | | | | |
{ x * y } | | | | | | | | | | | | | | | | |
{ xy * r } | | | | | | | | | | | | |
{ xyr * z } | | | | | | | | |
//next iteration, which means different x, y and z's| |
{x2 * y2 } | | | | | | | |
{x2y2 * r } // this is dependent on both previous r and x2y2
{x2y2r * z }
したがって、依存関係の競合がないため、xyr * z と x2 * y2 を重ねることができます。しかし、それは3サイクルを取り除くだけですよね?
したがって、(12 - 3) / 3 = 9 / 3 = 1 エレメントあたり 3 サイクル (3 エレメント) となります。では、どうやって A2 の 8/3 CPE を得ているのでしょうか?
この概念を理解する助けがあれば大歓迎です! テストは来週までないので、急ぐ必要はありません。他に必要な情報があれば教えてください!
(以下は、完全に解答が記入された表とともに、完全なテスト問題のテキストです)
n 個の整数の配列の積を計算する次の関数を考えてみましょう。
ループを 3 倍に展開しました。
int prod(int a[], int n) {
int i, x, y, z;
int r = 1;
for(i = 0; i < n-2; i += 3) {
x = a[i]; y = a[i+1]; z = a[i+2];
r = r * x * y * z; // Product computation
}
for (; i < n; i++)
r *= a[i];
return r;
}
製品の計算というラベルの付いた行では、次のように、括弧を使用して計算の 5 つの異なる関連付けを作成できます。
r = ((r * x) * y) * z; // A1
r = (r * (x * y)) * z; // A2
r = r * ((x * y) * z); // A3
r = r * (x * (y * z)); // A4
r = (r * x) * (y * z); // A5
関数のパフォーマンスを要素あたりのサイクル数 (CPE) で表します。この本で説明されているように、この測定では、長さ n の配列の実行時間がクロック サイクルで測定され、Cn + K の形式の関数であると想定しています。ここで、C は CPE です。
Intel Pentium III で関数の 5 つのバージョンを測定しました。このマシンでの整数乗算演算のレイテンシは 4 サイクルで、発行時間は 1 サイクルであることを思い出してください。
次の表は、CPE のいくつかの値と、欠落している他の値を示しています。測定された CPE 値は、実際に観察された値です。「理論上の CPE」とは、整数乗数の遅延と発行時間が唯一の制限要因である場合に達成されるパフォーマンスを意味します。
不足しているエントリを入力します。測定された CPE の欠損値については、同じ計算動作を持つ他のバージョンの値を使用できます。理論上の CPE の値については、乗数のレイテンシと発行時間のみを考慮して反復に必要なサイクル数を決定し、3 で割ることができます。