Windowsに、デスクトップを高速にキャプチャする機能が欲しい。というのも、GDIでキャプチャしようとしても、実用にならないほど遅い。どういうわけか分からないが、フレームレートは垂直同期の半分に落ちてしまう。しかし、実際には、GPUによるが、640x480の解像度で、一秒間に60回程度のキャプチャを行うことは可能だ。具体的にはDirectXのサーフェイスをアレなやり方で取得する。Frapsがいい例だ。ちなみに、Frapsが快適に動作するのは、そのままではHDDの書き込み速度が追いつかないので、多少の圧縮をしているためでもある。
2008-05-31
2008-05-28
スライム年代記
前回の、はぐれメタルに関する記事の続き。
ドラゴンクエスト モンスター物語に記されているスライム年代記の記事が、恐ろしいアクセス数を記録した。理由は分かっている。ゴルゴ31にリンクを貼られたからだ。しかし、あんなRSSも吐かない様なアクセシビリティの低いWebサイトの利便性というのが、どうも私には分かりかねる。おまけに、いまだにShift JISだ。
さて、前回も言ったように、スライムはアレフガルド大陸の中央部の、小さな湖の中で生まれた。「初めは目に見えないぐらい小さかったスライムも、やがて爪の先ぐらいの大きさになりました」、とある。さらに、スライムは単細胞生物である旨が述べられている。後に雌雄に分かれたが、どうやらいつまでも単細胞生物のままだったようだ。単細胞生物のまま、身体を大きくしていったらしい。
さて、その強い繁殖力により、湖の中はスライムでいっぱいになってしまった。そこで、陸に上がらざるを得なくなったが、初めは熱さから身体が溶けてしまったらしい。しかし、スライムの驚嘆すべき適応力で、わずか数世代にして、陸で暮らせるスライムが生まれたとある。信じがたい適応力である。陸に上がってからは、草原の草を食べていたらしい。
さて、陸で暮らせるようになったものの、すぐに人口の増加を支えきれなくなった。そこで、元気のいい数百匹が、新天地を求めて、四方に旅することとなった。
まず南に向かったスライムたちは、大きな草原を発見した。しかし、南に向かったグループは多かったので、草原はすぐに荒地になってしまった。食べるものがないので、虫を食べることで、かろうじて生をつないだが、体色がオレンジ色のスライムが生まれるようになった。これがスライムベスである。ちょうどその頃、近くに魔法おばば達が住んでいた。彼女らは、魔王にこき使われて、救急看護婦部隊として、魔物の回復などの支援に当たっており、とても重労働だった。そこで、スライムに回復魔法を覚えさせることを、思いついた。魔法おばば達は「秘伝のタレ」にスライムを浸した。秘伝のタレとは、原文を引用すると次の通り、「秘伝書に書かれていた通り、シャーマン族の面の皮に極楽鳥の羽、それにオークキングの牙が入れてある。ソレにワシの爪の垢もナ」。スライムたちがこの秘伝のタレにつけられると、下半身から触手が生えてきた。その結果、普通のスライムはホイミを唱えられるようになり、スライムベスはベホマを唱えられるようになった。こうしてホイミスライムとベホマスライムは、魔王の手下として使われ、その多くは、人間達との戦いによって、命を落としたという。
その頃、西に向かったスライム達は、行けども行けども、不毛な砂漠ばかりで困窮していた。遠くを見ると山があったので、とりあえず山へ行くことにした。草を求めて山の上へ上へと進むうちに、どんどん寒くなってきた。ふと見ると、人間の馬車が横倒しになっており、そこには見かわしの服がたくさんあった。寒さに凍えていたスライムたちは、見交わしの服の中にもぐりこんで、旅を続けようとしが、ふと気がつくと。洞窟から声がする。食べ物があるかもしれないと思って、洞窟に入った。ちょうどその時、洞窟の中では、トロル達がミスリル銀を採掘していた。硬い岩を崩そうと、魔法の玉を三つ仕掛けたところ、果たして岩は崩れたが、地熱で溶けたミスリル銀の液体が流れてきて、トロル達は埋もれて死んでしまった。運悪くその瞬間に洞窟に入ったスライム達は、ミスリル銀に埋もれてしまった。本には、身かわしの服を着ていたために、熱を遮断し、死なずにすんだとある。やがてミスリル銀が固まると、スライムの皮膚は、ミスリル銀になってしまった。こうして、身かわしの服のすばやさと、ミスリル銀の皮膚を手に入れた。真に驚くべきは、この体質が子孫に伝わったことだ。このスライムは、後にメタルスライムと呼ばれるようになる。
さて、北に向かったスライム達は、広大な草原を発見したが、サーベルタイガーに襲われてパニックを起こし、逃げた先に草原はなく、ストレスから、レミングよろしく集団大移動を始めた。その恐るべき有様は、スライム達が通った後の池はくぼ地に、草原は砂漠に変わり、人間は踏み潰されたとある。ちなみに、その人間達の会話が面白いので、本から引用することにする。
「アレ水色の生き物、弱い。石ぶつけると逃げる。心配ない」
「でもすごい数。とてもたくさん」
「水色の生き物たくさん来る。石たくさんぶつける。心配ない」
その後もスライム達は暴走し続けたが、ついに崖に到達した。しかし後から走ってくる集団に押され、皆崖から落ちて、海の中に入ってしまった。陸上に適応したスライムたちは、既に泳げず、半数以上が溺れ死んだとある。しかし、何とか泳ぎを覚え、生き延びたものもいた。切り立った崖は高く、とても上れそうにないので、海の中で生活することにした。三日目に新しい世代が誕生したとあるが、驚くべきことに、新しい世代は海の生活に適応し、自由に泳ぐ事を得たとある。しかし海の中にも敵はいた。ガニラスである。そこで、スライム達は、宿主のいない巻貝の中に入って身を隠すことを覚えた。そのうち、最初から殻を背負ったスライムが生まれるようになる。実に驚くべき適応能力である。このスライムは、マリンスライムと呼ばれるようになった。スライム達は、さらに海中深くへと移動していったが、そこには大王イカがいた。大王イカの力は強く、貝殻は役に立たなかった。あるとき、あるスライムの子供が大王イカ捕らえられ、まさに打ち殺されそうになった。スライム達は皆、子供が助かるようにと祈るばかりであった。すると、子供の守備力が上がり、以て大王イカの攻撃に耐える事を得た。これは、後にスクルトと呼ばれる呪文である。さて、海の中もスライムが増え、食物が枯渇する前に、若いマリンスライムの一群が、旅に出ることにした。ある老スライムは、経験豊富な自分もついて行くと主張し、その旅に加わった。海のさらに深い場所は水圧が高かったが、カルシウムの高い食事をすることによって、殻がより丈夫になり、下手な魚に襲われた程度では、スクルトの呪文も必要なくなった。しかし、そこにはルカナンの使い手、マーマンがいて、スクルトが無効化されてしまった。そのとき、例の老スライムが躍りでて、スクルトを攻撃に応用する方法を考えていたと言うや否や、ヒャドを唱えた。これを見た周りのスライムも、すぐにヒャドを唱えられるようになり、マーマンをして逃亡せしめた。しばらくして、今度は大王イカよりも強大な、テンタクルスに襲われた。テンタクルスにはヒャドが聞かず、スクルトは、しばらく使わなかったために、皆忘れていた。引越し、新しい呪文の考案などの意見が出されたが、例の老スライムの演説により、スライム達は、イカを眠らせるべきであると結論した。そうして、ラリホーの呪文を使えるようになった。これがスライムつむりである。
最後の東に向かったスライム達の次第は、前回の通りである。
以上が、モンスター物語に記されているスライム年代記の概略である。もし詳しいことを知りたければ、是非とも原本に当たるべきだ。他にも面白い物語がたくさんある。試みに列挙すれば、
馬鹿正直な、あるストーンマンの話
マドハンドの増殖の謎
異世界から召喚されたメタルハンター
何故、キラーリカントがゾーマ時代では四速歩行なのに、竜王・ハーゴン時代では直立しているのかを解き明かす話
大魔道カトゥサによる、ブラックメイル製造秘話
爆弾岩の生い立ちと、ある正直な爆弾岩の話
ある哀れなミミックの話と、人食い箱との違いについて
泥人形がMPを吸い取る目的と、パペットマン誕生秘話
メルキドを陥落させるべく、策を巡らしてゴーレムに挑む大魔道カトゥサの話
ベリアルのアークデーモンとなったベビルのグレムリンの元、ミニデーモンのベビーサタンの出世話
悪魔神官ドルバによる、キメラ製造秘話
栗本和博によるカラーの四コマ漫画
魔王軍団の編成図
モンスター分類図
2008-05-26
試験問題と著作権について
問題集から長文が消える 著作権で引用できず 1/2
問題集から長文が消える 著作権で引用できず 2/2
大学入試の過去問題集などで、国語の長文読解問題の一部が掲載されない異例の事態が起きている。評論などを執筆した作家から著作権の許諾が取れていないためだ。教育業界では「教育目的」という大義名分のもとで無許諾転載が慣例化していたが、著作権保護意識の高まりから、大手予備校や出版社などが相次いで提訴されており、引用を自粛する傾向も目立ち始めている。
法律上は、いわゆる試験問題作成のために複製、公衆送信を行うことができるのだが、営利目的の場合はこの限りではないとされている。つまり、この営利目的の除外に、過去問題集が当てはまるわけだ。
そもそも、まだ著作権が存在するような文章を、問題文として使う必要があるのだろうか。既に著作権が切れて、パブリックドメインとなっている文章を使えば、何の問題も起こらないというのに。
私も高校生の頃、入試の予想問題や過去問集を山のように説いたが、現代国語で複製されている文章はひどかった。特に論文だ。筆者は、論文の内容よりも、文章の堅苦しさを重視したとした思えない文章が、多数あった。特に論文の内容ではなく、文章に矛盾があるのだ。それなのになぜか、文章の文法上の矛盾を挙げよという問題は存在しなかった。
なぜこのようにひどい悪文になるかというと、論文の筆者に漢文の素養のないことが原因だろう。
それ真に、漢文調、かつ、論理的な文章を読まんと欲する者は、中江兆民の三酔人経綸問答を読むべし。
まあ実際、三酔人経綸問答は、修飾過多である。それでも、福沢諭吉の文章より読みやすい。確かに福沢諭吉の文章は、当時としては驚くほど簡単なのだが、どうも文章が単調で、読んでいてつまらない。先を読もうという気力が沸かない。
2008-05-23
VistaでやっとまともにサポートされたI/Oのキャンセル機能
Win32 I/O Cancellation Support in Windows Vista
via ファイル I/O でブロックされているスレッドを殺したくなったらどうするか?
最近、technical articleでkanji scriptsをreadするのがtediusなので、リンクは英語の記事に貼った。
今まで、一度もCancelIoを使う機会に恵まれなかったので、知らなかったのだが、I/Oのまともなキャンセル機能というのは、Vistaになって初めてサポートされたらしい。ドライバが対応していればの話だが。CancelIoでキャンセルできないI/Oは以下の通り。
I/O operations issued for the file handle by other threads;
え、マジで?
Specific I/O operations;
いや、具体的に頼む。
Synchronous I/O operations, since they (by definition) block in the operating system;
え、できなかったの?
I/O issued to a completion port or associated with an IOSB range.
おいおい、完了ポート未対応だったのかよ
Vista以降は、CopyFileなどの一部複雑なAPIを除き、ほとんどのI/O操作をキャンセルできる。WalkTreeというAPIを知らず、探しても出てこないのだが、これはVBか.netか何かのライブラリなのだろうか。
あるファイルハンドルへの、すべてのスレッドからの非同期I/Oをキャンセルしたい場合は、CancelIoExを使い、OVERLAPPED構造体へのポインタは、NULLを指定しておく。こうすれば、現在のプロセスのすべてのスレッドから行われた操作がキャンセルできる
同期I/Oをキャンセルしたい場合は、そのファイルハンドルに対して、CancelSynchronousIoを呼び出せばよい。
ただし、これらのキャンセルを用いる場合は、Raceを考慮しなければならない。例えばすべてのスレッドの非同期IOをキャンセルしたいとしても、スレッドごとに順次キャンセルしていくので、すでにキャンセルし終えたスレッドが、別のIO操作をするかもしれない。同期IOのキャンセルに関しては、ある処理がなかなか終わらないので、他のスレッドからキャンセルしようとしたが、まさにキャンセルしようとした瞬間に処理が終わり、新しく始めた別の処理をキャンセルしてしまうこともある。
IEチームとのチャット 五月版
Transcripts of Previous Windows XP-Related Chats
興味のあった会話
Q: Will the IE team work on improving standardization, like ACID with updates after release... Or do only major versions change this?
A: (originally answered wrong question - sorry) In order to ensure updates don't cause compatibility problems with websites, updates only address security and reliability issues.質問:リリース後に、標準規格準拠のためのアップデートなどは行われるのかい? そういうのはメジャーバージョンアップだけかい?
回答:互換性の問題のために、セキュリティや安定性のパッチぐらいしかださないよ
また、この手のチャットは、常に、XHTMLやCSS3やDOMのサポートについて言及されるのだが、毎回、「個々の機能が製品に入るかどうかは答えられない」、と返されている。しかし今回、いい加減にうんざりしたのか、「XHTMLの利点ってなんだい」、と答えている。まあ、実際、XHTMLは、文法ミスがひとつあっただけで、ブラウザが読み込みを拒否しても文句は言えないような環境だしなぁ。
2008-05-22
数体系ということについて
すばらしく簡単で、ほぼ厳格な10進数の数体系を持つ日本人の皆さん。私は、2進数の数体系の中で生きるhitoである。
今回は、数の数え方、ということについて、広く浅く紹介をしようと思う。数を数える、ということは、君達、日本人にとって、あまりにも当然で簡単なことだと思うだろう。ところが、実際には、そうではないのだ。君達は、ほぼ完全な10進数の世界で生きている。九まで数えると、位が上がって、十になる。君達が11といったときには、それは1*10 + 1である。さて、英語を考えてみよう。英語の11は、Elevenであるが、これは11という数そのものを意味するのだ。もうお分かりだろうか。英語は日本語ほど、完璧な10進数ではないのだ。実際、ダースという単位があるのは知っているだろう。これは、12進数の名残なのだ。
かつて、勃起したペニスで障子を突き破る東京都知事、シンタロー・イシハラは言った。「フランス語は数が数えられない言語である」と。それは事実である。なぜならば、フランス語には、16までの専用の単語があるし、20進数の名残が、色濃く残っているからだ。17から19までは、10 + n(6 < n < 10) などと10進数で表記するのだが、20以上になると、20 + n(0 < n < 10) となる。さらに、30、40、50、60、を表す専用の単語がある。60以降は、60 + n(nは1から19までの数え方)、となる。80以降は、4 * 20 + n(nは1から19までの数え方)、となる。
より深く、各言語の数体系を学びたい輩は、世界の言語の数体系を参照されたし。
Compiler Intrinsicの吐くコード
でまあ、x264の開発者達は、Compiler Intrinsicを無視しているわけだが、実際にどんなコードを吐くのだろうか。
コード自体は、前回を見ていただくとして、インラインアセンブリにする前のコードは、魔法のアルゴリズムのところで言及している。
コードの処理内容は、三つの整数地のmedianを取りたい、というものだ。これが単なる平均というのであれば、単に全部足し合わせて、三にて除すればよいのだが、中央値となると、そうはいかない。最初のCのコードでは、最小値と最大値を求めて、合計から減ずるという方法を取っている。最小値と最大値を求めるには、if文が必要だ。x264とは動画のエンコーダであり、この処理が恐ろしく頻繁に必要になる。だから、このコードのクロック数をわずかでも少なくすることは、エンコード速度の向上につながる。たとえ、一回あたりが数十クロックから数百クロックの削減であったとしても、効果は絶大だ。
さて、現在のCコードは、シフト演算子をつかって、符号ビットを見ている。そうすることによって、最小値と最大値を、条件分岐を用いず、計算だけで出すことができる。もちろんこれは、規格では未定義のコードだ。しかし、どうせ実装依存というのであれば、プロセッサのSIMDな命令を使えば、もっと速くできるはずだ。とても短いコードで、インライン展開しなければ利点がないので、別途yasmなどでアセンブルして、リンカで、というわけには行かない。そんなわけで、インラインアセンブリが必要になる。
これを単純に、固定値で呼び出すと、次のコードを吐く。
mov eax,1
movd xmm0,eax
movq xmm2,xmm0
mov ecx,2
movd xmm1,ecx
pmaxsw xmm0,xmm1
mov eax,3
movd xmm3,eax
pminsw xmm0,xmm3
pminsw xmm1,xmm2
push edx
pmaxsw xmm0,xmm1
悪くない。前回のコードと比べて、まったく遜色ない。gccのインラインアセンブリのところは、Intel Syntaxではなく、AT&T Syntaxなので、srcとdstが逆になっていることに注意されたい。では、実際にx264で使ってみた場合は、どのようなコードを吐くか見てみよう。以下のコードは、macroblock.c の183行である。
0041B017 . 66:0F6EC1 MOVD MM0,ECX
0041B01B . 0FBF08 MOVSX ECX,WORD PTR DS:[EAX]
0041B01E . 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10]
0041B022 . F3: PREFIX REP: ; Superfluous prefix
0041B023 . 0F7ED0 MOVD EAX,MM2
0041B026 . 66:0F6ECA MOVD MM1,EDX
0041B02A . 66:0FEEC1 PMAXSW MM0,MM1
0041B02E . 5F POP EDI
0041B02F . 66:0F6ED9 MOVD MM3,ECX
0041B033 . 66:0FEACA PMINSW MM1,MM2
0041B037 . 66:0FEAC3 PMINSW MM0,MM3
0041B03B . 66:0FEEC1 PMAXSW MM0,MM1
0041B03F . 5E POP ESI
0041B040 . 66:0F7EC2 MOVD EDX,MM0
OllyDbgで見てみたが、よく分からないのは、間にpopが挟まっていることだ。この後すぐに、関数から、return するので、popをしなければならないというのは分かるのだが、なぜ後でまとめてやらないのだろう。何か理由があるのだろうか。
まあともかく、Compiler Intrinsicは、悪くないと思うのだが。
x264のインラインアセンブリをMSVCでコンパイルできるように移植してみた
もちろん、例のx264_median_mvの部分だ。インラインアセンブリにする必要性があるらしい。というわけでMSVCでコンパイルできるようにutil.hを書き直してみた。まあ、単にMSVCのCompiler Intrinsicsを試してみたかっただけだが。
/*****************************************************************************
* mc.h: h264 encoder library
*****************************************************************************
* Copyright (C) 2008 Loren Merritt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef X264_X86_UTIL_H
#define X264_X86_UTIL_H
#ifdef __GNUC__
#define x264_median_mv x264_median_mv_mmxext
static inline void x264_median_mv_mmxext( int16_t *dst, int16_t *a, int16_t *b, int16_t *c )
{
asm(
"movd %1, %%mm0 \n"
"movd %2, %%mm1 \n"
"movq %%mm0, %%mm3 \n"
"movd %3, %%mm2 \n"
"pmaxsw %%mm1, %%mm0 \n"
"pminsw %%mm3, %%mm1 \n"
"pminsw %%mm2, %%mm0 \n"
"pmaxsw %%mm1, %%mm0 \n"
"movd %%mm0, %0 \n"
:"=m"(*(uint32_t*)dst)
:"m"(*(uint32_t*)a), "m"(*(uint32_t*)b), "m"(*(uint32_t*)c)
);
}
#elif defined(_MSC_VER)
#include <emmintrin.h>
#define x264_median_mv x264_median_mv_sse2
static inline void x264_median_mv_sse2( int16_t *dst, int16_t *a, int16_t *b, int16_t *c )
{
__m128i m0, m1, m2, m3 ;
m0 = _mm_cvtsi32_si128( *(uint32_t*)a ) ;
m1 = _mm_cvtsi32_si128( *(uint32_t*)b ) ;
m3 = _mm_move_epi64( m0 ) ;
m2 = _mm_cvtsi32_si128( *(uint32_t*)c ) ;
m0 = _mm_max_epi16( m0, m1 ) ;
m1 = _mm_min_epi16( m1, m3 ) ;
m0 = _mm_min_epi16( m0, m2 ) ;
m0 = _mm_max_epi16( m0, m1 ) ;
(*(uint32_t *)dst) = _mm_cvtsi128_si32( m0 ) ;
}
#endif
#endif
驚くべきことに、このコードは問題なく動くようだ。
このコードの何が、x264開発者の連中のお気に召さないかというと、奴らはコンパイラを一切信用していないからだ。出力されたコードは、それほど悪いものでもないと思うのだが。
マイクロソフトが、x64からインラインアセンブリを捨てて、このようなCompiler Intrinsicsを豊富に提供しだしたのは、まあ、色々理由があるのだろうけど、ひとつにはレジスタの割り当てというのがあるのではないか。x264もだいぶ苦労していて、いまはマクロアセンブラのマクロ機能を多用して、各プラットフォームごとにレジスタの割り当てを切り替えている。Windows向けのx64コードは誰も気にしていないので、当然動かない。そんなことをするぐらいだったら、やはりこういうCompiler Intrinsicsの方がいいのではないだろうか。
追記
関数名を正しく変更した。このコードはSSE2を要求する。つまり、このコードは、Pentium 4、あるいはAthlon 64 以降でないと動かない。なぜSSE2を使ったかというと、MMXはx64ではサポートされていないからだ。
追記2
int16_t *をint32_t *にキャストするようにした。どうやら、このポインタのキャストは、意図したものらしい。
追記3 dstの型をキャストするのを忘れていた。Cキャストはuglyで嫌いだ。reinterpret_castを使いたい。
2008-05-21
x264のスレッドのバグと、前提条件について
fix a crash on win32 with threads.
fix a crash on win32 with threads.
r852 introduced an assumption in deblock that the stack is aligned.
何が問題かというと、r852によって、スタックが16バイトアラインメントされているというassumptionがあったのだ。x86_32のABIは、4バイトアラインメントしか保障していない。何故この問題がテストに引っかからなかったかというと、linux上のgccは、常にスタックを16バイト上にアラインメントするからだ。
17:15 (hito) i had never met crash with multi-thread encoding. is it a rare thing to happen? i wonder why this bug is windows only.
17:19 (pengvado) x86_32 abi only guarantees 4-byte stack alignment. pthread-win32 does that. but gcc on linux does 16-byte alignment.
17:20 (hito) hmm intresting.
そして、新しいファイル、standards.txtがdoc以下に加えられている。この中身は次の通り
x264 is written in C. The particular variant of C is: intersection of gcc-2.95 and msvc. This means C89 + a few C99 features.
The extra utilities (mostly checkasm) are written in C99, with no attempt at compatibility with old compilers.
We make the following additional assumptions which are true of real systems but not guaranteed by C99:
* Two's complement.
* Signed right-shifts are sign-extended.
x86-specific assumptions:
* The stack is 16-byte aligned. We align it on entry to libx264 and on entry to any thread, but the compiler must preserve alignment after that.
* We call emms before any float operation and before returning from libx264, not after each mmx operation. So bad things could happen if the compiler inserts float operations where they aren't expected.
つまり、x264のコードは、2の補数である事と、符号ビットが右シフトで動くことを前提としている。これはC99では保障されていない。なぜこんなドキュメントをつけたかというと、まあ、私が吹っかけた議論ではあるのだが。
22:29 (hito) in x264_median, is it always guaranteed? a-b >= 0, b-c >= 0
22:30 (Dark_Shikari) no
22:31 (hito) in C spec, shift operands must be nonnegative. otherwise its behavior is undefined.
22:32 (Dark_Shikari) where is there such a case
22:32 (Dark_Shikari) in the code
22:32 (Dark_Shikari) all the shift values are 31
22:33 (Dark_Shikari) ((a-b)>>31) is equivalent to "give us the sign bit"
22:33 (hito) i mean if there is expression like "a >> b", both a and b must be nonnegtive.
22:33 (Manao) hito: huh ? >> on signed value is a sar
22:34 (Manao) it's well defined
22:34 (hito) standard say nothing about sign bit. just leave it as implementaion defined.
22:35 (Manao) and every C compiler is know of treat it as a sar. So there may be an addendum to the C standard
22:35 (Manao) s/is/I/
22:35 (Dark_Shikari) if someone didn't treat it as a sar other programs would probably break too >_>
22:40 (hito) maybe someone release strange architecture which place sign bit at the least significant bit.
C++0x N2601 60進数リテラル
目には目を、歯には歯を、とは言ったものの、奴隷の目を潰したり、腕をヘシ折ったりしても、金さえ払えばよしとされる、すばらしいハンムラビ法典の信奉者諸君、私は、すべての文字文化に理解のある、心の広いhitoである。
さて、今回は、2008年5月のC++0xのメーリングリストの中から、N2601を紹介しよう。一体どういう提案なのかというと、60進数リテラルをサポートしようというものだ。60進数というのは、現実世界では良く使うのだ。例えば、我々は慣習的に、時間を60進数で表す。しかし、60進数を表現するには、文字が足りない。大文字小文字のアルファベットを使うのは、まったく直感的ではない。そこで、昔から良く使われていた文字を使おうというものだ。ペーパーの言葉を借りると、「誰にも遣われてゐない表記法を發明するよりも、古バビロニア時代から用ゐられてゐて、歴史的に実践されてゐた楔形文字を使いませう」、と言う事になる。
そう、我々はハンムラビ法典が記されたのと同じ文字を使って、60進数を表記するのだ。君達の言葉でいえば、温故知新という事だね。ワーオ! I'm a confucianist!
具体的には、Unicode 5.0.0 (July 2006) から採用された、CUNEIFORM Numberを用いる。
使い方はとても簡単だ。例えば、896を表したいとしよう。 60進数では、896 == 10×60+4×60+50+6 となるので、"𒌋𒐼𒐐𒐋" となる。君のOSが楔形文字を入力する環境に恵まれていないとしても、問題は無い、例えばHTMLのエンティティでは、𒌋𒐼𒐐𒐋、という表記になる。C++では、\U0001230B\U0001243C\U00012410\U0001240Bだ。もし君の環境に、楔形文字フォントがインストールしてあるならば、これは読めるはずだ。Unicodeで表現できるすべての文字のフォントをインストールしておくことは、とても重要だ。マイクロソフトは、その重要さがわかっているからこそ、Windows Vistaに、300メガバイト以上ものフォントを標準で入れておくことを決断したのだ。
ちなみに、日付は 2008-04-01 である。つまりは、そういうことである。
2008-05-20
魔法のアルゴリズム
最適化が好きで好きで、main関数の中身をretだけにしてしまった原理主義の皆さん、こんにちは。私はすべてのコードを厳格な規格準拠で書くことを布教しているhitoである。今回は、すばらしいビット演算の妙技について語ろうと思う。
人は何故、最適化をしたがるのか。思うに、これは完全な自己満足のためだけに行われているのではないかと思う。確かに、プログラマは高速なコードを望むし、ユーザはすばやい処理速度を望む。しかしながら、ムーアの法則は、CPUのクロック数からコア数に土俵を移したとはいえ、いまだもって有効であり、スケーラビリティのあるコード、あるいは処理内容であれば、現在の遅いプログラムは、数年後には満足できる速度になっているだろう。
とはいえ、最適化という名の宗教の原理主義者たちの声に耳を傾けてみるのも、たまにはひつようだ。一体何が悪いかといって、条件分岐こそ、諸悪の根源である。パイプラインをストールさせ、キャッシュミスなど引き起こす。とはいえ、条件分岐を用いないわけにも行かない。しかし、そこには抜け道がある。ビット演算だ。
例えば、次のような典型的なコードがあるとする。
inline int min(int x, int y)
{
if ( x < y )
return x ;
else
return y ;
}
残念ながら、このコードには条件分岐がある。これはとても遅い。条件分岐は、現代のプロセッサにとって最悪のコードだ。そこで、このようにすればよい。
inline int min( int x, int y)
{
return x + ( ( (y-x) >> (sizeof(int)*8-1) ) & (y-x) ) ;
}
inline int max( int x, int y)
{
return x - ( ( (y-x) >> (sizeof(int)*8-1) ) & (y-x) ) ;
}
Lo and Behold! このコードは魔法である。汝、謹んでこれを拝領し、その挙動に対して、豈疑うことなかれ。
もちろん、このコードは万能ではない。ポータビリティがないのだ。このコードは、最上位ビットは符号ビットであり、シフト演算で、その符号ビットもシフトされることを前提にしている。規格では、シフト演算の引数に、負数を用いてはいけないことになっている。
もし君が、これらの魔法に興味がある異端者ならば、The Aggregate Magic Algorithms は、一日費やすことができる、楽しい読み物になるだろう。
なぜこんなことを書いているのか。それは、x264に、以下のコードがコミットされたからだ。
static inline int x264_median( int a, int b, int c )
{
- int min = a, max =a;
- if( b < min )
- min = b;
- else
- max = b; /* no need to do 'b > max' (more consuming than always doing affectation) */
-
- if( c < min )
- min = c;
- else if( c > max )
- max = c;
-
- return a + b + c - min - max;
+ int t = (a-b)&((a-b)>>31);
+ a -= t;
+ b += t;
+ b -= (b-c)&((b-c)>>31);
+ b += (a-b)&((a-b)>>31);
+ return b;
}
好きではない類のコードだ。
あっと驚く技術
Talks Blaise Aguera y Arcas: Jaw-dropping Photosynth demo
via Digg This Technology Will Blow Your Mind.
まあ、実用かどうかはともかく、面白いデモだ。というより、むしろDiggのこのコメントに笑ったのだが。
I'd rather have a technology which blows my... nevermind
--Technology that blows on your hot pizza because I hate it when I burn my mouth.
2008-05-19
はぐれメタルについて
なかなか面白い考察ではあるが、まったく的外れだ。ドラクエ好きならば、エニックス公式の、魔物たちを詳細に記した大著、「ドラゴンクエスト モンスター物語」1989年発行 ISBN4-900527-08-4 ぐらいは手元に持っておくべきである。以下に話を要約する。
まず、スライムというのは、アレフガルド大陸の中央部にある、小さな湖に住んでいた。しばらくすると陸で暮らせるようになった。しかし、個体数の劇的な増加により、その土地では暮らせなくなり、住処を求めて、東西南北に旅立った。そのうち、東に向かったのは、一番小さな集団だったのだが、行けども行けども、不毛な土地ばかりであった。そこには毒の沼地がたくさんあり、腐った死体が温泉代わりにつかっていた。スライム達は腐った死体の、ここは快適だという言に騙されて(とはいえ、腐った死体たちにはだます意図はなかったのだが)、毒の沼地に飛び込んでみたが、体が潰れてしまった。しかし、驚くべきことに、スライムたちは死ななかった。こうして、バブルスライムが生まれた。
途中を省略するが、このバブルスライムがあるとき、困っているエルフに出会った。エルフは、毒の沼地に、金の鏡を落としてしまったのだ。バブルスライムたちは、一生懸命この落し物を探して、ついに見つけ出した。そして、エルフから、天上界についての話を聞き、自分達も天上界で暮らしたいと願った。精霊ルビスの力によって、はぐれメタルは体が銀色に変わり、身も軽くなって、天上界へ昇っていった。
ちなみに、メタルスライムはまた別の話である。メタルスライムとは、たまたま、身かわしの服を装備したスライムたちが、鉱山で灼熱したミスリル銀を浴びてしまい、すばやさとしゅびりょくを身に着けたものだ。
追記:
他のスライム達の概略もスライム年代記にまとめてみた。
2008-05-17
合衆国にノートPCを持ち込む際の心得
Taking your laptop into the US? Be sure to hide all your data first
合衆国の出入国管理員は、君のノートPCを操作する権限を持っている。文句を言っても仕方がない。既にそう決まっているからだ。とれるのは、対策だけだ。
暗号は役に立たない。なぜならば、彼らは君にパスワードを入力しろと迫るからだ。もし拒否すれば、何日も拘束されるだろう。物事をより厄介にするだけである。
したがって、一切の個人情報を持ってはならない。PCのHDDにいれるのは、OSとソフトウェアに必要なデータだけにすること。自分の個人情報は一切入れないこと。文書、画像、ブラウザの履歴などの個人情報は、一切消すこと。HDDのセクタに何度も書き込む強力な削除ソフトウェアを使って完璧に消すこと。必要なデータは、ネットワーク上に置いておく事。もちろん、そのネットワークを示す手がかりを残してはならない。
参照記事では、小さいフラッシュメモリに暗号化してデータを入れて隠し、見つかったらごまかすなどという方法も推奨しているが、これをしてはならない。最も確実なのは、先にも述べたごとく、一切のデータはネットワーク上に暗号化して置いておく事だ。そして、そのネットワークを示す手がかりを頭の中にだけいれておけば、連中も見つけられないというわけだ。
合衆国にお出かけの際は注意されたし。
Flash Player 10のGPUアクセラレーションについての誤解
What does GPU acceleration mean?
Flash Player 10では、wmodeをdirectかgpuにすることで、GPUアクセラレーションを利用できる。directは最も早く、DirectDrawもしくはDirectX 9を使う。gpuはスケーリングなどをGPUにまわし、最終的な描画はソフトウェアで行うらしい。ただし、盲目的に設定すべからず。既存のFlashは遅くなることもあり得る。なぜならば、GPUが苦手な処理というのもあるからだ。最もパフォーマンスが上がるのは、動画の再生らしい。必要なGPUのスペックとしては、VistaのAeroが動くぐらい。いままでは、wmodeをopaqueにすると、DirectDrawで描画したらしい。古臭い。
すべてがうまく解決するわけではない。GPUアクセラレーションを使うと、表示される内容は、必ずしもすべての環境で一致するわけではない。ブログでも言及しているように、GPUの世界は、ハードウェアやドライバのバグなどいろんなことがあるので、難しい。
2008-05-16
C++標準化委員会の会議に参加したいが
Faith and Brave - C++で遊ぼう:C++標準化委員会の会議に参加してきました
こんなことが行われていたとは。参加したいのはやまやまだが、京都に住んでいる身としては、少しばかり敷居が高い。行けない事もないわけではないのだけれど。
むしろ、早く仕事を見つけなければならない。この手の会議に参加したがる程の理想主義だから、全然仕事が決まらないのだ。何社か面接に行ったが、何が気に食わないかといって、出てきた社員の技術に関する冷め切った態度ほど、嫌なものはない。
しかし、そういう偉そうな事を言えるほどのグルであるかと問われると、いかに理想主義で尊慢な私であったとしても、流石に言えない。とくにここ数年は、規格ばかり追いかけてきた。知っていることといえば、恐ろしく変態的なC++のトリックぐらいなものだ。後はWin32 APIか。HTMLやCSSをまともに学んだのも今年に入ってからであるし。
実は、まだフェンリルの求人に申し込むかどうか迷っている。既に、「ああ、ここで働いたら一生凡人として糞コードを書き続けていくんだろうな」、というところに、面接に行ってしまった。どうも、プログラマー板に書かれているような悲惨な職場は、本当にあるらしいと実感した。
Sleipnirは三年前まで良く使っていたので、どのようなソフトウェアかは知っているし、そのようなフリーウェアを作って、さらにそれで起業までしたフェンリルは、面白そうではある。受けるとしても、IEを利用するコードを書いたことは一度もないし、どのようにして書くのかも、まったく知らないので、受かるかどうか。どうするかねぇ。こうしていても始まらないが。
汚物は消毒だ~
【都江堰(とこうえん)(中国四川省)武本光政、浦松丈二】15日、生徒約900人が生き埋めになったとされる都江堰市の聚源(じゅげん)中学校では、朝になっても救出作業は始まらなかった。「子供を置き去りにできない」。地震発生から「72時間」が経過した午後も、生徒の親たちは手作業で懸命にコンクリート片を取り除いた。
午前8時。地元住民や遺族ら約50人が学校の前にいた。倒壊したのは築20年以上の鉄筋コンクリートの校舎。直径約1センチの鉄筋がぐにゃりと曲がっていた。「建築がしっかりしてない。腐敗した人間が、こんなのを造っている。責任者は遺族に謝罪すべきだ」。男性(40)は訴えた。
聚源中は生徒数約1700人。地震発生時は18学級の約1000人が授業を受けており、9割が生き埋めになったとみられる。「世界でたった一人の、かわいい子だったのに……」。2日前に遺体で見つかった王林君(15)の母親(36)は、この日も現場で泣いていた。「まだ、ここを離れられないの……」
午前9時過ぎ。成都市の疫病コントロールセンターの白いワゴン車が到着。遺体が多数埋まっている場合、感染症が発生するおそれがあり、白衣を着た職員が校舎のがれきに向かってホースで消毒液の散布を始めた。
午前11時過ぎ、死者を弔う爆竹が鳴った。赤いろうそくが2本供えられていた。生徒の親ら数人が、手作業でがれきを掘り返し始めた。「建物から離れなさい」。警察官の指示で、がれきの前からいったん人が消えた。午後2時28分。発生から72時間が経過した。直前に医師や看護師が姿を見せたが、早々に立ち去ってしまった。
「1、2、3!」。午後3時半、男性数人が再びがれきの撤去作業を始めた。現場に散乱する金属製のタライにコンクリート片を入れ、バケツリレーのようにして運び出す。時間とともに人が増え、夕方には20人近くになった。ほとんどの人は素手のまま。男性の指には血がにじんでいた。
「何の説明もなく救出を打ち切るなんて許せない」。解秀英さん(38)は涙ながらに憤った。「スポーツが得意な子だった」。がれきの下にいるかもしれない2年生の息子、巴飛君(15)を丸3日、思い続けている。近くでは、授業を休んでいて難を逃れた李力君(16)ら3年1組の4人が死者に贈る紙銭を燃やしていた。
三日程度なら、まだ生きている、助けられる可能性のもあるのに、文字通り消毒している。さすがは宗主国様。まあ倫理的な問題を無視して、疫学の観点から見ると、理に適った行動ではある。なぜならば、既に死んでいる者もいるので、遺体をそのまま放置すると、伝染病などが流行する危険もある。しばらくは遺体を除去できないことは明白であるので、せめての対策として、消毒液でもまいておくのは、効果があるのかもしれない。
,,、,、、,,,';i;'i,}、,、
ヾ、'i,';||i !} 'i, ゙〃
゙、';|i,! 'i i"i, 、__人_从_人__/し、_人_入
`、||i |i i l|, 、_)
',||i }i | ;,〃,, _) 汚物は消毒だ~っ!!
.}.|||| | ! l-'~、ミ `)
,<.}||| il/,‐'liヾ;;ミ '´⌒V^'^Y⌒V^V⌒W^Y⌒
.{/゙'、}|||// .i| };;;ミ
Y,;- ー、 .i|,];;彡
iil|||||liill||||||||li!=H;;;ミミ
{ く;ァソ '';;,;'' ゙};;彡ミ
゙i [`'''~ヾ. ''~ ||^!,彡ミ _,,__
゙i }~~ } ';;:;li, ゙iミミミ=三=-;;;;;;;;;''
,,,,-‐‐''''''} ̄~フハ,“二゙´ ,;/;;'_,;,7''~~,-''::;;;;;;;;;;;;;'',,=''
;;;;;;;;''''/_ / | | `ー-‐'´_,,,-',,r'~`ヽ';;:;;;;;;;, '';;;-'''
''''' ,r'~ `V ヽニニニ二、-'{ 十 )__;;;;/
devOpera Articlesに日本語記事が出て驚いた
Opera Dragonfly 入門 (Japanese)
Introduction to Opera Dragonfly←元記事
まあ、単に英語記事の翻訳なのだけれど、何故驚いたかというと、いままで日本語記事なんてひとつもなかったからだ。DevOpera ArticlesをRSSで購読していたのだが、いきなり日本語が現れたものだから、予想外に驚いたわけだ。これ、日本語読めない奴がRSSチェックしてて、いきなり日本語が現れたら、私以上に混乱するんじゃなかろうか。何故、Dragonflyだけ日本語訳をだそうと決断したのか不明だ。この記事以外に一切、英語以外の記事はないのだけれど。
それからもうひとつ。これは、求人なのだが、Operaの開発ブログでやることかね。「Operaはオープンソースになるべきだと主張している君も、ウチに来て働けばいいよ」、の下りは、大いに笑った。
2008-05-14
IE8はXHTMLをサポートしないんじゃないか
IEチームとのチャットログを読むにつけ、IE8はまだ、XHTMLをサポートしないのではないかと思われる。
なぜIEがこれまでXHTMLをサポートしていないかというと、理由は単純で、厳格なXHTMLパーサを使っていないからだ。いまのIEがXHTMLを解釈しているように見えるのは、HTML用の寛容なパーサのためだ。IE8でも、まだサポートしないのではないかと思われる。
しかし、XHTMLが、本当に使われる日は、来るのだろうか。XHTMLにするからには、規格に厳格でなければならない。ひとつでも文法エラーがあれば、Webサイトが一切表示されなくても、文句は言えない。
つまるところ、このブログはXHTMLに対応してない。今までXHTMLを学ばずに来た稚拙なコードが、治されないまま大量に残っているし、そもそもBlogger自体が、正しい文法のXHTMLを吐いていない。テンプレートはすべて、XHTMLだというのに。
だから、もし仮にIEがXHTMLをサポートする日が来たとしても、大半の人はtext/htmlを使い続けると思う。
2008-05-13
Importance of RSS
ブログにとって、RSSやATOMを提供するのは、とても重要だ。これらのフィード機能があれば、ブログの読者は、わざわざ更新を確認しにブログを訪れなくても、新しい記事が読める。たまに、このRSSの出力を、記事の一部分しかしていない人がいる。とくにはてなダイアリーでは、一部しか出力しないのがデフォルトになっている。残念なことだ。
さて、私がにわかにRSSを持ち上げているのは他でもない。私自身が、RSSによって、何十というブログを読んでいるからだ。RSSが提供されていれば、わざわざブログを見に行くまでもなく、RSSリーダーで、多数のブログを購読できる。実に便利だ。RSSリーダーには、クライアントやWebアプリなどの種類があるが、私が愛用しているのは、Google Readerだ。
さて、今月の初め頃だが、ふと何気なく、自分のブログを、Google Reader上で読んでみた。いままで、自分のブログのRSSがどのようになっているのか、気にとめたことがなかったが、そのあまりの貧弱な内容に驚いた。white-spaceできれいに整形したつもりのソースコードは崩れているし、Flashは表示されていない。何より驚いたのが、Google Readerでこのブログを読んでいる人が、私を含めて37人もいるということだ。他にも、はてなには、私を含めて17人が、このブログに対してアンテナを利用しているし、あるいは別のRSSリーダーを使っている人がいるかもしれない。最近の主要なブラウザは、皆RSSリーダーを備えている。これは、何とかしなければならない。
そこで、RSS経由で整形されたソースコードが読めるように、CSSに頼らず、空白は空白として使うことにした。Flashはいかんともしがたい。というのも、私はFlashの表示には、swfobjectを使っているのだが、RSSの出力には、head要素が含まれることはない。解決方法としては、すべての記事でswfobject.jsを読み込むか、あるいは埋め込むという方法が考えられる。もう少し現実的な方法としては、javascriptに頼らず、object要素を手書きするという解決方法もある。しかし、object要素の手書きは面倒だし、IE以外のブラウザでは、Eolas社の特許に引っかかるため、クリックして有効化しなければならない。結局、置換するdiv要素の中に、Flashである旨を書いておこうと思う。divの中にobject要素を仕込むというのも、ありといえばありだが、せっかくswfobjectを使っているのに、それはあまりにも面倒だ。
さて、RSS経由で読んでいる人向けの対策はいいとして、実際にブログを直接読んでいる人への対策もおろそかにしてはならない。このブログは、私の美意識にもとづいてデザインされている。例えば、記事が一度に百件も表示されるのは、読み込みが重いので好ましくないと思う人がいるかもしれないが、私はむしろ、一度に数件の記事しか表示されないブログというのは、すぐに次のリンクをたどって先を読み込まねばならず、実に不快であると考えているためだ。そのほかにも、フォントを指定しない、フォントサイズをピクセル単位で指定しない、という信念がある。ただし、ソースコードの場合だけ、Consolasを使っている。次の候補としてmonospaceフォントを指定しているので、Consolasがなくても問題は無いはずだ。また、テキストはブラウザの枠一杯に表示し、ブラウザの幅を超える場合は、ブラウザによって改行させるべくデザインしている。
気乗りがしたときにやらなければ、いつまでも放置してしまうため、以前から気になっていた部分も変更した。それは、右のサイドバーの、ラベルのことだ。今までは、一行にひとつのラベルを表示していた。これはスペースをとって仕方がないと、以前から思っていた。各ラベルはli要素の中にあるので、セレクタをうまく使い、ラベル部分のliのdisplayプロパティをinlineにしてみたが、これは失敗した。ラベルの文字列の途中で改行されてしまう。これは読みづらく、好ましくない。そこで、CSS2.1から追加された、inline-blockを使うことにした。これはうまくいった。
ただ問題は、IE7とFirefox 2は、inline-blockに対応してないということだ。しかしその場合でも、縦一列に表示されるので、まあ、問題は無いだろう。IE8やFirefox 3は対応しているようなので、来年には、ほとんどの人が、inline-blockを正しく閲覧できるだろう。
2008-05-12
日記など
やれやれ、また体調を崩した。今はだいぶ回復している。
フェンリルについて調べていたのだけれど、どうもよく分からない。そもそも、住所が分からない。普通、求人をするからには、勤務地の住所ぐらい載せるものではないのだろうか。ただ、北区とだけしか書かれていない。北区のどこだというのだろう。疑問だ。
利益は広告や、Googleとの提携、あるいは他の提携会社のWebサイトに特化したブラウザの開発などで出しているらしい。
Sleipnirを使ってみたが、正直言って微妙だ。FireFoxと同じく、お気に入りのメニューが無駄な機能で埋め尽くされている。「このフォルダを開く」なんていう機能、誰が使うというのか。この無駄な機能のために、メニュー一行とセパレータ一個が使われ、実際のお気に入りを開くために、マウスを余計に動かさなければならない。
Tridentは正直言って使い物にならないので、Geckoに切り替えてみたが、正直SleipnirでGeckoを使うぐらいならば、Firefoxを使いたい。プラグインも豊富にあるし。
なお、SleipnirのプラグインのSDKなどが公開されていないかと思ったら、いまだ開発中なのだろうか。よく分からない。
いまは、求人に載っている、意味が曖昧で理解しがたい質問、「あなたの過去・現在・未来へと繋がること」ということについて考えている。これは、「自分の過去と現在の現状、そして将来の目標」、という意味なのか、あるいは、「自分の、過去現在未来へと、連綿として続く、何らかの行為」、なのだろうか。
前者であれば、文の区切りがおかしい。「あなたの過去と現在、そして未来へと繋がること」、など書かれるべきであるし、そもそも、未来じゃなくて将来としたほうがいい。「繋がる」、という言葉の一般的な意味から考えても、後者だと思われるのだが、その場合も、やはり抽象的過ぎて、何がなんだか分からない。例えば、昔は1998年に制定されたC++を学んでいて、今は2003年に改定されたC++を学んでいて、将来もC++0xを学ぶであろう、などと記述するのだろうか。
まあ、C++に限れば、前者後者どちらの意味にも取れる文章が、なんとか書けるのだが。
コレだけが理解できずにこの週末を無駄に浪費した。どちらかの意味で解釈するか、メールで質問の意味を聞くべきかも知れない。
2008-05-08
BDのエンコードは大変なようです
http://www.watch.impress.co.jp/av/docs/20080508/rt059.htm
リアルタイムでエンコードするのにCore2Quadが5個も必要らしい。まあ、それはいい。速度を度外視して、画質を重視しているとしよう。しかし、それほどまでしても、まだ手動でビットレートを調整する必要があるのはどういうこった。第一、BDは30Mbps以上も動画に費やせるんだぞ。一体どんなエンコーダなんだ。不思議で仕方がない。こういう奴らがBD用のエンコードを担当しているのか。世も末だ。
返事
今の時点でどちらを選んでも結果が予見できないのならあとは自分の気分次第。
職業プログラマにならない方の結果ならば、予見できる。今後も規格のみにかかずらい、規格を崇め、規格を読み、規格を確認するコードを書き、結果が自分の解釈どおりであることに満足するだろう。何も生み出さない。どうも最近、現実から離れているようだ。昔はこうではなかった。まずコードを書き、うまく動かない場合に限り、規格を確認するような人間だった。それがどうして、こうなったのか。
京都ではなく大阪ですが、フェンリルとかいいんじゃないですか?
フェンリルって大阪にあったとは。確かに理想的だ。C++を、Windowsで使えるだろう。さて、問題は入れるのかどうか。ともかく、こうしていても始まらないので、メールを出してみよう。
しかし、フェンリルってどこにあるのだろう。北区ならば、実家から通勤に問題は無いとしても、詳しい住所が見つからない。
2008-05-07
そろそろ限界が近い
バイトでためた貯金も、そろそろ無くなりつつある。もうこれ以上は引き伸ばせない。何か、仕事を見つけなければならない。問題は、いまだにプログラマになる夢をあきらめきれない、という事だ。ああ、去年の暮れ、学校を辞めたときから、もうこの道はあきらめようと思っていたのだが、いまだにあきらめられないでいる。この憂い、人の腸を痛ましむ。実際、ストレスで体調を崩しそうだ。早いところ、何とかしなければならない。
やはり、選択を誤ったのだろうか。先見の才がなかったのだろうか。C++は学ぶところまで学んだが、その他はさっぱりやってこなかった。今年になって初めて、HTMLやCSSを学び始めた。まあ、C++と比べればだいぶ簡単だったが、やはりもっと早く学んでおくべきだった。JavaScriptは、言語自体は悪くないのに、ブラウザごとの差異が激しそうだ。
アトミックな読み書きについて
C++0xのAtomic operations libraryが、いまいち、よく理解できなかった。第一、この辺の用語からして理解ができない。happens beforeとかlock freeだとか、reorderingだとか。特に、29.1 Order and Consistencyがさっぱり理解できていなかったのだが、このブログを見て、疑問は多少解決した。
The Joys of Compiler and Processor Reordering
The Joys of Compiler and Processor Reordering: Why You Technically Need Read-Side Barriers
How Do KeMemoryBarrier and MemoryBarrier Prevent Compiler and Processor Reordering?
このブログ自体は、たまたま、Google ReaderのRecommendationsを眺めていて、目にとまったものだ。Windowsのカーネル周りをやってる人らしい。内容はとても分かりやすい。
2008-05-06
著作権、もうねアホかと馬鹿かと
どうやら、ipodなどにも課金するか、あるいはダビング10を拒否するかどうかを天秤にかけてあれこれやっているらしい。もうね、アホかと馬鹿かと。もうええよ。勝手にやっとれ。どうせ見ないし聞かないから。
しかし思うのだが、iPodに課金する場合、iTunes Storeで著作権料を徴収する必要はあるのだろうか。すでにiPodで著作権料は徴収しているのだから、いらないんじゃない。
C++0xのThreadライブラリ
今度はスレッドのライブラリの規格を読んでみることにした。
Atomic operations libraryは、まあ、特に問題は無いと思う。名前が気に入らないけれど。個人的には、read/writeのほうが分かりやすいんだけど、load/storeになっている。
肝心のスレッドライブラリはどうかというと。だいぶPOSIXよりになっている。これではPOSIX信者はいいとしても、私のようなWindows信者はどうすればいいのかと思ってしまう。がしかし、どうやら救いはあるようだ。30.1.3 Native handlesによって、Win32 APIは問題なく使えるだろう。POSIX側にとっても、問題は無い。ポータビリティはないにしてもだ。
結局のところ、C++では、それほど深く、スレッドライブラリ自体については規定せずに、ただ最小限ライブラリは用意するということなのだろうか。もう規格制定まで時間もないし。atomic oerationと、Mutexと、Condition Variableだ。ここでいうMutexは、Windowsで言えば、クリティカルセクションなのだが。
unordered_setはどのくらい早いのか。
unorderd_setの速度を調べるために、以下のコードを書いた。VC9で実行した結果、以下のようになった。
class std::set<unsigned int,struct std::less<unsigned int>,class std::allocator<unsigned int> >
insert : 0.284398
find : 0.102093
class stdext::hash_set<unsigned int,class stdext::hash_compare<unsigned int,struct std::less<unsigned int> >,class std::allocator<unsigned int> >
insert : 0.293333
find : 0.0481863
class boost::unordered_set<unsigned int,struct boost::hash<unsigned int>,struct std::equal_to<unsigned int>,class std::allocator<unsigned int> >
insert : 0.14261
find : 0.00541996
もちろん、挿入や検索の仕方に問題があるのかもしれないが、なぜMSVCのhash_setはこんなに遅いのだろうか。unordered_setとはすこし違うが、しかしVC9のhash_setは、ドキュメントにこそかかれていないものの、TR1とほぼ同じ意識したつくりになっている。std::lessを使うことになっているのが問題なのだろうか。このコードでは、hash_setはboostのunordered_setに比べて非常に遅い。挿入が倍遅いのはともかくとして、検索が10倍遅いのは、とても気になる。
いろいろなことを試した。まずスレッドの優先度をリアルタイムにしてみたが、結果は同じであった。次に、_SECURE_SCLを0としてみたが、やはり結果は変わらなかった。何故こんなに遅いのだろう。最近出た、MSVCのunordered_setも試してみたいところだが。
template < typename SET >
void check()
{
std::cout << typeid(SET).name() << std::endl ;
LARGE_INTEGER now, dt, freq ;
QueryPerformanceFrequency( &freq ) ;
SET set ;
QueryPerformanceCounter( &now ) ;
for ( unsigned int i = 0 ; i != 1000000 ; ++i )
{
set.insert(i) ;
}
QueryPerformanceCounter( &dt ) ;
std::cout << "insert : " << double(dt.QuadPart - now.QuadPart) / double(freq.QuadPart) << std::endl ;
QueryPerformanceCounter( &now ) ;
for ( unsigned int i = 0 ; i != 1000000 ; ++i )
{
set.find( i ) ;
}
QueryPerformanceCounter( &dt ) ;
std::cout << "find : " << double(dt.QuadPart - now.QuadPart) / double(freq.QuadPart) << std::endl ;
}
int main()
{
for ( int i = 0 ; i != 5 ; ++i )
{
check< std::set< unsigned int > >() ;
check< stdext::hash_set< unsigned int > >() ;
check< boost::unordered_set< unsigned int > >() ;
}
}
64bitコードっていつになったら流行るんだろう。
x264の64bitビルドができない。どうも、いまのWindows用64bitコードは、テストされてないらしい。レジスタの利用があまりにも変わってしまって、どうせコンパイルできたところで、動かないだろうとのことだった。やれやれ。
実際、Windowsにおける64bitコードは、全然一般的ではない。ドライバなどは64bit版もそろっているので、いますぐ64bitのWindows移行しても問題ないのだが、肝心の64bitコードはいつになったら主流になるのだろう。
第一、いま64bitのコードを書こうとしても、環境がそろっていない。VC9 Expressは、x64コードを吐くコンパイラが入っていない。まあ実際、今はまだ、それほど必要そうにない。
仕事が見つからない。2chでネタにされるような、酷い地雷というか、ブラック会社は、意外と多いようだ。面接だけでそれが推し量られるのはどうかと思う。64bitコードを吐くような仕事をしてみたいものだけれど。でも時代は猫も杓子もWebだよな。HTMLとCSSは簡単に覚えられたけれど、現行のJavaScriptは、どう考えても使いやすいとは思えない。GCを悪用したようなクロージャは確かに面白いけれど、どう考えてもGCの敵だとしか思えない。あんな汚いテクニックよりは、言語機能を付け加えたほうがマシなんじゃないかと思う。C++を崇拝してる自分が言うのもなんだけれど。プロトタイプじゃなくて、クラスの概念が欲しい。つまりは、ECMAScript Fourth editionに期待しているわけなのだけれど。でもあれは、もはや別物だよなぁ。別の名前をつけたほうがいいんじゃないかと思うのだけれど。
2008-05-05
C++0xのunordered コンテナ
N2588 Working Draft, Standard for Programming Language C++
unorderedコンテナは、内部的には、まあ、ハッシュだ。現在のSTLの、map、multimap、set、multisetのハッシュ版に相当する、unordered_map、unordered_multimap、unordered_set、unordered_multisetが存在する。
使い方はとても簡単。現在のmapやsetを使う場合と、なんら変わらない。いままで、まあ、あれは、単なるハッシュだろうと思って、別に気にしなかったが、実際に規格を読んでみても、やはり、特に気にする必要は無さそうだ。私のような素人は、中身を気にせずに、定数時間で同じ要素を探せるmapやsetとして使えばいい。
ただ、気にならないことが無いわけでもない。
まず名前だ。なぜ、unorderedなのか。hashではだめなのか。C++の規格というのは、具体的な実装方法を規定しているわけではないので、実装を連想させるような名前はダメなのだろうか。しかし、unordered_mapなどとタイプするのは、いささか面倒なのだが
それから、bucketという概念も気になる。bucketの個数や容量、使用量を取得するメンバがあり、さらには、あるキーがどのbucketに属するかを取得するメンバもある。しかし、bucketそのものにアクセスする方法は無い。bucketそのものにアクセスできないのに、あるキーが何個めのbucketに属しているかのインデックスを返されたって、一体なんの役に立つのだろう。
追記:
bucketにアクセスするlocal_iteratorというものがあった。しかし解せないのは、bucket単位でアクセスできる利点だ。
>Keys with the same hash code appear in the same bucket.
規格では、同じハッシュ値のキーは同じbucketに入ることしか規定されていないように読める。つまり、似たようなハッシュ値のキーが同じbucket、あるいは隣接するbucketに入るとは書かれていない。bucketという概念をエンドユーザに提供する利点が分からない。
追記2:
同じハッシュ値が同じbucketに入ることが保障されているので、似たようなキーから、同じハッシュ値が生成されるようにしておけば、似たようなキーが同じbucketに入る。コレを利用して、大量のキーから、似たようなキーを得ることができる。キーの値が偏っていない場合に特に有効。しかし、そんなに使うかなぁ。
2008-05-04
2008-05-03
2008-05-02
RFC 5242 超汎用文字コード
RFC5242 A Generalized Unified Character Code: Western European and CJK Sections
世の中には、文字コードがさまざまある。ASCIIは最も有名だろう。日本語を表す文字コードだけでも、本当に大量にある。
例えばJISコード。これは糞もいいところだ。まったくもってコンピュータで処理したいような文字コードではない。何とかマシにしようと、マイクロソフトはシフトJISを作った。JISよりはマシだが、実際色々と問題が多い。一体、あるバイトが、一バイト文字なのか、あるいはマルチバイトの二バイト目なのかが、簡単に判別できない。最悪、文字列の先頭までたどる必要がある。マイクロソフトのほかにも、EUC-JPなんてものを作った奴らもいる。やめてくれ。これ以上混乱させるな。
このカオスな状況を打破し、全世界の文字を、ひとつの文字コードに統一しようと、Unicodeが作られた。これは16bitで、すべての文字を表現できる……はずだった。
最初のUnicode規格が公開されてからというもの、残っていた未登録領域の割り当てをめぐって、大量の文字が殺到した。
チャイニーズやジャップどもは、「漢字」と呼ばれる、未開で野蛮な表意文字を、実に一万五千も、新たに登録しようとした。また、コリアンというリテラシーの無い民族は、ハングルという、表音文字にもかかわらず、1万1172文字もあるというフザけた文字を、すべて登録すべきだと主張した。その他にも、ヒエログリフなどの、死語となった文字を含めるべきだという要求が大量に来た。
哀れむべきは、まんじとハーケンクロイツ、卍と卐だろう。ああ、汝は実に三千年の歴史を持っているのだ。インドを発祥とし、仏教文化に深く影響を与えてきた、偉大な文字よ。それなのに、今の扱いはどうだろう。マイクロソフトの文字コード表は、U+5350を表示しない。他の文化と歴史を重んずることのない西側の人間のせいである。ああ、U+534DとU+5350よ。かつてはお前を家紋とする日本人もいたというのに。
こうして、哀れUnicodeは、その崇高な目標を達せず、数ある文字コードの中のひとつ、という地位に成り下がってしまった。いずれはUnicodeに収束していくと思われるが、いまだにシフトJISを使うジャップと、EUCを使うアカの手先、そして最悪な、ASCIIという7bit文字の世界に生きる西側の連中は、いまだに多い。
もういい。一体文字コードというのは、文字を表すのだ。そも、文字というのは、我々の話す言語を、符に置き換えたに過ぎぬ。もしそれ、複数の文字が、まったく同じ形を有するならば、それは同じ文字に異ならず。それが、RFC5242である。
いい加減に疲れた? うん、まあ、この辺にしておこう。ざっと説明すると、RFC5242というのは、文字そのものではなく、文字の形を表現する文字コードである。縦横の線であるとか、点であるとかを表現することによって、文字を表現する。もし、まったく同じ形の文字があれば、それは同じ文字である。それってアウトラインフォントだよねぇ。CJK文字を表現するのに、一文字何百バイト必要になるんだろう。超可変なマルチバイト文字コードになるだろう。
空白はどのように記述すればいいのか
ちなみに、Wikipediaによると、以下の文字が空白として登録されているらしい。
U0009-U000D (Control characters, containing TAB, CR and LF)
U0020 SPACE
U0085 NEL
U00A0 NO-BREAK SPACE
U1680 OGHAM SPACE MARK
U180E MONGOLIAN VOWEL SEPARATOR
U2000-U200A (different sorts of spaces)
U2028 LSP
U2029 PSP
U202F NARROW NBSP
U205F MEDIUM MATHEMATICAL SPACE
U3000 IDEOGRAPHIC SPACE
ここで欲しいのは、スペースのある空白だ。一体どれを使うべきなのか。結局、日本人としてはU+3000が使いやすい。ちなみに、U+00A0はあまり使いたいとは思わない。なぜならば、これは文字通り、NO-BREAK SPACE なので、ブラウザで表示させると、狭いウインドウからはみ出してしまうという、あまりよろしくない挙動をする。
前にも失敗したように、CSSのwhite-spaceは地雷だし。
ちなみに、日本人だから、空白記号がどうこう言えるのだが、西側には、背景色と同じ色か、あるいは通過色の画像ファイルを使うなんて事を本気で言い出す連中もいるらしい。まあ、連中はASCII外の文字を、直接入力する環境がないし。そういう点から見ると、CJKの世界に住んでいる人間は、Unicodeに関しては結構恵まれているのだろうか。
ちなみに、このUnicodeの空白記号を恐れることなく使う兵達がいる。いやはや。
2008-05-01
HTML5のscoped属性つきstyle要素の使い方が間違っていた
scoped属性の着いたstyle要素は、Flow contentの中に記述することができる。つまり、昨日のように、p要素の中に記述することはできない。
記述できる場所は、何の意味も持たないdiv要素の他は、HTML5で新しく作られた、Sectioning content(bodyに加えて、section, nav, article, aside)の中ぐらいだろう。headerとfooter、addressなんていう要素もあるにはある。
HTML5とは関係ないが、これからは、コードにもbr要素を使うことにした。これまでは、CSSを使って、"white-space : pre-wrap ;" としてきたが、IEが対応していないのはまだいいとして、RSS経由で読むと、当然動くわけもなく、やはりコンテンツとして改行が必要な場合は、改行要素を使ったほうがいいという結論に達したためだ。
ああ、以前はdivとclassを使い、いまは.post p > codeを使っている。しかも、white-spaceを使うかどうかでカオスになっている。以前のブログのコードの修正はめんどくさいのでやる気が起きない。
言うまでもなく、記述したいのはコンテンツだ。マークアップではない。なにかこう、普通のテキストで文章さえ書いておけば、そのテキストに対して、自動でマークアップを適用できるような機能が欲しい。
アーサー王の死の時代考証について
トーマス・マロリー卿の書いたアーサー王の死を読むと、当時の騎士は何十キロもあるプレートアーマーを着用の上、盾と長剣を持って屈強な馬に乗り、ランスをかざしてジョストを行ったように読める。
ところで、そもそも、アーサー王という人は、五世紀から六世紀ごろを生きていたとされる人物である。一方、我々ファンタジー好きが良く知る、プレートアーマーは、十四世紀からのものである。というのも、西洋で鋼を大量に作れるようになったのは、ふいごが登場する十五世紀以降の事である。一応、定義から言えば、プレートアーマーというものはあったが、私にはラメラーと何が違うのか良く分からない。チェインメイルならあったのではないかと思う。
剣についても疑問だ。よくあるアーサー王の絵には、まるで十字軍が使っていたような十字架の形の柄をした剣が描かれているが、そもそも当時は鋼がなく、そんな細身でかっこいい剣が作れたとは思わない。もろい木炭まじりの鉄だから、剣身は不恰好に太かったはずだ。ランスなんてあったかねぇ。
まあ、全イングランドの支配者、アーサー王なんてのは、そもそも存在しなかったのだから、どうでもいいといえばどうでもいいのだが。