現在,『Write Great Code〈Vol.1〉ハードウェアを知り、ソフトウェアを書く』を読んでいます。全部で12章構成ですが,何ヶ月もかけて,やっと,第11章の「メモリのアーキテクチャの構成」まで読み進めてきました。
「11.8 メモリ階層を意識したソフトウェアの作成」の中に,
悪い設計の代表例が,整数値の2次元配列を初期化する次のようなループです。
(途中略)
信じられないような話ですが,現在のCPUでは,このコードの実行速度は次のコードと比べてはるかに劣ります。
とあります。両者(以下,サンプル参照)を見ると,効率が良い/悪いのは分かるのですが,さすがに"はるかに"と書かれていると試してみたくなりました。
以下がサンプルです。良い例と悪い例の違いは,array[i][j] か array[j][i] の違いだけです。
#include <stdio.h> #ifndef SIZE # define SIZE 256 #endif int main(void) { int array[SIZE][SIZE]; int i, j; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { #ifdef GOOD array[i][j] = i * j; /* 良い例 */ #else array[j][i] = i * j; /* 悪い例 */ #endif } } return 0; }
実験
環境は,
- Mac OS X 10.5.6
- 2.4GHz Intel Core 2 Duo
- 2 GB 667 MHz DDR2 SDRAM
です。
bench.rb
require 'benchmark' Benchmark.bm(7) do |x| x.report("good_case:") { system('./good_case') } x.report("bad_base :") { system('./bad_case') } end
計測してみます。
$ ruby bench.rb
user system total real
good_case: 0.000000 0.000000 0.000000 ( 0.013505)
bad_base : 0.000000 0.000000 0.060000 ( 0.059739)
計測結果を見ると,4.4倍くらいの速度の差が見られました。
本書について
まだ読み終わっていませんが,少し感想を書いておきます。
この本を読み進めてきて良かったと思うことは,今まで自分の知識が体系化されず,点として散らばっていた感じだったのが,本書を読むことによって,線で結ばれ体系化されつつあると感じることです。
もっと若い時期に本書に出会っていたら,と思ってしまいます。
もっとも面白いと感じたのは,「第10章 命令セットアーキテクチャ」でしょうか。"Y86仮想プロセッサ"という仮想的なプロセッサに,命令セット設計をしていく過程が興味深いものでした。