マルチコア時代のソフトウェア開発


シングルコアで最速を目指す時代は終わっている

15年前くらいか…Intel Core 2 Duoが出てきてから、CPUのマルチコア化が加速した。
一方でNVIDIAがCUDAを打ち出し、グラフィックボードのGPGPU分野で先を越されたAMDなどが主導でOpenCLを策定していった。Streaming Processor (SP)ごとにデータを同時に処理できるところがGPGPUの強み。SP数はCPUのコア数と比較にならないくらい多い。

もっと前は…Intelは爆熱と叩かれたPentium D、マルチコア先駆者AMDはAthron64 X2を投入していて、マルチコアはあるにはあったけど、ベンチマーク対決ではシングルコア至上主義が一般的だった。
それまでのソフトウェア開発も同じで、シングルコアで効率よく処理できるかが主流。
実際、その時代のソフトは1コア分しか使っていない。

GPGPUが出てきてから一変したのは「AES128は弱い」「WEPは危険」など、既存の暗号化強度が弱いということ。
当時、暗号化の機能開発をしていたので、より印象深く覚えている。

これより前にも、複数CPUによるマルチプロセッサーはあったけど、費用対効果はGPGPUの比じゃない。
GPGPUはグラフィックボードを積んでいれば、一般のPCでも使えるから。
一般人がzipの暗号化解読するまで数時間に…暗号化の意味がないよねって話。

GPGPUを用いた暗号攻撃 – IEICE
https://www.ieice.org/publications/conference-FIT-DVDs/FIT2009/pdf/L/L_010.pdf

でも、未だにパスワード信者は「複雑で長いパスワードを設定すれば大丈夫」くらいに思っているのが残念な感じ。
暗号化強度は解読に要する時間が基準になっていることを忘れては駄目。
「何百年もかかるから大丈夫」なんていうのは、あくまで現時点での技術上の話でしかないという良い見本だったのだけど。

現在進行形で暗号化とクラックはイタチごっこを続けている訳だけど、背景にはCPUのマルチコア化やグラフィックボードのGPGPUがあり、それらのリソースを生かしたソフトウェア開発が行われていたことを留意しておく。

あと、大半のプログラマーはどんな言語で書いても、最終的にハードウェアで処理でされていることを意識した方がいい。

ネットワークの高速化と分散コンピューティングが当たり前の時代

インターネットは普及したし、ネットワーク速度はGbpsは当たり前となって、複数コンピューターによる分散ができるようになった。

分散コンピューティングは基本的にジョブ単位で割り当てられるので、インフラ次第なのもある。
ここでは、コンピューター1台あたりの処理速度向上について書く。

自動的に最適な形で動いてくれる訳ではない

古くからある言語(C/C++、Javaなど)はシングルコアが前提となっていて、マルチコアで処理するためにはスレッドを起動してOSで並列化させないと駄目。
でも、それが設計者の意図する形になっているかはコンパイラーやインタプリターに委ねられている。
おまけに、何も考えずにスレッドを起動していると、そのオーバーヘッドで逆に悪化したりもするような代物。

任せるのではなく、意図した並列化ができるように.NETのParallel、MATLABは専用プラグインのようなものがあった。

Goはスレッドと異なる思想のゴールーチンやチャンネルで上手く分けてくれる。ここはGoの強み。それでも最適化は必要。

コア単位でどのようにデータやタスクを分割するか

オライリー 並行コンピューティング技法

発売後、まもなく買った本。
データに対する考え方、タスクに対する考え方など要点がよくまとめられている。

本を読む前はUNIXのpthreadでマルチスレッドは経験済みで、動作を頭の中でシミュレーションできていたレベル。
それでも、考え方に不足していたところはあった。
読んだ後は「シーケンシャル依存を外せないか」「データを上手く分割できないか」などを考えながら作れるようになったのが大きい。

OpenMPに触れたのも、このタイミング。
使用していたC/C++コンパイラの都合でSIMD部分をアセンブリで記述していたものの、デュアルコアで1.9倍近いパフォーマンスにまで上げられたので良い結果を得られた。

シングルコア時代では良しとされていたものもマルチコア時代では通用しない。マルチコアと言っても、big.LITTLEに対するOSのアプローチ次第でアプリケーション開発は変わりそう。
未だに、マルチコアを意識したプログラミングをできる人って少ない印象だから、もっと勉強するのが良いと思う。