RAII

投稿者: | 2018年4月3日

我々の大気大循環モデルは,並列コンピュータで動作するように作られています。並列コンピュータは複数のコンピュータをネットワークで接続したものです。複数のコンピュータに計算を割り当てて,計算を速く終わらせようというわけです。分割数を変えると結果が変わってしまうという奇妙な現象が見つかりました。原因を探したところ,ある配列に値を適切に与えていないためであることが判明しました。

配列は数値を多数格納しておく入れ物で,大気大循環モデルの中ではたくさん使われています。配列には番号が付いていますので,順番に1, 2, 3と配列の大きさまで繰り返して各要素を0にしてから計算した結果を入れるつもりでした。ところが順番を数えるループ(繰り返し)の外で配列の要素の一つだけ0にしていました。初期化をループの中ですることで全ての要素が確実に初期化され,バグ(プログラムのミス)は修正されました。元どおり分割数を変えても結果が変わらなくなりました。

なぜ配列をそのまま使ってはいけないのでしょうか。値を入れる左辺に使うなら,右辺の計算結果で上書きされるので構わないのですが,右辺に使うと問題が起こります。コンピュータの中で配列はメモリに確保されます。確保した時点ではどんなデータが入っているか分かりません。使う権利だけもらった状態です。土地に例えると,古い建物があるかもしれないし,雑草がぼうぼうに伸びているかもしれません。その土地を耕して作物を育てたり,家を建てたりするには更地にしたり草刈りをしたりする必要がありますね。もらったばかりのメモリ上の値をそのまま計算に使うと,変な数値だったり,数値ですらないデータだったりして,意図しない計算結果になる可能性があります。そこで,0などに初期化する必要があるというわけです。

このようなバグは,「RAII」という合言葉を実践することで防ぐことができます。「RAII」とはresource acquisition is initialization(資源取得と同時に初期化)という意味です。プログラム中では使うところで0にしていますが,配列を確保した時点で初期化していれば,使う時点では安全使うことができます。残念ながら我々の大気大循環モデルでは,この合言葉は徹底されていません。

RAIIは日常生活でも役立つ合言葉だと思います。買ったものが紙袋のまま,宅配されたものが段ボールに入ったまま何日も放置されていませんか。入手したらすぐに使える状態に準備しておくと有効活用できます。RAIIという言葉の中には入っていませんが,使う場面が過ぎたら確保されたメモリを返却するということも概念の中には含まれています。使わなくなったら片付けることも重要ですね。