Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Simulator

128 views

Published on

logic & fault simulator
Operating principle and optimization

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Simulator

  1. 1. 故障シミュレータ 計算機システム研究室 B4 中岡典弘
  2. 2. アジェンダ 1. 計算機環境について 2. 論理シミュレータ 3. 故障シミュレータ 4. 結果 1
  3. 3. 計算機環境について lizard(192.168.23.73) CPU: Intel® Xeon® E5620 (2.40GHz) Memory: 48GB OS: CentOS 6.8 コンパイラ: GCC version 4.4.7 2
  4. 4. 論理シミュレータ(処理手順) 1. 回路テーブル,テストパターンの読み取り 2. 演算順序の決定 3. 信号線の演算 4. ansファイルへ書き込み 3
  5. 5. 論理シミュレータ(演算順序の決定) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 4
  6. 6. 論理シミュレータ(演算順序の決定) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 5
  7. 7. 論理シミュレータ(演算順序の決定) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 9 10 11 6
  8. 8. 論理シミュレータ(演算順序の決定) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 7
  9. 9. 論理シミュレータ(信号線の演算) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 値 1 1 1 1 8
  10. 10. 論理シミュレータ(信号線の演算) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 値 1 1 1 1 1 1 1 1 9
  11. 11. 論理シミュレータ(信号線の演算) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 値 1 1 1 1 1 1 1 1 1 1 0 10
  12. 12. 論理シミュレータ(信号線の演算) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 値 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 0 1 1 11
  13. 13. 故障シミュレータ(処理手順) 1. 故障リストの読み取り 2. 故障の設定 3. 演算順序に従い信号線を演算 4. 演算結果と論理シミュレータの信号線の値を比較 5. 故障検出率を算出 12
  14. 14. 故障シミュレータ(演算順序の決定) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 4 3 5 6 7 8 13
  15. 15. 故障シミュレータ(信号線の演算) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 4 3 5 6 7 8 値 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 14
  16. 16. 故障シミュレータ(演算順序の決定) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 15
  17. 17. 故障シミュレータ(信号線の演算) 1 2 3 4 6 5 8 7 10 9 11 12 14 13 15 16 17 18 19 番 号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 演 算 順 1 2 3 4 5 6 値 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 0 1 1 16
  18. 18. 故障シミュレータ(実装) • 故障値が出力まで到達しない場合がある • 演算ルートを全て計算するのはもったいない • 演算しながらルートを作成する方が良いのではないか ⇒キューでの実装 • 正しい演算結果を求めるために、キュー内のソートが必要 17
  19. 19. 故障シミュレータ(実装) 1 2 3 4 9 6 5 10 87 番号 1 2 3 4 5 6 7 8 9 10 演算順 1 2 3 4 5 6 7 8 9 10 $1 1 2 3 4 5 7 6 8 $2 1 2 3 4 5 6 7 8 値 (正/$1/$2) 1/1/1 1/0/0 0/0/0 1/0/0 1/0/0 1/0/0 1/0/0 0/1/1 1/0/1 1/0/1 2/0故障を想定 入力:1->1 2->1 3->0 $1:エンキューのみ $2:エンキュー+ソート 18
  20. 20. 故障シミュレータ(最適化) • ほぼ論理シミュレータで決定した演算順序にエンキューされる • キュー内は分岐の数だけ値が存在 ∴そこまで数が多いわけではない • 最適なソートアルゴリズムはどれだろう? ⇒挿入ソートが最適ではないか ∵クイックソートなどはオーバーヘッドが大きい? 19
  21. 21. 故障シミュレータ(最適化) 回路名 クイックソート 挿入ソート マージソート e432 0.004 0.004 0.004 e499 0.005 0.005 0.005 e880 0.012 0.012 0.010 e1355 0.017 0.020 0.019 e1908 0.036 0.037 0.044 e2670 0.045 0.041 0.045 e3540 0.060 0.059 0.061 e5315 0.080 0.071 0.069 e6288 0.123 0.113 0.134 e7552 0.178 0.167 0.181 20
  22. 22. 故障シミュレータ(最適化) 21 回路名 クイックソート 挿入ソート マージソート cs9234 0.111 0.098 0.104 cs13207 0.145 0.158 0.126 cs15850 0.137 0.135 0.117 cs35932 0.219 0.229 0.233 cs38417 0.283 0.276 0.290 cs38584 0.313 0.311 0.311 • 挿入ソートがいつも最速とは限らない • 挿入ソート>マージソート>クイックソートで試すのがオススメ
  23. 23. 故障シミュレータ(最適化) • キューでの実装にはエンキューごとにソートが必要 • エンキューの回数が増えれば、実行時間が長くなる • 一部の故障パターンでは全走査した方が速い • エンキューの回数を考えて,キューか全走査か判断 • cs35932の場合 キュー実装: 0.219s 全ソート回数: 2123143回 1故障あたり最大ソート回数: 9249回 全走査: 0.180s 22
  24. 24. 故障シミュレータ(最適化) • ビット演算を用いた処理 • ループ処理の最適化 • アセンブラを用いた最適化 • 細かな最適化 23
  25. 25. ビット演算を用いた最適化 24
  26. 26. 故障シミュレータ(最適化) • ビット演算 2進数の0/1の列を操作するような演算の総称 ビット論理和,ビット論理積,ビット排他的論理和,ビット否定, etc… • ビット演算のメリット ビット演算自体が高速 回路が単純なので,プロセッサによる誤差が小さい 1回の演算でビット幅分を1度に処理できる(64bit⇒64個の0/1を一括で処理) ビット単位にデータを詰めることで,メモリ使用量が減る ⇒キャッシュヒット率が向上 25
  27. 27. 故障シミュレータ(最適化) • ビット論理和 OR(C言語:|) • ビット論理積 AND(C言語:&) • ビット排他的論理和 XOR(C言語:^) • ビット否定 NOT(C言語:~) 26
  28. 28. ループ処理の最適化 27
  29. 29. 故障シミュレータ(最適化) • ループ内連続アクセス(配列のデータ格納方式を考慮) • キャッシュブロック化(データアクセス範囲をキャッシュ容量内へ) 28[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) ❌NG for(i=0;i<n;i++){ a[i][1] = b[i]*c[i]; } ⭕OK for(i=0;i<n;i++){ a[1][i] = b[i]*c[i]; } ❌NG for(i=0;i<n;i++){ for(j=0;j<n;j++){ a[i][j] = b[j]*c[j]; }} ⭕OK for(jb=0;jb<n;jb+=m){ for(i=0;i<n;i++){ for(j=jb;j<jb+m;j++){ a[i][j] = b[j]*c[j]; }}} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 j i A[i][j] 格納方向
  30. 30. 故障シミュレータ(最適化) • 行列積において 1. ループ交換法 連続アクセスの方向を変える 2. ブロック化(タイリング法) キャッシュにあるデータを再利用 29[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) for(i=0; i<n; i++) { for(j=0; j<n; j++) { for(k=0; k<n; k++) { c[i][j] = c[i][j] + a[i][k] * b[k][j]; }}}
  31. 31. 故障シミュレータ(最適化) • 行列積において 行列データへのアクセスパターンより3種類に分類可能 1. 内積形式(最内ループのアクセスパターンがベクトルの内積と同等) 2. 外積形式(最内ループのアクセスパターンがベクトルの外積と同等) 3. 中間積形式(内積と外積の中間) 1,2,3全てにおいて列方向アクセスがある ⇒C言語の格納方式を考えると不向き 1において列方向のアクセスを行方向へ転置できると良い 30[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf)
  32. 32. 故障シミュレータ(最適化) • ループアンローリング レジスタへのデータの割当、パイプライニングがよりできるように 1. k-ループ2段展開⇒k-ループのループ判定回数が1/2に 2. j-ループ2段展開⇒A[i][k]をレジスタに置き,高速にアクセス可能 31[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) for (i=0; i<n; i++) { for (j=0; j<n; j++) { for (k=0; k<n; k+=2){ C[i][j] += A[i][k] *B[k][j] + A[i][k+1]*B[k+1][j]; }}} for (i=0; i<n; i++) { for (j=0; j<n; j+=2) { for (k=0; k<n; k++) { C[i][j] += A[i][k] *B[k][j]; C[i][j+1] += A[i][k] *B[k][j+1]; }}}
  33. 33. 故障シミュレータ(最適化) • キャッシュライン衝突とは 1. メモリ→キャッシュの回線が常に稼働 (メモリのバンクからキャッシュラインへ) 2. メモリからデータを逐次で読み出す状態 (キャッシュがない状態と同等) 3. 演算器にデータが届かず,計算を中断 (演算器の利用効率が悪くなる) • メモリ・インターリービング 物理的なメモリの格納方向に従いアクセス時 データアクセス時、現在アクセス中のバンク上のデータは、 周辺バンク上のデータも一括して(同時に)、 別のキャッシュライン上に乗せるハードウェア機能がある ⇒物理的なデータ格納方向に連続アクセスするとよい 32[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf)
  34. 34. 故障シミュレータ(最適化) • キャッシュライン衝突 メモリバンクのキャッシュラインへの割付は2冪の間隔が多い ⇒2冪サイズでの配列確保は避ける • 回避法 1. パディング法 配列に(2冪でない)余分な領域を確保 2. データ圧縮法 計算に必要なデータのみキャッシュライン衝突しないようにデータを確保 かつ,必要なデータをコピー 3. 予測計算法 キャッシュライン衝突が起こる回数を予測するルーチンを埋め込み, そのルーチンを配列確保時に呼ぶ 33[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf)
  35. 35. 故障シミュレータ(最適化) • ブロック化によるアクセスの局所化について • キャッシュには大きさがある 大きさを超えると、キャッシュからデータは追い出される ゆえに以下が必要 1. キャッシュサイズ限界までデータを詰め込む 2. 詰め込んだキャッシュ上のデータを何度もアクセスして再利用 34[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf)
  36. 36. 故障シミュレータ(最適化) 1. キャッシュブロック化なし 2. キャッシュブロック化あり(nがブロック幅(ibl=16)で割り切れるとき) 35[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) for(i=0; i<n; i++) { for(j=0; j<n; j++) { for(k=0; k<n; k++) { C[ i ][ j ] += A[ i ][ k ] * B[ k][ j ]; }}} ibl = 16; for ( ib=0; ib<n; ib+=ibl ) { for ( jb=0; jb<n; jb+=ibl ) { for ( kb=0; kb<n; kb+=ibl ) { for ( i=ib; i<ib+ibl; i++ ) { for ( j=jb; j<jb+ibl; j++ ) { for ( k=kb; k<kb+ibl; k++ ) { C[i][j] += A[i][k] * B[k][j]; } } } } } }
  37. 37. 故障シミュレータ(最適化) 3. キャッシュブロック化+アンローリング 36[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) ibl = 16; for (ib=0; ib<n; ib+=ibl) { for (jb=0; jb<n; jb+=ibl) { for (kb=0; kb<n; kb+=ibl) { for (i=ib; i<ib+ibl; i+=2) { for (j=jb; j<jb+ibl; j+=2) { for (k=kb; k<kb+ibl; k++) { C[i][j] += A[i][k] * B[k][j]; C[i+1][j] += A[i+1][k] * B[k][j]; C[i][j+1] += A[i][k] * B[k][j+1]; C[i+1][j+1] += A[i+1][k] * B[k][j+1]; }}}}}}
  38. 38. アセンブラを用いた最適化 37
  39. 39. 故障シミュレータ(最適化) 38 このコードをコンパイルする
  40. 40. 故障シミュレータ(最適化) -O0 -O2 39 • 最適化オプションなしの場合, 無駄な処理でもそのまま • 最適化オプションありの場合, 無駄な処理は省く
  41. 41. 故障シミュレータ(最適化) インクリメンタルforループ do-while 40
  42. 42. 故障シミュレータ(最適化) インクリメンタルforループ do-while 41 同じ処理でも書き方によって, 命令数が異なる ⇒命令数が少なるように
  43. 43. 故障シミュレータ(最適化) 一部の処理をアセンブラ化(インラインアセンブラ) 以下はアドレスからメモリを参照するサンプルプログラム 42 実行結果 $ ./a.out v1=100, x2=10
  44. 44. 細かな最適化 43
  45. 45. 故障シミュレータ(最適化) • 共通部分式の削除 • 割り算は演算時間がかかる⇒掛け算へ • なるべくループ中にIF文は書かない • 値渡しとポインタ渡しを使い分ける 44[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) ❌NG d = a + b +c; f = d + a + b; ⭕OK temp = a + b; d = temp +c; f = d + temp;
  46. 46. 故障シミュレータ(最適化) • ソフトウェア・パイプライニングの強化 定義と参照の距離がなるべく遠くなるように 45[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) ❌NG for (i=0; i<n; i+=2) { dtmpb0 = b[i]; dtmpc0 = c[i]; dtmpa0 = dtmpb0 + dtmpc0; a[i] = dtmpa0; dtmpb1 = b[i+1]; dtmpc1 = c[i+1]; dtmpa1 = dtmpb1 + dtmpc1; a[i+1] = dtmpa1; } ⭕OK for (i=0; i<n; i+=2) { dtmpb0 = b[i]; dtmpb1 = b[i+1]; dtmpc0 = c[i]; dtmpc1 = c[i+1]; dtmpa0 = dtmpb0 + dtmpc0; dtmpa1 = dtmpb1 + dtmpc1; a[i] = dtmpa0; a[i+1] = dtmpa1; }
  47. 47. 故障シミュレータ(最適化) • データ構造をSoAに変更 AoS(Array of Structs; 構造体の配列)よりも SoA(Struct of Arrays; 配列の構造体)の方が高速に動作する可能性がある 46[プログラム高速化の基礎](https://www.cc.u-tokyo.ac.jp/events/lectures/X01/shiryou-1.pdf) • AoS struct data { int a, b, c; double x, y, z; } d_ary[SIZE]; • SoA struct data { int a[SIZE], b[SIZE], c[SIZE]; double x[SIZE], y[SIZE], z[SIZE]; } d_ary; a[0] b[0] c[0] x[0] y[0] z[0] a[1] b[1] c[1] x[1] …a[0] a[1] … b[0] b[1] … c[0] c[1] … x[0] x[1] … y[0] y[1] … z[0] z[1] … ※SoAのデメリットとして、キャッシュラインを使い尽くす場合がある ⇒SoAとAoSの適切なハイブリッド構造にすること (Ex.頻繁に同時にアクセスする要素を1つの構造体にする)
  48. 48. 故障シミュレータ(最適化) • OpenMPを用いたスレッド並列化 ⇒今回は配列の加算や乗算が多いので,割と有効(MPIに比べると実装が楽なので効率が良い) OpenMPの並列化の効率はコンパイラに依存 ⇒MPI(並列実装の1つ)と比較するとチューニングによる性能改善が小さい OpenMPはメモリアクセスのローカリティが低くなる傾向 ⇒頻繁なメモリアクセスがあるプログラムではOpenMPは遅くなる • GCC 4.4だとOpenMP3.0 (gcc -fopenmp) 以下のようにヘッダとfor文にディレクティブを記述するだけで並列化可能 47[OpenMP Application](https://www.openmp.org/wp-content/uploads/spec30.pdf) #include<omp.h> #pragma omp parallel for for(i=0;i<1000;i++){ a[i] = i; b[i] = 1; c[i] = a[i] + b[i]; }
  49. 49. 故障シミュレータ(最適化) • 結論 最適化としてはまずはコンパイラオプションを使え (今回は使ってないですよ?) ∵最適化コストが手作業だととても効率が悪い とりあえずはO2を使う それでも足りない場合はO3,Ofastを使ってみる あとmtune,march,mfpmathの併用もおすすめ コンパイラを信じろ 48
  50. 50. 結果 回路名 実行時間(s) e432 0.004 e499 0.005 e880 0.010 e1355 0.017 e1908 0.036 e2670 0.041 e3540 0.059 e5315 0.069 e6288 0.113 e7552 0.167 49
  51. 51. 結果 回路名 実行時間(s) cs9234 0.088 cs13207 0.112 cs15850 0.107 cs35932 0.174 cs38417 0.261 cs38584 0.304 e平均 0.052 cs平均 0.174 回路平均 0.098 50

×