ソフトウェア技術者は、ハードウェア設計技法を学ぶべきだと思います

通常の動作テストでは発見困難なバグとして、複数のスレッドによるリソースの競合や、レース状態が挙げられる。これらの問題は、結果的に起こってみないとわからないし、起こってしまえば原因を突き止めることは難しくない。
マルチスレッドにまつわる問題の多くは、設計者やプログラマの経験不足*1が原因だと思っている。
最近、ハードウェア設計者と少しだけ話をする機会があった。そのとき感じたことは、明らかに検証という分野においては、ソフトウェアはハードウェアに対して、遅れをとっている。物理的な制約が存在するハードウェアは、ソフトウェアに対して検証のモデルを構築しやすいことや、もともと非同期並列やデバイス依存の動作のバラつきが存在すること、また不具合修正のコストが全体的に大きかったことが、検証という分野を発展せざるをえなかった理由だと思っている。
それに対しソフトウェアは、その基本的な動作は決定的であるため、どれもまったく同じ動作をし、適当に作っても比較的適当に動いてしまう。
いま、ソフトウェア開発者の中で、開発中のプログラム内の全てのスレッドを把握し、それらが舐めるコードの1ステップ1ステップに対し、一瞬でも被ってしまうがために不具合が発生するというバグを意識しながら、設計やコーディングを行っているという方は、多くないと思う。ましてや、多くに人員を投入するプロジェクトでは、完全に分業体制が確立されており、全てのコード*2を把握している者は、まずいない*3。1年以下の案件ですら、キロ・ステップ単位ではなく、メガ・ステップ単位のコードが開発される現状で、いったい誰が全てのコード*4を把握できるでしょうか。
そんな世界で活きてくるのが、検証技術だと思います。
もちろん、ハードウェアに対して自由度の大きいソフトウェアでは、規模の大きいシステムに対し形式的検証など望むまでもなく、実現することは非常に困難です。テスト項目とテストパターンによる半しらみつぶし作戦で、信頼性を上げるしかありません。
しかし、マルチスレッドを用いたプログラムでは、この半しらみつぶし大作戦だけでは、バグは普通に通り抜けてしまいます。そのため、これらは事後に発見するんどえはなく、設計・コーディング段階で未然に防がなければなりません。
そこで、私は思います。複数のスレッドを走らせたとき、どの部分で問題が発生するかを、コードを読むだけで目星がついてしまうという、よく分からない得意技をこの3年間で身に着けました。危ないところは匂いがする*5、という感じです。
この良くわからない特技は、非同期回路の開発を通して身に付いたと最近思っています。非同期回路では、至る所にレースが発生する可能性*6があり、脳内シミュレーションで可能な限り排除しなければなりません。
この、脳内シミュレーションで排除するという行動が、不具合の少ない設計やコーディングに効いてくるのではないか。そんな考えの下、ソフトウェア技術者も、ハードウェア設計の経験を持つべきではないかと、最近思うようになりました。
以上です。

*1:悪いけど言い切らせてもらう。酔いどれだし

*2:プログラムは設計どおりに動くのではなく、コードとして記述されたとおりに動きます

*3:ここでも言い切ります

*4:設計じゃありません

*5:正確には、どのようにすれば発見できるかという技術は存在します。それを駆使すれば、かなり容易に発見できます。

*6:開発方法論によりますが、プリミティブに落としていくと、基本的には発生すると考えています