C++とアセンブラをやる意味

先日のエントリで、C++アセンブラを毎日やることに何かしらの意味があるんだろうといろいろ考えた。その結果、たぶん自分が普段考えているレイヤーの上位と下位で物事を考えるという訓練だという結論に達した。人間の思考回路はだいたいべたで書くようなCだと、一番考えやすいらしい。その上と下という意味で、上はC++であり、下がアセンブラなのだろう。

上位の代表格はC++である。C++アルゴリズムそのものを記述するのも得意である。その一方で、アルゴリズムを隠蔽することにより、もう少し大きな視点で物事を考えることができる。例えば線形サーチだったら、Cの場合どうしてもforでループを回さないと行けない。でも、C++の場合STLという標準化されたテンプレートでいろいろな実装方法があるので、単なるサーチだとしても、listテンプレートを使う場合だってあるだろうし、dequeテンプレートを使う事もできる。CとC++の両方の視点を持つと、どうしてもCの冗長さが欠点に思えてくる。業務アプリにおいて、Cが絶滅したのも、単純な処理をするためだけに長々と行数だけ消費してしまうという欠点が致命的になったためである。人間の集中力というのは、有限なリソースである。行数はなるべく少ないに越したことはない。行数が多いということはそれだけ集中力を要するということでもある。業務アプリでCが廃れたのは必然の流れだった。

一方、下位の代表格であるアセンブラはCの直下レイヤーである。Cが高級アセンブラという言い方もあるほど、アセンブラとCの共通点は多い。Cはコンパイラの作成者が楽をするために作られたという。記述レベルに関しては、ほとんど一対一で対応できる。一例を挙げると、i++とかj--はアセンブラのインクリメントの命令そのものである。

丸善本店で見かけた本を読んでみた

IT技術者として生き抜くための十ヶ条

IT技術者として生き抜くための十ヶ条

いつぞやのC++Windowsの話ばっかりの(良い意味での)頑固じじいって感じのウェブの管理人がどうやら本を出したようです。ちょっと期待してたんですけど、なんか脈絡がありそうで全然無いような話がまとまりも無く、どういう階層に向けてメッセージを出しているのかが、いまいち分かりづらいような本になってしまったのはちょっと残念だった。

たぶん、好意的に評価するならば、IT業界のスーツと奴隷の間で苦悩している世渡り下手なギーク向けかなと想像する。というのも、帯の「技術職を捨てて管理職になりたいですか」という質問だと、ギークだったら間違いなくノーを突きつける。かといって途中半端に大きい会社だと、一生プログラマという訳にもいかない。だってすんごい単調作業ばっかりだもの。システムコールとか知らなくても済むし、学校で習うようなクイックソートとかバイナリサーチ級ぐらいのアルゴリズムですら、ほぼ出番が皆無ね。

「あなたは、今のソフトウェア開発に満足していますか」という質問でも、ギークなら間違いなくノーだろう。ベンダーから指定された開発環境しか使うことが許されず、もっと粗悪な環境だと未だにvigccだけでがんばるような気合いと根性のみの自衛隊みたいな環境というのも、やっぱりあるところにはあるもんである。「このままでこの先も食べていけると思いますか」という質問は、たぶんギーク向けじゃないんだろうなあと想像する。ギークなら間違いなく自分の技術力に過信しているだろうし、そういう人は食べていけないような境遇になるなんて夢にも想像がつかないんじゃないかな。というと、この三番目の質問は奴隷向けなんだろうか。

序章に書いてある10項目について、ちょっとこれを中心にして本をまとめていけばよかったのにと思うのだが、実際はインタビュー形式で本が薦められてしまっている。帯の裏に「本書の内容」っていうことで10項目ってあるけど、インタビューと10項目が絡み合ってないのが一番の敗因かもしれない。

情報を捨てる勇気を持つこと

やっぱり今日のウェブだけでも、莫大なリソースが毎日生成&消滅されている。まあ、消滅する方はarchive.orgなんかのクローラーがどんどんがんばってくれているおかげで、消滅されてしまって、もう永久に情報が失われてしまったなんてのは、なくなりつつある。というと、やっぱり生成される量>>消滅する量なわけで、生成される情報におぼれてしまうと言うのはほんと昔から言われている問題である。もうかれこれ10年ぐらい同じ事を聞いている気がする。

一番大事なのは情報を取捨選択することなんじゃないかなと思う。同じ情報を出していても、一次情報源と二次三次だとだいぶ情報の信頼度が違ってくる。WindowsAPIのお話だと、ちゃんと一次情報源であるMSDNに行って見てくるという話かもしれない。昔はMSDNはソフトウェアのパッケージについてきて、パッケージを買わないといけなかった。でも今じゃウェブで無料公開されている。二次三次の情報源って、量は圧倒的に多いけど、品質は誰も担保していないから、エントリーレベルしかでていないような薄っぺらい情報ばかりになってしまうこともある。まあ、オープンソースのソフトウェアだと、一次情報はあんまりよくわからなくて、二次三次のほうがちゃんと書かれている場合もある。これは場合によりけりだけど、やっぱり一次から見ていったほうが時間のロスが少ない。

英語アレルギーを取ること

けっこう多いです。まあ、これは英語能力の個人差が激しいのでどうしようもないんだけど。でも一次情報源が英語で書かれている限り、英語をうまく飼い慣らすっての重要な能力たり得ると思う。でも、英語の能力そのものより、文章を見て、自分の中で構造を組み立てて、要点を早く飲み込む能力っていう、英語の読解能力の延長線上のほうが重要なんじゃないかなと思う。これは純粋に英語能力じゃないかもしれないが、やっぱり英語の読み書きができなきゃどうしようもないかもしれない。

一日一回フォーラムに投稿すること

普段はフォーラムめいたところにはいかないんだけど、ちょっと覗いてみました。場所はsysinternalsね。有名なアプリばっかりでけっこうお世話になっているんだけど、フォーラムの参加者はどーしようもないやつばっかりだってのは覗いてみればすぐ分かる。だから、あんまりフォーラムに投稿したりRSSリーダよろしく購読するより、はてなみたいな場所で、ツールチップぐらいの情報を書き続けていったほうが、なんぼかいいんじゃないかなと思う。

フォーラムの一番の欠点は、話題の言い出しっぺが質問で始まることなんじゃないかなと思う。「これこれなんだけど、どうしてこういう現象が起きちゃうのかな?」だと、群盲象を撫でるになってしまって、割と話が分散しがちになってしまう。でも、ブログとかになると、始めに話題ありき、という形になるので、話題が発展しやすい。

劣等感を持たないこと

劣等感は誰にでもある。劣等感の無い人はいない。そういう意味で、10項目に付け足したんだと思う。要するに、周りと比べて自分のアドバンテージを早く身につけろ、っていう事かもしれない。情報分野において、教養的な分野と専門的な分野を両方ともまんべんなく身につけるのはけっこう難しい。プロセスとスレッドの違いとか、OSの基礎的な役割について、現場の開発者で知ってるのって何人いるだろうレベルだ。そういう意味で、劣等感を持ったところで何の得にもならない。

ビジネスモデルを考えること

ギークは技術だけに目が向いてしまっているから、自分の作り出した生産物がどういうふうにお客さんのもとに届けられるかっていうのは、けっこう盲点だと思う。毎日毎日ひたすらPHPのモジュールばっかりいじくっていると、そういう気分にもなるのかもしれない。ビジネスモデルを考えるというのは、ちょっと重要かもしれない。

でもいきなりビジネスモデルを考えるっていうのは、技術的な側面ばかりやってきたら、もう皆目検討もつかないんじゃないかなと思う。今までやってきたことの無い分野を、今日いきなり始めますというのはさすがに無理がある。例えば、システムの営業みたいな分野の人脈を作って、そういう人との関わりを持って、そういう人たちの視点をまねるというのはどうだろうか。これだったらふつーにできそうな気がする。そういうのから、お客さんが望むモノはどういう形で実現可能か、という発想が自然と出来ていくと思う。

楽して仕事することを考えること

やっぱりコンピュータに向かって作業をしていると、自分のやっていることが単調に思えてくるわけです。コンピュータは自動化(定型化)されたお仕事が得意です。というと、単調な作業をコンピュータにさせるというのはごく自然な発想であるわけです。例えばvigccのみでがんばっているような作業を、VisualC++を使って、インテリセンスで楽をするということもできるわけです。デバッグだって、ブレークポイントをそのままぽちっと押してステップ実行するだけでいいんだから。デバッグを可視化できただけでも、今まで手作業でやってきた人から見れば相当な驚き&進歩なんじゃないかなと思うわけです。

先哲のアドバイスを聞くこと

先哲のアドバイスっていうと、どうも会社の上司や先輩、っていう発想になってしまう。でも、今時のオープンソースなら、ちょこっとソースコードをダウンロードして、どういうふうに実装されているのかを調べるだけでも、相当な進歩たりえるんじゃないかと。いきなりLinuxカーネルを覗いてみても訳が分からないだけに終わるけど。

先哲のアドバイスを文章化すること

聞いて文章化すべし、ということなのだろう。日々の業務に忙殺されていると、どうも自分がやっていることのログがうまくつけられない。手順書を書くために、画面のスクリーンキャプチャを取るのですら、ちょっとためらってしまう。やっぱり自分のやってきたことと、先哲のアドバイスをちゃんと文章にして書き留めておくというのは、やっておかないと後で後悔する元となってしまう。同じ事を何回もするのは馬鹿である。やっぱり、文章化して書き留めておいたものは貴重である。

一日一回C++ソースコードをビルドすること

普段、業務でCとかJavaを使っていると、C++から疎遠になってしまう。もちろんCとC++C++Javaは共通点が多いのだけれども、C++にしかない特徴はかなりある。標準テンプレートですらそういう状況なのだから、毎日何かしらのテーマを持って、ビルドするのは大切な習慣かなと思う。

一日一回アセンブラコードを眺めること

VisualC++やgccは、オプションをつけるだけで、C/C++のコードからアセンブラのコードを出力することが出来る。こういうツールを使いつつ、レジスタ単位でどういう動きをしているのかを知って勉強しておくと、コンパイラの最適化絡みでバグを発生させてしまうと、これはコンパイラが先走ったことをしているからかな?と検討をつけることができる。

メモリマップファイルを作成する

WindowsのようなOSでは、ページングやらメモリ保護やらたくさんの機能がある。おかげで異なるプロセス同士でも、お互い干渉せず実行できたりする。でも、複数のプロセスからメモリを共有したいときがある。メモリマップファイルというOSの機能を使えば、簡単にメモリを共有することが可能となる。

write.c (共有メモリに情報を書き出すプロセス)

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int i =0;
  int *p = NULL;
  HANDLE h;
  h = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 1024, "a");
  p = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 1024);

  for (i = 0; i < 128; i++) {
    p[i] = i * 10;
  }

  getchar();

  return 0;
}

read.c (共有メモリから情報を読み込むプロセス)

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int i =0;
  HANDLE h;
  int *p = NULL;
  h = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 1024, "a");
  p = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 1024);

  for (i = 0; i < 128; i++) {
    printf("p[%d]= %d\n", i, p[i]);
  }

  return 0;
}

この二つのサンプルのソースコードをそれぞれコンパイルし、実行してみる。write.exeが実行している間では、read.exeでは数字が読み込むことができる。ここで、二つの異なるプロセスがメモリを共有できていることが分かる。write.exeが実行し終わった後では、自動的にメモリ共有は終わり、read.exeは読み込む内容はすべて0クリアされてしまう。

コンパイラの勉強(第二章を読む)

コンパイラ構成法

コンパイラ構成法

公式サイトがつぶれてしまったので、本の付属ソースコードが入手できないという事態に。

手持ちのソースコードをUPしておきます。

TSUTAYAから戦争映画を借りてきた

ルワンダの涙 [DVD]

ルワンダの涙 [DVD]

今回はアフリカの内戦にスポットを当ててみる。見たけど、あまりにも残虐シーンが多いので、子どもがこの映画を見るのはちょっとやめておいた方がいいかも。

学生のうちにプログラムを書き始めると言うこと

最近、といってもずいぶん昔からだが、プログラマは使い捨てという概念がある。35歳定年説ってやつだ。まさに使い捨てである。定年って事は、それ以上進まないって事を意味している。つまり、プログラマはどんなにがんばったって35歳までしか仕事が無い事になる。コンパイラがどのように動いているかの知識は必要なく、どのようにメモリ上でロードされているか分からなく、OS層の事なんかぜんぜん理解していない、とかいった人たちが世間一般で言われているプログラマである。人海戦術として手作業のみこなすといった、きわめて単純作業のみの仕事に限定されているらしい。そもそも、計算機として捉えたコンピュータの内部でどのような流れ(OSとの連携といった大きい面から、スタック(関数の呼び出しの順番)に積まれた変数といった小さな面まで)で動いているかは知るべきである。知っていなければ、ある一定以上の規模になってくると扱うことが難しくなる。

どうも手作業で人海戦術といったアプローチが必要なのが腑に落ちない。デバッガによる支援無しで、エディタとコンパイラで作業するなんて、慣れていなければ相当難しいはずなのに。三つ子の魂百まで、といったことわざがあるように、人間というものは最初に学んだツールの使い方をいつまで経っても貫き通すらしい。初めにエディタとコンパイラのみでプログラム構築をした人間が、統合開発環境なんてツールを使っている場面なんかほとんど見たことが無い。統合開発環境を使うメリットがどれだけのものか分からないのか、単に使い方が分からないのか。

そういったことを考えているうちに、学生のうちにプログラムを書き始めるならば、最初から統合開発環境でプログラムを書いていくといった事をおぼえておくべきなんじゃないかなと思えてくる。リファクタリングやステップ実行など、エディタのみで作業をしていたら絶対にできない事が統合開発環境を使えば簡単にできる。それでもやっぱり初めは見慣れないツールなので、使いこなすのが難しい。買ってきたソフトウェアには、書籍でのマニュアルもない。ワープロ表計算ソフトと違って、使いこなせるまでに結構時間がかかる。でも、使いこなすことができれば、スタックや変数の移り変わりなども一目で分かる。そういうツールの活用こそ、単純作業とか少しは楽になるんじゃないかなと思った。

VisualStudio2008 Professional のインストールがうまくいかない

今までExpress版を使っていたが、やっぱりこういうのはProfessional版を使いたいということで、思い切って買ってみた。そしてインストールしようと・・・したら、いきなりシャットダウン&リブートしてしまった。あまりの突然の出来事にちょっと目の前の現象が信じられなかったのだが、やっぱりインストーラーを起動しようとすると、どうも途中でシャットダウン&リブートがかかるみたいである。

何か理由があるのだろうか。CPUがAMDじゃいけないとか、使っているBiosに特殊なバグがあって、その地雷的なバグを偶然見つけてしまったとか。いろいろ考えるところはあるけれども、結局のところ、現在の環境ではVisualStudio2008 Professionalが使えないという結論になってしまったので、悲しいこと限りない。

追記

おそらく、次のような理由だと思われる。まずUDF2.0というものがあり、ふつうはこのタイプのフォーマットを読むことができる。しかし、このフォーマットを扱うサードパーティ製のドライバに欠陥があり、うまく読み込むことができないバグがあるらしい。読めないだけではなく、読み込もうとするとOSを巻き添えにしてハングアップしてしまい、結果としてシャットダウン&リブートとなってしまう。以上のように推測をすると、なぜこのような現象が起こったのかが理解できる。しかし、インストールができないのは変わりない。