graphics.hatenablog.com

技術系テクニカルアーティストのあれこれ

CPU とキャッシュのはなし


GPU 




CPU 100




CPU 8 512 

CPU 





function 読み込み命令 {
  if(読み込みデータがキャッシュに載ってない) {
    読み込みデータをキャッシュに載せる;
  }
  キャッシュから読み込み;
}


function 書き込み命令 {
  書き込みデータをキャッシュに載せる;
  キャッシュにダーティフラグを立てる;// メインメモリとキャッシュの整合が崩れる
}
function CPUが暇なときに呼ばれるコールバック {
  if(キャッシュにダーティフラグが立ってたら) {
    キャッシュからメインメモリにコピー;// メインメモリとキャッシュの整合を確保
    ダーティフラグを折る;
  }
}


function 書き込み命令 {
  書き込みデータをキャッシュに載せる;
  キャッシュからメインメモリにコピー;// メインメモリとキャッシュの整合を確保
}

使CPU使使




使 ppc  int  float ppc  int/float 使
float f = 1.f;
int i = f;

iff int f10
int hoge(int* a, int* b) {
  *a = 3;// (1)
  *b = 5;// (2)
  return *a + *b;
}

 1: a b(1)  (2) 
 2: a b (1)(2)  (2)  (1) (1) (2)  *b 5
CPU ab2 __restrict 


L1 Cache  L2 Cache

2 L1Level 1Cache  L2Level 2Cache 2CPU  L1 L1  L2  L1 L2  L2  L1 


I-Cache  D-Cache

2 I-CacheInstruction Cache D-CacheData Cache2
D-Cache 
float m[100][100];

 m[0][0], m[0][1], m[0][2], ... 
for(int col = 0; col < 100; ++col) {
  for(int row = 0; row < 100; ++row) {
    float val = m[col][row];
    ... // val を使った計算
  }
}

2
I-Cache 
int f1() { ... }
int f2() { ... }
int f3() { ... }

f1/f2/f3 obj
使




2 L1/L2 2

int flag = 0;
critical_section cs;

inline void locked_write(int* dst, int src) {
  enter_critical_section(&cs);
  *dst = src;
  leave_critical_section(&cs);
}

void core1_func() {
  while(true) {
    if(flag  == 0) locked_write(&flag, 1), hoge();
  }
}

void core2_func() {
  while(true) {
    if(flag  == 1) locked_write(&flag, 0), fuga();
  }
}

int main() {
  ...
  initialize_critical_section(&sc);
  run_on_core1(core1_func);
  run_on_core2(core2_func);
  while(true){
    ...
  }
  ...
}

hoge()  fuga()  flag  flag
CPU/GPU  CPU/CPU  CPU/GPU GPU  CPU GPU