猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

言語のしくみ その5

 言語設計者はCPUの内部構造まで意識しないといけないとか、大変ですね...。(>_<)

2-6 キャッシュとシンボル

キャッシュの有効活用

 どれだけ効率的にキャッシュを利用できるかで、CPUの性能は50倍程度は異なる。

 コア間で共有するキャッシュ上のデータの書き換えが発生すると、メモリ上のデータにも書き戻しが発生し、さらにコア毎に固有のL1$の無効化と再読み込みが発生する。いかにキャッシュを効率的に利用するかは難しい*1

 Streemに関して言えば、なるべく同一パイプラインのタスクは同一コア(同一スレッド)上に割り当てるのが、最も高速になる。

  • CPU:1クロック
  • L1$:4クロック(コア毎に独立)
  • L2$:10クロック(複数コア間で共有)
  • L3$:40〜100クロック(複数コア間で共有)
  • mem:200クロック
  • HDD:2000万クロック
シンボルの扱い

Rubyには「シンボル」というデータ型が存在し、変数名や識別子などを表す型で名前をもつ。シンボルと文字列の違いは以下の通り:

  • 同じ名前をもつシンボルは1つしかない(⇄同じ名前をもつ文字列は複数存在する)
  • シンボルは内容が変更できない(⇄文字列は変更できる)
  • 上記の理由で一致判定が高速

Rubyではこの比較の高速性を利用して、メソッド名・変数名の指定やキーワード引数、マップのキーなどにシンボルを用いている。

*1:コンピュータサイエンスにおける難題は2つ。キャッシュの無効化と名前付けだ」という格言があるらしい。確かにプログラム中に適切な変数名をつけるのはすごく難しい。