ユユユユユ

webエンジニアです

CS:APP を読み終えた

f:id:jnsato:20210806222526j:plain

CS:APP を読みはじめる」という記事を書いてから足掛け3ヶ月にして、読了に漕ぎつけた。案外ペースとしては悪くない。各章末に配された練習問題はスキップする方針で読んだ。平日には長くても1時間、週末には気が向く範囲で数時間といったくらいの時間を割り当てて、読み通した。少なくとも数十時間はつぎこんでいる。まあ大作ビデオゲームをそこそこ楽しく遊んだくらいのものとおもうと、そうたいしたものでもないか。読みながら「ここは」とおもった折にメモを残していたので、それを書き写そう。


 第4章、パイプラインプロセッサの設計のところがまず難関であった。途中から完全に(なにもわからない)という状態になり、とりあえず話を目でなぞってお茶を濁すことにした。それまでの議論はそれなりに追従できていたはずなのだが、にわかに力技の議論で押し通されるようになったゆえに置いてきぼりにされてしまったのかもと疑ってはいる。論の運びがパワフルなところが美点でも欠点でもある、とは訳者序文にても指摘されていた。まあ、 CPU はパイプライン化により高速化を図っており、それを補助するためにストールとかフォワーディングといった実装がある、というところを知識として持てただけでよしとしよう。実装の詳細については、また機会があったときに再訪すればよい。


 第9章、仮想メモリの話もタフだった。とりわけ、アロケータの実装を「簡単に」といいつつ詳解していく手際には置いていかれるよりなかった。もっとも、実装レベルで学ぶことを目的とせずに読んでいたこちらの怠惰が跳ね返されただけともいえる。仮想アドレシングの手続きはハードウェア層から OS までが相互に協調して最適化を与えているというあたり、「すごい技術だ...」と呆然とするほかなかった。「システムはモジュラーであるべき」というドグマがいっぽうにありつつ、ここぞというところでは結合を密にすることで速度をあがなうということは理解はできる。しかしアドレス参照というスーパークリティカルなシステムを動かすにあたってハードウェアと OS が共依存関係を構成していること、そしてそれがメモリ階層のシステムや追加のキャッシュもあわせて素晴らしいコレオグラフを描き出していることに感動した。ほんのすこしだけ表面をなぞったにすぎないわけではあるが、強く印象に刻まれた。


 など、困難を感じたところのメモから書き起こした。相対的に、残りの章については印象が薄かったかのような誤解を与えかねない。ところが事実は、すべての章がいちいち素晴らしい学びに満ちていて、とても整理しきれないのである。二進数表現のありきたりな話からはじまって、「そんなことは知ってるよ...」とこちらを飽きさせる暇もなく、浮動小数点のエンコード方式のような、いままでわかったようで実はわかっていなかったトピックを叩きこまれた。さらにそれらの演算命令がどのように機械語エンコードされるかをみたかとおもうと、最適化コンパイラの設計思想とその最適化の限界を暴き出してみせ、キャッシュメモリの階層化の説明を付け加えることによって、「プログラマの視点から」どのようにハードウェアをコントロールして最高のパフォーマンスをチューニングするかを鮮やかに描きだす。凄まじい熱量をもって議論が展開していくのを眺めるのは実に気持ちがいい。

 さらに高レベルに議論は進み、リンカの話、カーネルの例外制御の話がはじまる。仮想メモリやシステムレベルI/Oの話題となると、ハードウェアとソフトウェアの相互作用が語られるようになり、これも描写しがたいおもしろさだ。「ネットワークはデバイスである」という表現の意味がわかっていなかったのだが、ファイルデスクリプタという概念をおよそ理解できたことで、それも乗り越えられたようにおもう。初学者のころにソケットというものの意味がなにもわからずに退けていたことを思い出しながら読んだ。

 ひとつひとつ数え上げては感想を述べても飽きないが、それでもなお未知の部分が残っていることに疑いはない。わかった気になれているのは、僕の想像力が足りずに、わかったようになっているだけともいえる。 Nand2Tetris を読んだうえで CS:APP に進んできて、ハードウェアの世界とソフトウェアの世界の接合部についてはかなり手応えをもって知ることができたようにおもう。しかしそれでもなお、せいぜい学びの第一歩を踏み出したにすぎないこともはっきりと理解している。「なにがわからないかわからない」という状態であったところをひとまず脱して、コンピュータアーキテクチャの概略をおおむねマッピングできた、というあたりに自分を位置付けている。

 各章末に配された「書誌ノート」も卓越している。トピックごとに、読むべき古典を提示してくれている。正しくアカデミックな手続きで書かれており、いつでもここに立ち返って再読し、関連文献をあらためて逍遥することができる。

 一生読める一冊であるから、値段が 16k もしようが、あきらかにその価値はある。翻訳については、いくらかミスも見受けられるが、読める訳文である。こちらに前提知識が欠落しているため、はじめから原著で読むことは、不可能ではないとはいえかなりの時間を要したろう。しかしこの訳書で羅針盤を得たので、後続の学習は英語でも恐れずに進められるようにおもう。

シグナルを送ることで他のプロセスに割り込みをおこなう

シグナルとは、小さなメッセージのようなもので、何らかのイベントがシステム内で発生したことをプロセスに通知するものである1

 ハードウェアレベルで例外が起こるとする。たとえばあるプロセスがゼロ除算エラーを発生させるとする。通常はカーネルがこの例外を補足してハンドルするため、個々のユーザープロセスは個別にハンドラを定義しないし、そうする必要もない。要するに、ユーザープロセスにはこの例外は見えない。

 この種の例外の発生をイベントとして通知して、ユーザープロセスが例外を検出することができるようにするのがシグナルである。ゼロ除算エラーの場合、カーネルは SIGFPE (8) をユーザープロセスに送る。

 シグナルを受信したユーザープロセスは、シグナルを無視したり、実行を終了したり、ユーザー定義のハンドラを実行してシグナルをキャッチすることができる。なにもしない場合、シグナルごとに定義されたデフォルトアクションが実行される。たとえば SIGKILL (9) のデフォルトアクションはプロセスを終了させることである。

 シグナルは、低レベルの例外を検出したカーネルからユーザープロセスに送信されることもあれば、ユーザープロセスからユーザープロセスに送信されることもある。つまり、システムイベントの通知がシグナルとして抽象化された結果として、ユーザーが任意のシグナルを発行して、あたかもあるシステムイベントが発生したかのようにプロセスを制御することも可能にされたわけである。

 シグナルとそのデフォルトアクションのリストは、さまざまなところに掲示されている。ひとまず wikipedia のテーブルをみるのが無難とおもう。

https://en.wikipedia.org/wiki/Signal_(IPC)#Default_action

 たとえば kill コマンドをこうやって使うことは、駆け出しエンジニアのころに意味も知らないままに覚えて、以来無批判に使っている。

kill -9 pid

 引数にあたる -9 は SIGKILL に割り当てられた数字であり、これはプログラムの強制終了を指示するシグナルである。こう書いても同じことを意味することになる。

kill -s KILL pid

 引数 pid に負数を渡すと、プロセスグループに対するシグナル送信とすることができる。手元のマシンの kill のマニュアルにはその記載はなく、試してみてもいないのでわからない。とはいえ使う機会があるかもしれないので知識としてのみ覚えておく。

 unicorn の起動スクリプトに埋め込んでいた HUP や USR2 のシグナルの意味もいまならわかる。

 tablexi/capistrano3-unicorn は QUIT, HUP, USR2, TTIN, TTOU といったシグナルを送信するタスクを定義している2。これらのシグナル群について、 unicorn がシグナルハンドラを提供している3。この仕様に沿ってシグナルを送信することで、プロセスをたとえばグレースフルリスタートさせるような制御をおこなうことができるわけである。

rails/rails にはじめてのコントリビュートをした

rails/rails に初めての PR を出して苦い気持ち と書いていた。結局、そのあと二往復ばかりのレビューのやりとりがあって、無事にマージされた。これでぼくも rails コントリビュータのはしくれといえるだろうか。ふわふわした気分でいる。

rails/rails#42867

みてのとおり、たいしたことをしたわけではない。業務で読み書きするコードのほうがはるかに高い出力を要求される。それはたしかである。

でも、これは誰にやれといわれるでもなく、ぼく自身がやりたいからやった大切な仕事である。それをきちんと成就させられて、こんなにいい気持ちになることをぼくは知らなかった。もっとたくさん、開かれた世界でコードを書いてみたい。自分で自分を満足させられるような仕事をもっとしたい。そういう熱意が燃え上がってやまない...というまでに苛烈ではまだないが、すくなくともその火種になるべき刺激をあたえられている。

そしてそれを活かすも殺すもぼく次第なのである。

rails/rails に初めての PR を出して苦い気持ち

rails レポジトリのイシュー一覧をみていたら、 good first issue のついた手ごろな問題があった。

rails/rails#42862

初コントリビュートのチャンスかとおもって、ドキドキしながらパッチの準備をした。環境を整えて、修正して、テストを動かして、コミット。関連する PR やイシューから情報を取捨選択して、コミットメッセージもできるかぎり丁寧に書いた。「これで大丈夫か?」となんどもダブルチェックをして、提出した。

で、みると2分差で競り負けていた。僕がダブルチェックをしている隙に先を越された。

rails/rails#42866
rails/rails#42867

f:id:jnsato:20210725193437p:plain

競争相手はほとんど同じ変更セットを、最小限の説明文で提出している。こちらが初めての PR 提出であるのに対して、彼はこれまでにいくつかの変更をマージしており、 CI も承認を必要とせずに通っている(初めてのパッチを作成した開発者は CI の実行にメンテナの承認がいるようす)。

これは負けたな、とおもっている。悔しいが、まあまずは提出までをこなせたことでよしとすべきなのだろう。細部に気をつけたせいでスピードで負けるというのはありがちな話であるが、ここにおいては丁寧は明らかに美徳とおもうので、反省はしない。

学びはたしかにあった。おまけとして、なにかしらのレスポンスがもらえると嬉しいなとおもうが、はたしてどうなるか。ひとまずは close もせずに置いておくことにする。

放送大学に出願した

 どうも生活にメリハリが感じられない。運動と食事のルーティンは守れているので、客観的には健康的なほうにおもうのだが、主観的にはくすぶりを感じる。

 いったいなにが僕を満ち足りない気持ちにさせるのか? それがわからない。政治と社会のムードに抑圧的な影響を受けているのかもわからないが、世の中をののしってもどうにもならないという疎外感のほうが大きい。結局のところ、個人的な問題として処理しなければならない。

 だから、というのは論理の飛躍になるが、放送大学に出願した。新しいことを始めるぞ! という晴れやかな気分にいくらかでもなることができればとおもっている。

 もともと大型連休のころに 放送大学に入学してみようという記事を書いていた。思いたったタイミングがちょうど新学期であったので、妙なレイテンシが発生してしまった。とはいえ、やってみたいという気持ちは減衰しなかった。閉塞感やくすぶりを抱えているなかで、こうして前向きに「やりたい!」とおもえる対象が持てるのは幸せなことである。

 1年間有効な学生ライセンスに出願した。そして申し込んだ講義はこの5つ。

  • 1160028:初歩からの数学(’18)
  • 1559257:西洋音楽史(’21)
  • 1760041:入門微分積分(’16)
  • 1760106:初歩からの化学(’18)
  • 1760114:入門線型代数(’19)

 ここで欲張って、「仕事に活かせそうなものを学ぼう」と公私混同をするとあとがつらくなるような気がした。徹底的に仕事とは関係のない題目を選択した。

 数学科目は、次学期に応用的な科目を履修するための準備である。いきなり上位の科目に挑んでもよかったのだが、その前に入門科目を履修済みであることが望ましいとシラバスに丁寧な助言がされていたので、厳粛に従うことにした。

「初歩からの化学」は好奇心から。物理とか生物とか、他にも「初歩からの」シリーズがあってずいぶん悩ませられたが、欲張りすぎて散漫になることを嫌った。化学出身の知人を持たないので、未知の学問領域という感覚が強くある。高校までの知識しか持たないけれど、そもそも新大学生というのはみなそういうものだろうから、大丈夫だろう。

 西洋音楽史という文系科目も選んでいる。講義題目からして、おおかたバッハ以降の歴史を扱うのだろうと見当をつけてシラバスをみた。それより遥かに遡って、古代ギリシア音楽理論から扱うものらしいことに衝撃を感じて、おもわず選択した。いったいどんな話を聞けるのか見当がつかない。なにが出てくるかわからない楽しみという意味では随一のメンバーである。

 こうして書くにつけても、始まるのが楽しみで仕方がない。なにかを目指して勉強をするのは素敵なことであるが、勉強そのものを目的に意味もなく勉強することこそ究極の贅沢である。それをやろうとおもえる心の余裕をいま持てていることは幸福であるが、これができなくなったそのときには、人生の優先順位がおかしくなっていないか自分に問い直したまえ。この警句を3ヶ月後、新学期を迎えた自分自身に向けたい。

コンテスト参加をしばらくおやすみしようとおもう

 4月にレーティングが緑色になった。その後の数回のコンテストでも悪くはない成績を出すことができた。いちどや二度は茶色に陥落するものとおもったが、ひとまず洗礼は通り抜けたというところである。

 もともと過度な自尊心や上昇志向は持たないように注意深くモチベーションをコントロールしていた。少なくとも参加することだけは続けたい、とごく低い目標を掲げていた。経験上、これくらいであれば継続できていたはずなのだが、これすらどうにも難しいことがわかってきた。

 やりたいというぼんやりした気持ちはあるのだが、やるぞ! という情熱がどこかにいってしまった。天候の変化とか、身内の事情とか、複合的な要因で集中力が高まらない。そんな日々にあって、緊張感なり競争心といった気概をもって打ち込むことができなくなってしまった。

 もとより遊びのつもりではあっても、やるなら本気でやりたいという気持ちもあったらしい。予習復習を欠いてだらだらと参加することに意味はあるだろうか? という考えがどうしても拭えない。真面目すぎるような気がするのだが、本能に根ざしたものなのでどうしようもない。

 今週末もまた参加を見送って、不参加を選択した自分自身にガッカリしてしまっている。とはいえ、こんなことにガッカリしてもどうしようもないことはわかっている。できないことをできなかったと悔いることが健康によいとは思わない。

 メリハリのためにもいったん休むことを決意した。もういちど熱意が燃え上がるまでは、キッパリとおやすみにする。そうすれば、週末ごとに思い悩むこともないし、気持ちを落ち込ませる要因をひとつ自分の生活から追い出すことができる。

 いうまでもなく、これは僕自身の問題である。いずれまたやりたくなるときがくるだろうし、そんなときにいつでもまたやり直せるというのがアマチュアなりの喜びである。

6年ぶりにメガネを新調した

6年ぶりにメガネを新調した。

f:id:jnsato:20210704140135j:plain
縁を縛るようにゴールドがさしてあるのが気に入っている

もともと使っていたものはたしか JINS で買った。変哲のないウェリントンタイプのものだった。インターンをやっていたころ、卒業論文を書いていたころ、プログラマとして働きはじめたころ、ドイツにいったころ、ずっとかけていたことになる。安いわりにずっとかけていただけあって、昨年くらいからツルの塗装がはげおちはじめて、ちょっとだらしなくなりはじめてしまっていた。

f:id:jnsato:20210704140342j:plain
黒縁が剥がれて透明なフレームが露出している

これでもよくみない限りは気づかれない。というか、出かけるときにはコンタクトレンズをつけることが多いし、そもそも出かけることが禁止される風潮なので困りもしていなかった。

思いたって以来となると実に1年近くもなってようやく替えたことになる。コンタクトレンズが切れたので眼科に処方箋をとりにいくついでに、メガネの処方箋も切ってもらった。十分吟味してから決めるだろうかとおもっていたところ、映画をみにいったついでにみつけたメガネやさんでほとんど即決のようにして選んだ。

立川のルミネにはいっている TLIP というお店に世話になった。子供のころからメガネをつけているからといって、メガネに詳しいというわけではないことがよくわかった。イシイさんという店員さんが、豊富な知識で最高のアシストをしてくれた。なにも知らないこちらにその道のプロとしてよき選択肢をわかりやすい言葉で示してくれて、心底ありがたかった。