質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
キャッシュ

キャッシュはドキュメントやデータを一時的に保管するもので、アクセス処理時間を短くするために使用されます。

Q&A

解決済

2回答

592閲覧

配列から配列へ要素をコピーする関数におけるキャッシュミス数とキャッシュヒット数の数え方

ijuya_yika

総合スコア50

キャッシュ

キャッシュはドキュメントやデータを一時的に保管するもので、アクセス処理時間を短くするために使用されます。

0グッド

0クリップ

投稿2017/10/28 22:27

編集2017/11/02 20:43

C言語で以下のような2次元配列から2次元配列へ要素をコピーする関数があるとします

c

1typedef int array[2][2]; 2 3void copy_arr(array A, array B){ 4 int i, j; 5 6 for(i=0; i<2; ++i){ 7 for(j=0; j<2; ++j){ 8 A[j][i] = B[i][j]; 9 } 10 } 11}

もし

  • キャッシュが1ブロックサイズ=8バイトで合計容量16バイトまで
  • sizeof(int)が4バイト
  • キャッシュがダイレクトマップ方式で最初は空
  • Bがアドレス0から始まってAがアドレス16から始まる

とした場合ですが、

  1. キャッシュにB[i][j]が無い(ミス)ので、Bの配列を全てキャッシュに格納(容量が16バイトまでなのでキャッシュはBの要素で埋まる)した後にB[i][j]を読み込む

  2. キャッシュにA[j][i]が無い(ミス)ので、Aの配列を全てキャッシュに格納(容量が16バイトまでなのでキャッシュはAの要素で埋まる)した後にA[j][i]を読み込む

  3. キャッシュにB[i][j+1]が無い(ミス)ので、Bの配列を全てキャッシュに格納(容量が16バイトまでなのでキャッシュはBの要素で埋まる)した後にB[i][j+1]を読み込む

4.キャッシュにA[j+1][i]が無い(ミス)ので、Aの配列を全てキャッシュに格納(容量が16バイトまでなのでキャッシュはAの要素で埋まる)した後にA[j+1][i]を読み込む

(以下(8)まで同じ要領でミスが続く)
となりミス率は100% (ヒット率は0%) だと思っていたのですが教科書によるとB[1][1]をコピーする時唯一ヒットとなると書いてありました。これはなぜなのでしょうか…?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

ダイレクトマップ方式を完全に誤解していました。

ブロックサイズが8なのでブロックオフセットのビット数は2^b = B より b = 3
セット数はS=2なのでセットインデックスのビット数はS = 2^s より s = 1

よってキャッシュのどのセット(今回の場合だと 0 or 1)に配列がロードされるかはアドレスの第3ビットによって決定されるのでしたね

BとAのそれぞれの要素をArr[int1][int2]の形式にすると

B[0][0]B[0][1]B[1][0]B[1][1]
0-3バイト目4-7バイト目8-11バイト目12ー15バイト目
A[0][0]A[0][1]A[1][0]A[1][1]
16-19バイト目20-23バイト目24-27バイト目28ー31バイト目

アドレスを見るとそれぞれB[0]0x0000, B[1]0x1000, A[0]0x10000, そしてA[1]0x11000 ⇛ 第3ビットによりA[0],B[0]はセット0へ,A[1],B[1]はセット1へ格納となるのですね

流れとしては
i=0, j=0
B[0][0]をセット0へ(ミス)⇛ セット0のキャッシュが空の為,新しく格納
A[0][0]をセット0へ(ミス)⇛ B[0]を追出し

i=0, j=1
B[0][1]をセット0へ(ミス)⇛ A[0]を追出し
A[1][0]をセット1へ(ミス)⇛ セット1のキャッシュが空の為,新しく格納

i=1, j=0
B[1][0]をセット1へ(ミス)⇛ A[1]を追出し
A[0][1]をセット0へ(ミス)⇛ B[0]を追出し

i=1, j=1
B[1][1]は既にB[1]がセット1に格納されていた為何もしない(ヒット)
A[1][1]をセット1へ(ミス)⇛ B[1]を追出し

で結局唯一のヒットはB[1][1]の時ということがわかりました。

投稿2017/11/02 20:42

編集2017/11/02 20:47
ijuya_yika

総合スコア50

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

キャッシュが1ブロックサイズ=8バイト

ということであれば、B[1][0]を参照した場合、B[1](2個分8バイト)だけがキャッシュに乗ります。それを前提に考え直してみてください。

投稿2017/10/29 00:16

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ijuya_yika

2017/10/29 12:18 編集

ご回答ありがとうございます。 頂いたコメントを元に考え直したのですが、参照の順番は`B[0]`(ミス) ➝ `A[0]`(ミス) ➝ `B[0]`(ヒット) ➝ `A[1]`(ミス) ➝ `B[1]`(ミス) ➝ `A[0]`(ミス) ➝ `B[1]`(ヒット) ➝ `A[1]`(ミス)で良いと思うのですが、`B[0][1]`の参照の際にヒットにはならないのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問