アトミック

このふたつの例はそんなにとっぴなものじゃない。知ってりゃわかる話だし、初心者が始めてぶちあたったとしても、Cのコードと見比べながらちゃんと調べればわかる。まぁ除算器使わないという決断をコンパイラが下すという部分は最適化の機構が働いているんだろうけど、"なめてんのか?"といわれるほど恐いもんじゃない。末尾最適化なんかのごついのはまぁ置いとくとして、メモリアクセスの減少とかパイプライン動作を考慮したアセンブリ命令の順序の置き換えなんかのほうがデバグ時に障害となる可能性が大きいです。

いや、やってみりゃそんなに大変なもんじゃないって。だからやっといた方がいいんだよ。

んー、アセンブリ命令ってのはインストラクションのことで、末尾最適化というのは末尾再帰の最適化のことかな。
末尾再帰最適化なんてそれこそたいしたことないと思うけど、この例がたいしたこと無いのはその通りで、実際問題として大変なのはもとのコードと機械語の命令が1対1対応するわけではないことだったりする。で、その場合に生成されるコードを想像してデバッグしないといけない状態ってなんなんでしょ。排他制御はまさにそういう例だとは思うけど、こういうバッドノウハウ的なコード生成は関係なくて、要するにどういう処理がアトミックにできるのかという話だよね、多分。ということで、「生成されるコードを想像できないといけない」というのは言いすぎだと思うのだ。C より抽象度の高い言語(たとえば Haskell) の場合とかになると、もう無理な気がするし。

新人君とかに"なんでたった1行のインクリメント文をセマフォでガードしなきゃいけないんですか?"と聞かれたときは、アセンブリレベルの話をするのが一番的確で一番簡単だと思うんだけど、他になんかいい説明方法ありますかね?もしアイデアあるようであれば真剣に知りたいです。

Java でも排他制御の必要はあるけど、それはレジスタが、機械語がというレベルでは説明できないし、synchronized、volatile について理解する必要がある*1よね。
たとえば、この例でいうと「共有変数へのアクセスはアトミックに行うか、排他制御する必要がある」ということと、「インクリメントは読み出し、加算、書き込みを伴う処理でアトミックではない」ということを理解させればいいんじゃないかなぁ。いや、もちろん機械語レベルの知識があるならそれで説明するのが手っ取り早いだろうけど。
あと、shiro さんのコメントを読んで気づいたんだけど、もしかして一部の人は無意識的に CISC プロセッサを前提にしているんじゃないだろうか。いや、もしかしてバイナリアンな人たちは RISC でもすいすいと読むのかな。
まぁ、なんというかモデルとしてコンピュータでの命令実行がどうなっているのか、という話は知っておいてしかるべきだとは思うんだけど、実装の泥臭いところまで知っているべきというのは、なんか違うと思うんだよね。

*1:C に関してはそういう目的での volatile は役に立たないけど