4/22 (日)
WordPress
しばらく Webサーバのログ解析をサボっているうちに "-- WordPress/2.1-alpha3" という User-Agent 名の トラックバックスパムが大量に送られてくるようになっていた。
このトラックバックスパムは、 常に一定の間隔で送られてくるのではなくて、 数日間の期間を挟んでバースト的に送信されている。 一方、送信先の IP アドレスはかなりバラけている。 少数のトラックバックスパマーが ボットネットを使って送信しているのだろうね。
|
|
|
|
|
選別して弾いているので実際に登録されることはないのだが、 うざったいのでアクセス禁止にする。
[Food] さっぽろ純連@高田馬場 (ぐるなび)
所用で新宿まで来たので高田の馬場まで足を伸ばして、 ひさびさに「さっぽろ純連」を食する。
午後4時ごろの入店だったが、店はほぼ満員状態。
久々のさっぽろ純連、大変美味しくいただきました。
今日見つけたキティちゃん
近所の飲み屋の店先においてあったキティちゃんの石像。 キティちゃんよ永遠なれ。
4/21 (土)
データのバックアップ
職場のディスクにシークエラーが出るようになったので、 データ部分を DVD-R にバックアップする。 容量的にはメールや資料等で約3GBになる。
2年ほど前にバックアップした時よりも0.5GBほど減っているが、 スパムメール等はバックアップ範囲から取り除いたため。
「年々データ量は増えていく」と言われているが、 スパムを除いた私信のメールのデータ量を調べてみると、 生涯に受け取るデータ量は1GBに届きそうもないと痛感する。
4/18 (水)
キター!!
愉快堂出版は結局破産したとのこと。 こんなメールが送られてきた。
ご 連 絡 冠 省 貴殿(社)におかれましては、御清栄のことと存じます。 さて、今般小職は、北九州市小倉北区上到津4−3−15−301、有限会社愉快堂 出版(代表者代表取締役 佐藤努)の代理人として次のとおり御通知申し上げます。 同社は貴殿(社)を始め約1000名(社)に対し約2000万円を超える負債を かかえ、支払不能の状態になり、債権者の方々には大変ご迷惑とは存じながら、この 事態を整理するために福岡地方裁判所小倉支部に破産の申立をなすこととし、当職の方 で準備を始めることになりました。 なお、小職の調査によると、同社には債権者の皆様に配当できる資産は残っており ませんので、貴殿(社)の支払われた会費等に相当する金員を返還することは困難で あると思われます。 債権者の方々には大変ご迷惑をおかけすることを同社の代理人として陳謝いたします。 必要な問い合わせ等は *****@yukaido.co.jp にお寄せいただければご回答いたします。 債権者各位
これで私も立派な債権者。しみじみ
4/13 (金)
[Linux] Linux で netgroup
NIS ネットワークのクライアントになっている UNIX マシンを、 ホスト単位で細かいユーザ制限を行いたい場合には netgroup が使える。 Linux で netgroup を設定する場合、 クライアント側の /etc/nsswitch.conf の passwd/shadow/group 指定をに "compat" とし、 netgroup の指定を "files " "files nis" と設定する。
passwd: compat shadow: compat group: compat netgroup: files nis
/etc/nsswitch.conf の netgroup: に "files" を指定した場合、 ローカルファイルの /etc/netgroup にネットグループの設定を書くことになる。 各行がネットグループ名となり その後にネットグループの所属者を ホスト:ユーザ:ドメインのトリプルで指定する。
ローカルの /etc/netgroup を記述する場合は、 ユーザ名だけでよい。
# groupname (host,user,domain) foo (,nminoru,)
最後にネットグループに所属しているアカウントだけのログインを許可するには、
/etc/passwd の最後の行に追加したいネットグループを
+@netgroupname
で追加する。
+@foo::::::
/etc/group は NIS の流しているグループを全て受け入れる。
+:::
これでお終い。
4/9 (月)
[CPU] メインフレームの命令って…
最近の新入社員は RISC プロセッサが斜陽化して Intel が独り勝ちをはじめたころに大学に入った人達なのね。 CISC といっても x86 ぐらいしか知らないため、 本当に複雑な命令が存在するのを信じられないみたい。
そういう人は System/370 の命令を一読すると、
過去の CISC コンピュータがどれほどヤバイ命令を持っていたか分かるようになります。
Translate命令はその好例でしょう。
TR D1(L,B1),D2(B2)
というフォーマットを見てもなんだか分からないと思うので、
現代風に書くと
TR L [r1 + r2] [r3 + r4]
System/370 はゼロレジスタのない16本の汎用レジスタ(gr0〜gr15)を持っているけど、
そのうち4本を使って
[r1 + r2]
と
[r3 + r4]
の二つのアドレスを指しています。
(ただし r1 と r3 は値がゼロした場合は、
gr0 の内容ではなく値ゼロを指す)。
このうち第一アドレスであるポイント p から 1 バイトづつ L + 1 バイト(1〜256) 読んで、
その度に 変換 を行います。
その変換内容を C 言語で書くと…
unsigned char *p = address of [r1 + r2]; unsigned char *q = address of [r3 + r4]; for (i=0 ; i<L+1 ; i++) { unsigned char v = p[i]; p[i] = q[v]; }
これで1命令。
命令の途中で割り込みは発生しません。
ページフォルトが起きた場合はメモリに何もなかった状態に巻き戻されます
(あるいは命令が完了してはじめてメモリに書き込まれます)。
ヤバイ。CISC 超ヤバイ。
あわわわ、そうなんですか。それはヤバい。
TRON chip も 命令フォーマット上は、無限段間接アドレッシングみたいなとんでもない機能があったようですが、実装上は2段だか3段だかに制限されていたようですね。気合いがたりません。(ぉ
(TRON chip は fault 後、68k 系のように命令を中途から再開するのではなく、よくある再実行タイプだったはずなんですが、ページフォールト時にどうするつもりで、そういう命令フォーマットにしたのか、昔から疑問でした。)
TRON chip も十分にやばいですね。
でも多段のアドレッシングでもメモリ読み込みだけを繰り返している分には、何とか割り込みを実装できそうな気がします。今の AMD64 アーキテクチャだって、TLB が外れた場合のページテーブル検索は通常 4 段ですし、仮想化機能の Nested Paging が有効な場合は 4 + 4 = 8段のページテーブルを行いますから (^_^;
名無しさん:
どう使うのかは私も良く知らないのですが、ASCII ⇔ EBCDIC の文字コードの変換などに使うらしいです。D2(B2) の位置に256バイトの変換テーブルをおいて、D1(L,B1) の先にある文字列(バイト列)を変換するみたいですね。
TR 命令の場合、機能の複雑さよりも、それが割り込みを許さず、ページフォールト
時に巻き戻されるというあたりが超ヤバイですよね。なんでまたそういう仕様にする
必要があったんでしょう。他のプロセッサで同時に動いているスレッドと共有して
いるメモリに対して実行した場合、他のプロセッサからはどう見えるんでしょうね。
無限段間接の方は、定数サイズの状態だけプロセッサ内部に保持すれば実装でき
るでしょうから、O(L)の状態が必要な TR 命令よりは簡単なんだと思います。
無限段命令の方は、もし実装されていたら、たった一命令でスラッシングを
起こし、永遠に次の命令を実行できないプログラムとかで遊べたんじゃないか
と思うと残念(?)です。
TRONの多段間接アドレッシングについては、嘆いていた人が...
フォールトが起きたページをページインしたあと命令を再実行する方式の場合、
その命令でアクセスするページ数が主記憶のサイズを越えるように細工してや
ると、永遠に次の命令に進めなくて楽しい(?)ですよね…って意味でした。
これが、命令を途中で中断して、ページイン後は中断したところから再開する
方式ならば、全部のページが主記憶に納まらなくても、先に進めるでしょうが…
確か TRON chip は (m68k のように) 再開型ではなく、再実行型だったと思います。
分かりづらくてすいません。
360のTR命令の変換テーブルと変換対象領域は、それぞれ高々2ページにまたがりますので、必要なら命令実行開始時にページフォールトを起しておけば、ループ実行中にはそれ以上の例外は起きないと思いますので、O(L)の状態は不要ではありませんか。
TRONchipについては、おっしゃる通りだと思います。
なるほど、確かにページフォルトに関する状態保存は不要そうですね。
4/7 (土)
[Book] 新宿ジュンク堂で書籍を購入
仕事の関係で Hacker's Delight を頻繁に参照するようになっている。 「Hacker's Delight を頻繁に参照する仕事」というのも不幸な気がするが、 私の英語力では英文を読む速度が和文を読む速度を上回ることがないので その邦訳の ハッカーのたのしみ を購入することにした。
最初 渋谷の Book 1st に行ってみたが在庫なし。 仕方がないので久々に新宿まで移動して、ジュンク堂に足を伸ばしてみる。 こちらでなんとか在庫を発見する。 ジュンク堂の背の高い本棚の一番下の棚に入っているものだから、 見落としそうになったよ。
ついでに Amazon.co.jp のカートに入っていた本の実物を探して手に取ってみる。
ネットで評判だった
へんないきもの、
またまたへんないきもの
は購入。
NFS & Amd、
大衆宣伝の神話 は
手にとって読んでみると、
期待したような本ではなかったので買わずに帰る。
渋谷に戻って服と椅子を買う。
椅子は4/14に配送される予定。
追加:4/14
注文していた椅子が配送される。
追加:4/22
ようやく椅子の組み立てを行う。
最初組み立て説明書が見つからず、
ほとんど全部組み立てた後にアームチェアの部分に組明がついているのに気づく。
おかけでワッシャーをはめていないビスを取り付け直すことに。
4/4 (水)
[Compiler] Intel C++ Compiler 9.1 のメモリポインタの一義化オプション
ポインタによるメモリアクセスは、 コンパイラの最適化を阻害する最大の要因だ。 それでも昨今の最適化コンパイラは下のプログラムの L3 と L4 が同じアドレスへの書き込みだと判断して L3 を削除することができる。
int *p = ...; *p = 0; // L3 *p = 1; // L4
しかしポインタが関数外や非ローカルな領域におかれると、 商用コンパイラはほとんど解析を諦めてしまう。 解析的なアプローチにはどうしても限界がある。 そこで C99 では restrict 修飾子を設け プログラマにあるポインタと別のポインタが重ならないことをプログラマに 示してもらうという方法を導入した。
同様のアプローチとして、 コンパイラオプションによって 無理矢理ポインタのエイリアシングはないと明示する機能を持つものもある。 かなり強引な方法なので気をつけないと とんでもないコードが生成されることになる。
Intel C++ Compiler も「ポインタの一義化(Memory pointer disambiguation)」オプションというのも複数装備している。 危険なオプションなので -On や -fast などの最適化レベルオプションをつけても、 ポインタエイリアス系の最適化は適用されない。 icc 9.1 の「一義化」オプションは以下の通り。
- -fno-alias
- プログラム内でエイリアシングを仮定しないことをコンパイラに指示する。
- -fno-fnalias
- 関数内でエイリアシングを仮定しないことをコンパイラに指示する。
- -alias-args- (-fno-argument-alias)
- 引数のエイリアス化を有効にするようコンパイラに指示する。
-ansi-alias
や、
restrict 修飾子を使いエイリアシングの解消を行う -restrict
オプションがある。
ただ説明が簡単すぎて、 どのオプションがどのような最適化が適用されるのか分かり辛い。 少し調査をしてみる。
以下は EM64T/Linux を使ってアセンブラコードを出力している。
デフォルトで -O3
オプションはつける。
引数のエイリアシングの解消
最初は引数ポインタ同士にエイリアシングによる曖昧性が生じている(restrict
を書くと解決する)パターン。
int foo(int* p, int* q, int v) { *p = v; // L3 return *q; // L4 }
上のプログラムをコンパイルすると、 通常は下のようにストア→ロードの順のコードが生成される。
.globl foo foo: movl %edx, (%rdi) #3.5 movl (%rsi), %eax #4.13 ret
上のプログラムは p と q の間の依存を読み切れれば、 ロード → ストアの順序を置換可能なので、 少しだけ高速化できる。
.globl foo foo: movl (%rsi), %eax #4.13 movl %edx, (%rdi) #3.5 ret
このパターンは
-O3
だけでは最適化されたコードは出力できず、
-fno-alias
、
-fno-fnalias
、
-alias-args-
オプションを加えると最適化できた。
外部変数からのエイリアシングの解消
引数以外からポインタが導入されているパターンで これも前の例と同様に 4 行目で生成されるストア命令と 5 行目で生成されるロード命令を入れ換えたコードが最速となる。
extern int* q; int moo(int* p, int v) { *p = v; // L4 return *q; // L5 }
このパターンは -O3
だけと -alias-args-
を加えたオプションでは最適化できず、
-fno-alias
と -fno-fnalias
を加えると最適化できた。
ちなみに以下のように両方とも外部変数でも、
-fno-alias
と -fno-fnalias
は最適化してしまう。
extern int* p; extern int* q; int moo2(int v) { *p = v; // L4 return *q; // L5 }
まとめ
今のところ
-fno-fnalias
と -fno-alias
の違いを見つけられない。
発見次第、加筆して行くつもり。
ノーマル | -alias-args- | -fno-fnalias | -fno-alias | |
---|---|---|---|---|
foo | × | ○ | ○ | ○ |
moo | × | × | ○ | ○ |
[Compiler] すっきり gcc、しょんぼり icc
-fno-fnalias
と -fno-alias
の違いは良く分からないが、
簡単なポインタ解析のテストをしているうちに
ICC の最適化はかなりしょんぼりだということに気づく。
int foo(void) { int i = 0x123; int* p = &i; return *p; }
gcc はポインタ解析を見切って、 以下のようなすっきりしたコードを生成する (v3.4.6 で確認)
foo: movl $291, %eax ret
一方、
icc は -O3
オプションに -fno-alias
をつけても、
下のコードのようにメモリにストアして同じ箇所をロードすると体たらく。
foo: pushq %rsi movl $291, (%rsp) movl $291, %eax popq %rcx ret
icc はどうしてこれが最適化できないのだろう? この程度のポインタ解析で救えるようなメモリアクセスが、 実際のコードに存在しないから真面目に作られていないのかしら?
僕は呼び出し側が守ってくれるかどうか不安で(自分ひとりで開発している場合でも (^^;; )使わないんですよね。
今回の仕事は数サイクル単位での最適化が重要になるので、できることは何でもやろうと Memory pointer disambiguation の最適化に手を出してみました。しかし手元のプログラムの性能は -fno-alias をつけてもぴくりとも上がらないです (;_; restrict の出番は今回もなさそうです。
4/1 (日)
[CPU] Montecito の Hyper-threading を使ってみる
hp rx2620 は 1 CPU (=2 Core) の Montecito (1.4GHz) が載っているが、 並列プログラムの検証のために並列度が稼ぎたいので Hyper-threading 機能をオンにしてみる。
起動時の EFI Shell から、以下のコマンドを打てば論理 CPU が 4 個に増加。
> cpuconfig threads on
通常 データと命令がそれぞれ 128 エントリずつある TLB が、 半分の 64 エントリになっていることを確認する。 手元のシングルスレッドベンチマーク(コアの片側だけ使用)だと、 非 HT 時の 80% 前後になる。