2023年3月31日金曜日
証明作法を読んで
2023年2月15日水曜日
プログラマーのためのCPU入門を読んで
プログラマーのためのCPU入門を読みました.
この書籍は,ゲームの土台となるシステムを作っているプログラマーには是非とも読んでもらいたい内容となっています.書いてある内容は10年以上ゲーム業界にいると聞いたことがあったりする内容が多いです.つまり,この本を読むことで何年もかけて学んだような知識を得ることが出来るわけです.
昨今は,ゲーム業界でも専門化が進み,新卒で入社してくる社員には物理学だったり数学だったりの専門家ではあるけれど,情報の教育は受けていない,というような人もいたりします.そういった方たちに高速に動くコードを書いてもらうための助けにもなることでしょう.
第1章では,CPUが命令を順次処理していくことに触れられています.この辺は基本的な知識として是非知っておいてもらいたいレベルですね.
そして,第2章ではパイプラインやスーパースカラなどによって並列実行をすることで高速に実行できるようにすることを解説しています.まずここが分かっていないと,例えばif文は遅いといった話をしても通じないことでしょう.
実際,最近パイプラインという言葉さえも通じないことがあったのでこの書籍を紹介しました.
第3章はデータ依存関係で,例えばある計算の結果を次の計算で使う,というような依存関係がある場合にパイプラインが上手く詰まらず効率が下がるということが解説されています.そのため,実行順序を変更したりして解消することを解説しています.
また,学生時代だと計算量などの話をする場合にはどの処理も一律で扱っていることもあったでしょうが,処理によっては必要な時間が違う,といった話も出ています.これをレイテンシといって,計測するためのサンプルも用意されています.
第4章では,if文のような分岐命令について触れています.分岐は遅い,という話を聞いたことがあるかもしれませんが,これもパイプラインに関係していて,この章を読めば何故遅いのかが理解できることでしょう.
第5章では,キャッシュについて触れています.正直なところ,キャッシュまで考慮して高速化するようなことは,よっぽど中心部分を実装しているような人でないと必要が無いかもしれません.昨今のようにゲームエンジンを利用する場合であればなおさらです.でも,プロファイラなどを見る場合にキャッシュミスが多いというのはどういう意味なのか,といったことを理解するためにも,こういった知識は必要でしょう.
レンダリングプログラマはキャッシュがどうのとしょっちゅう言っている気がします.
第6章では,仮想記憶,特にアドレス変換周りについて触れています.内容としては若干キャッシュの話と近い部分もありつつ,そもそも仮想記憶が当たり前すぎて仮想記憶とは何か分かってない,という方も増えてきているので読んで損はないでしょう.
第7章では,I/O (input / output)について触れます.例えばマウスとかキーボードとかですね.ゲームだとコントローラなんかも含まれます.I/Oは遅いというのはよく聞くんですが,省電力とかコストの関係で意図的に遅くしている,という話は面白かったです.
昔のゲーム専用機のコントローラは今より速かったらしく,ゲームを移植したら反応が遅いってなって,原因を調べると,そもそもコントローラが遅くなっていた,なんてこともありました.
第8章は,システムコールなどOSの機能に関係する部分です.この辺まで考慮するのは本当に根本の部分を担当する人たちだと思いますが,例えばファイルオープンは結構時間がかかるので,複数のデータをまとめてファイルオープンを減らすとか,システムコールが必要な同期の仕組みを減らして速度を上げるといったことは実際に行われているので,何故こんなことをしているのだろう,と思ったときのヒントになることでしょう.
第9章はマルチプロセッサについてです.ここまでくると,ソフトウェアのそもそもの設計なんかが複数のプロセッサを生かせるようになっていないと難しい,というような話になってきます.ゲームなんかは,元々複数の要素を並列で動かして高速化するといったことをしてきているので,この辺は既にフレームワークとして設計に組み込まれているかもしれません.
第10章は,キャッシュコヒーレンス制御です.これは,複数のプロセッサが別々に持っているキャッシュの内容が一致しているようにする,という話です.確実に一致する状態を保とうとすると処理速度が落ちます.実際,その設定をしていたせいで遊べたものではない状態になったことがあります.そう,設定を一か所変えるだけで劇的に改善されたんです.
かといって,場合によってはプロセッサによっては違う値を取ってくるというのは,それはそれでよく分からない問題を引き起こしたりします.
実際にそういったことが起きないように対処するのはシステムの根本を作ってくれている人たちが対応してくれると思いますが,そういったことが起こるってことくらいは知っていて損は無いと思います.
第11章は,メモリオーダーとかメモリ順序付けと言われるものを解説しています.これはこれでやっかいな話で,コード上は順番に書いているのに,実際には違う順序で実行されたりアクセスされた結果,条件が成立したのに成立していないとか謎な状態になったりします.今時のゲームは並列処理が基本でこういった問題もちょくちょく発生しているので,是非とも押さえておいた方が良いでしょう.
第12章は,アトミックとか不可分操作と言われるものを解説しています.CASとかロックフリーとか聞いたことがあるかもしれません.例えば,キューを並列でアクセスすると簡単にクラッシュします.そういったことを防ぐためにも必要な知識なので,是非押さえておきたいところです.
第13章はまとめとして高速なソフトウェアを書く際に注目する点を解説しています.そのあとには,様々な参考文献もまとまっています.
多くの章には簡単な実験で速度の低下や効率化が確認できるコードが付いています.ただし,Linuxを前提としているので,そういった環境を用意できない方はご注意ください.
最後まで書いて,新人への課題図書にしても良いんじゃないかなと思いました.
2023年1月4日水曜日
継続的デリバリーのソフトウェア工学の感想
継続的デリバリーの,となっていますが,読んだ限りでは元のタイトルのModern Software Engineeringを実現する方法として継続的デリバリーも推している,という感じなのかな,という気がします.
序文では,この書籍は次のようなものだと述べています.
ソフトウェア工学に工学を取り戻す試み
つまり,現在のソフトウェア工学は工学になっていない,ということです.正確には,皆が誤解しているというところなのだと思います.実際,この書籍で紹介される多くの概念は過去に提唱されてきたものがほとんどです.
そのための流れとして,まず科学と工学の違い,そしてソフトウェア工学とはどうあるべきなのかが定義されます.そして,工学であるために必要となる学習と複雑さの管理 について説明し,最後にそれらのためのツールというかアイデアを紹介しています.
この書籍が良いところは,既に様々な書籍で紹介されているアイデアを整理し,それらがどう関係しあって良い結果をもたらすのか,ということが具体例も交えつつ解説されている点です.
例えば,テスト駆動開発(Test Driven Development, TDD)を用いると,疎結合な設計になりやすいであるとか,関心事の分離により変更が容易になるとかです.
TDDや継続的インテグレーション(Continuous Integration, CI),継続的デリバリー(Coninuous Delivery, CD)などは,良い設計をする方向への圧力となるのだと.
また,プログラマはどうしても個々人のレベルアップによる開発を夢見がちですが,それでは大規模化が困難であることにも触れています.ある程度の規模のソフトウェア開発に関わっている人ほど,その点については何となくでも気付いていると思います.
TDDとなると,どうしてもテストを書くのが面倒だと言う人は多いのではないでしょうか? しかし,この書籍を読めば,何故TDDが必要なのか,単純に単体テストではダメなのか,という質問をされた場合に返答できるようになると思います.
雑に要約すると,TDDでのテストは仕様を記述しているのであって,バグを検出することが第一の目的ではない,ということです.
他にも色々とありますが,この書籍ではTDDやCI,CD,他にはマイクロサービスやDevOpsなどによってもたらされる利点が語られていますが,そのものについては既知のものとして詳しく触れてはいません.
1つか2つソフトウェアの開発経験を積んだ後,まずはこの書籍を読み,知らない概念についてはそれぞれの参考文献を読む,という読み方をするのが良いと思います.