Archives

October 2008 の記事

使いやすくてびっくりした!

YouTube gesture10key改造版(g10k3)デモ on 03
↑大変わかりやすいです。


詳細は下記から
gesture10key/gesture10keyr

様々なバリエーション
gesture10key改造ファイル


●他の sip データも探してみました。
どれも工夫されたものばかりで良く作り込まれています。


hp49g+
とあるhx2490bユーザーのメモ hp49g+
  ダウンロードはこちらから


ニコタッチ (2タッチ/ポケベル入力)
ときどきもばいる p905i_nt_sip


タイ語、HTC Touch Dual 風
El Camino Real 英語 日本語 タイ語 入力 スクリプト
El Camino Real HTC Touch Dual 風 各種入力パネル


emonsip
Desire for wealth emonsip

emonsip バリエーション
C_andY の iPHONE + WINDOWSMOBILE メモ emonsip★ネイル用スキン完成\(*^▽^*)/
>C_andY の iPHONE + WINDOWSMOBILE メモ emonsipスキン<iPhone系>
  C_andY の冷蔵庫

emonsip バリエーション 英語キーボード対応
Smart Phone memo emonsipのキーコードをX01HT仕様に変更成功!


ページ送りキー
伊藤浩一のW-ZERO3応援団 pageupdownsip3color


srkeyboardsip 改良版
小人閑居為不善 SIPローマ字変換用スクリプト改変(続)


フルキータイプ
モバイル日記(旧ほぼW-ZERO3[es]日記?) TouchKeySip用自分カスタマイズキーボードV1.2 [WM(自作ツール未満・・・)]


他にもあるかと思います。抜けていたらごめんなさい。



x86 (IA32) の命令は Prefix を追加し op code 長を増やすことで拡張されてきました。
SSE の命令は 2byte escape 0F + 1byte opcode の空間に割り当てられています。
例えば ADDPS は 0F 58 です。バリエーションであるスカラー ADDSS は Prefix と
して F3 が追加され、SSE2 の倍精度命令はさらに 66 と F2 も加わります。

ADDPS     0F 58 ~
ADDSS  F3 0F 58 ~
ADDPD  66 0F 58 ~
ADDSD  F2 0F 58 ~


x64 (AMD64/Intel64/EM64T) の拡張レジスタ xmm8~xmm15 にアクセスするには
上記にさらに REX Prefix が追加されます。
40~4F が REX Prefix で、4bit 分のオプション bit を持っています。

ADDPS     45 0F 58 ~
ADDSS  F3 45 0F 58 ~
ADDPD  66 45 0F 58 ~
ADDSD  F2 45 0F 58 ~


IA32 命令のレジスタフィールドは 3bit しかなく、レジスタ上限は 8個でした。
64bit モードでは REX Prefix 内の機能 bit を追加して、レジスタフィールドを
4bit とみなすことができます。
これで最大 16個のレジスタを指定可能です。

REX Prefix
H---------------L
[0|1|0|0|W|R|X|B]


REX.RXB の 3bit がレジスタ/Index フィールド拡張用です。
残り 1bit REX.W が 64bit オペランドサイズの指定に使われます。

SSE4.x ではさらに opcode が拡張されて 3byte escape の 0F 38 や 0F 3A で
始まるスペースが割り当てられています。(SSE5 は 0F 24)

// SSE4.1
DPPS      66 [REX] 0F 3A 40 ~
BLENDPS   66 [REX] 0F 3A 0C ~
EXTRACTPS 66 [REX] 0F 3A 17 ~

// SSE4.2
CRC32     F2 [REX] 0F 38 F0 ~


追加命令が増える度に命令は長くなる一方です。

AVX でも命令を区別するために、さらに VEX Prefix が定義されています。
今までの命令 Prefix と違うのは、最初から 2~3byte の長さを確保したことと、
その中に従来使われていた Prefix や opcode を組み込んでしまったことです。

例えば SSE 命令の前に付く 66/F2/F3 Prefix は無印を含めて 4通りしかありません。
これは 2bit にエンコードできます。

最初から REX も opcode の機能 bit に組み込んでしまえば 8bit フルに割り
当てる必要もなくなります。

必ず 0F が含まれるとわかっているなら、これを命令から取り除くことが可能です。

2byte-VEX (C5+1byte)
H---C5---L  H---------------L
[11000101]  [R|V|V|V|V|L|P|P]

3byte-VEX (C4+2byte)
H---C4---L  H---------------L   H---------------L
[11000100]  [R|X|B|M|M|M|M|M]   [W|V|V|V|V|L|P|P]


2bit の PP がまさに Prefix の有無を表しています。
 0= なし
 1= 66
 2= F3
 3= F2

L は 256bit (ymm) モードの指定です。0 なら 128bit (xmm)

R X B W は REX Prefix に含まれていた機能 bit です。

4bit の VVVV は追加のレジスタフィールドです。
AVX は 3オペランド命令で source/destination が分離されているので、増えた
レジスタオペランドの指定にここが使われます。

5bit の MMMMM は拡張命令用フィールドでその多くが予約されています。
現在定義されているのは次の 3パターンのみ。
 1= 0F (2byte escape)
 2= 0F 38 (3byte escape)
 3= 0F 3A (3byte escape)

2byte-VEX には MMMMM は含まれていませんが、無条件で 0F とみなします。

これで上で紹介した多くの命令が VEX Prefix で置き換えられることがわかります。
VEX Prefix 以降の 1byte opcode や ModR/M 等のフィールドには互換性があります。

また MMMMM の多くが余っているので、例えば、まず無いとは思いますが

MMMMM: 4= 0F 24

と定義してしまえば AMD SSE5 の VEX 化も可能でしょう。
今後はおそらく命令が長くなることもなく ぐっすり眠れます。


Intel AVX は IA64 のような全く新しい互換性のない命令セットではなく、
x86 (IA32) の命令を圧縮してエンコードしたものです。

追加されたレジスタフィールド以外はこれまでの命令や prefix と同じもの。
従来の命令形式にデコード可能な互換性を保っています。

命令長は必ずしも短くなるわけではなく、ADDPS などは VEX 化することで 1byte
増えそうです。
ただし x64 拡張レジスタへアクセスする場合は長さは変わらず、source と
destination を別指定できるため場合によっては MOV 命令を減らすことができるでしょう。


関連エントリ
Intel AVX その2 転送
Intel AVX



やはり、上位 128bit と下位 128bit を横断する命令は限られているようです。
基本的には 128bit 4要素の SSE 命令を、一度に 2個演算できるのが AVX の
256bit 命令です。

Intel AVX
Intel-AVX-Programming-Reference-319433003.pdf

上下 128bit への任意転送は 128bit 単位のものが多く、SHUFPS/SHUBPD のような
32/64bit 単位で任意に入れ替えたり転送する命令がみあたりません。
float 8個や double 4個の演算時でも、値を入れ替える場合に 128bit 転送命令を
組み合わせる必要がありそうです。

256/128bit 間の転送には VEXTRACTF128, VINSERTF128 が使えます。
上位下位どちらの 128bit を使用するか選択します。
以下 256bit レジスタの ymm.low を下位 128bit、ymm.hi を上位 128bit と表記します。

VEXTRACTF128  xmm1, ymm2, 0   // xmm1= ymm2.low
VEXTRACTF128  xmm1, ymm2, 1   // xmm1= ymm2.hi

VINSERTF128 ymm1, ymm2, xmm3, 0 // ymm1.low= xmm3,  ymm1.hi= ymm2.hi
VINSERTF128 ymm1, ymm2, xmm3, 1 // ymm1.low= ymm2.low,  ymm1.hi= xmm3

VINSERTF128 は VMOVSS 系の部分更新命令なので、合成用の追加のレジスタが増えて
います。
実際は ymm2 に dest (ymm1) と同じレジスタを指定するケースが多いかもしれません。

128bit 単位の入れ替え命令として VPERM2F128 があります。
2つのソース ymm2,ymm3 の任意の 128bit を組み合わせて ymm1 に代入できます。

VPERM2F128  ymm1, ymm2, ymm3, 0  // ymm1.low= ymm2.low,  ymm1.hi= ymm2.low
VPERM2F128  ymm1, ymm2, ymm3, 1  // ymm1.low= ymm2.hi,   ymm1.hi= ymm2.low
VPERM2F128  ymm1, ymm2, ymm3, 2  // ymm1.low= ymm3.low,  ymm1.hi= ymm2.low
VPERM2F128  ymm1, ymm2, ymm3, 3  // ymm1.low= ymm3.hi,   ymm1.hi= ymm2.low
~

VBROADCAST は、唯一 32,64,128bit の任意の値を 256bit に転送できます。
複製されます。

VBROADCASTSS   xmm1, m32   // xmm1 32bit x4= m32, 上位 128bit は 0
VBROADCASTSS   ymm1, m32   // ymm1 32bit x8= m32
VBROADCASTSD   ymm1, m64   // ymm1 64bit x4= m64
VBROADCASTF128 ymm1, m128  // ymm1 128bit x2= m128

F128 は SS, SD, PD, PS に相当し、128bit を表すようです。
(Larrabee では F256 がありそう)

これ以外の命令はほぼ 128bit SSE ×2 個分に相当します。
その他特殊な命令は次の通り。

VZEROALL
VZEROUPPER

VZEROALL は、ymm0~15 レジスタすべてをゼロクリアします。
VZEROUPPER はすべてのレジスタの上位 128bit のみクリア。
これらの命令は、レジスタの部分書き換えが発生してしまう Legacy SSE 命令の
レジスタ依存を断ち切ることが出来ます。

メモリとレジスタ間で条件付き転送が出来るようになっています。
転送単位は 32bit or 64bit で、転送するかどうか mask レジスタで指定します。
mask 値は転送データと同じサイズで、最上位 bit (符号) で判断します。
つまり負なら転送。

VMASKMOVPS  xmm1, xmm2, m128  // 32bit x4, xmm2 が mask
VMASKMOVPS  ymm1, ymm2, m256  // 32bit x8, ymm2 が mask
VMASKMOVPD  xmm1, xmm2, m128  // 64bit x2, xmm2 が mask
VMASKMOVPD  ymm1, ymm2, m256  // 64bit x4, ymm2 が mask
VMASKMOVPS  m128, xmm1, xmm2  // 32bit x4, xmm1 が mask
VMASKMOVPS  m256, ymm1, ymm2  // 32bit x8, ymm1 が mask
VMASKMOVPD  m128, xmm1, xmm2  // 64bit x2, xmm1 が mask
VMASKMOVPD  m256, ymm1, ymm2  // 64bit x4, ymm1 が mask


例えば xmm の各 32bit をシェーダーのように .x .y .z .w で表現すると

xmm2.x= -1
xmm2.y= 0
xmm2.z= -1
xmm2.w= 0

の場合

VMASKMOVPS xmm1, xmm2, m128

は次の転送を行います。

xmm1.x= m128[0]
xmm1.y= 0
xmm1.z= m128[2]
xmm1.w= 0

選択しながら読み出せるため便利ですが、mask レジスタを用意する必要があります。
命令も 3byte 長 VEX (0F38) に含まれています。


積和命令 FMA は AES と同じように別カテゴリに分かれています。
命令フィールドも 0F3A の 3byte VEX で独自のものです。

AVX は基本的に SSE をカバーしていますが SSE1~SSE4.1 までです。
SSE4.2 と AMD SSE5 は含まれていないようです。
積和命令 FMA~ FNMA~ は SSE5 と名称も機能も似通っています。
ちょうど SSE5 を VEX 拡張したかのような位置づけですが、opecode 等を見ても
関連性はありませんでした。


関連エントリ
Intel AVX




2008/10/13
Intel AVX

Intel の新しい拡張命令セットです。基本的には SSE と同じようなもの。

Intel AVX

その特徴は

・256bit になった
・積和命令
・ソース非破壊の 3オペランド命令
・命令 Prefix の圧縮
・メモリアライメント制限の緩和

など。

CPU core 数が増えて性能が向上するように、演算並列度を上げるために SIMD で
扱える bit 幅が拡張されるようです。
x64 の 64bit RAX~ レジスタのように、128bit XMM レジスタが 256bit YMM
レジスタに拡張されています。

256bit = 32bit×8 なので float×8個の演算を一度に行うことができます。
とはいえ GPU の Shader でも xyzw までで、8要素の演算には普段あまり馴染みが
ありません。むしろ 256bit = 64bit×4 と、double で一度に 4要素扱えることに
意義があるのかもしれません。

以前 SSE5 の記事を見たときに勘違いしたのが "3オペランド命令の採用" です。
てっきりソース非破壊で演算可能になったのかと思ったら積和命令のことでした。
(AMD SSE5 Shader のような新しい命令)

今度は本当です。
AVX は単なる 256bit 拡張ではなく、従来の 128bit SSE 命令も含まれています。
VEX Prefix を使った SSE 互換命令はレジスタフィールドが拡張されていて
source operand と destination operand が分離されています。
例えば ADDPS 命令の場合次の通りです。

ADDPS   xmm1, xmm2/m128        // SSE
VADDPS  xmm1, xmm2, xmm3/m128  // AVX
VADDPS  ymm1, ymm2, ymm3/m256  // AVX

積和系 FMA 命令だと 4 operand です。

VFMADDPS  xmm0, xmm1, xmm2/m128, xmm3
VFMADDPS  xmm0, xmm1, xmm2, xmm3/m128
VFMADDPS  ymm0, ymm1, ymm2/m256, ymm3
VFMADDPS  ymm0, ymm1, ymm2, ymm3/m256

SSE3 の HADDPS や SSE4.1 の DPPS もありました。

HADDPS   xmm1, xmm2/m128        // SSE
VHADDPS  xmm1, xmm2, xmm3/m128  // AVX
VHADDPS  ymm1, ymm2, ymm3/m256  // AVX
DPPS     xmm1, xmm3/m128, imm8        // SSE
VDPPS    xmm1, xmm2, xmm3/m128, imm8  // AVX
VDPPS    ymm1, ymm2, ymm3/m256, imm8  // AVX

256bit の VHADDPS も隣接 2値ごとの加算で、機能的には同じ。

問題の 256bit VDPPS ですが、8個全部の内積ではなく上位 128bit と下位 128bit
同士をそれぞれ内積した結果を返すようです。
つまり AVX の 256bit 命令とは、8個の float 演算と言うよりも 4要素の SSE 演算
自体をさらに 2つ同時に実行できると考えた方が理解しやすいようです。

残念なのが VDPPD 命令。
double×4 の内積ではなく 128bit 分 double×2 の内積を 1セット返すのみでした。
float x4 → double x4 への置き換えは簡単ではないようです。

VSHUFPS/VSHUPD も同様に上位 128bit 下位 128bit それぞれの範囲でのみ入れ替え
られます。256bit 全部入れ替えられるわけではないようです。

上位 128bit / 下位 128bit 間の転送には VINSERTF128/VEXTRACTF128 命令が使えます。
任意の xmm レジスタを ymm の上下 128bit どちらに転送するか、
または ymm のどちらの 128bit を xmm に転送するか選択できます。
ちなみに AVX では xmm レジスタへ転送を行うと上位 128bit は 0 クリアされます。

ソース非破壊だとソースを保存のための無駄な転送が減るし、3オペランドだと
演算が MOV を兼ねることが出来ます。
これらは単に命令数が減るメリットだけでなく、レジスタの部分更新が無くなるので
レジスタリネーミングの効率にも貢献するものと考えられます。

例えば MOVSS と MOVPS は AVX では次のように変化します。(m128/m256 は省略)

MOVAPS    xmm1, xmm2    // SSE
VMOVAPS   xmm1, xmm2    // AVX
VMOVAPS   ymm1, ymm2    // AVX

MOVSS   xmm1, xmm2        // SSE
VMOVSS  xmm1, xmm2, xmm3  // AVX

MOVPS は単なる転送命令なので 2 operand のみ。

MOVSS は bit0~bit31 のスカラーを転送する命令です。
SSE では xmm1 の bit32~bit127 は置き換えず保持します。

AVX では dest は全書き換えが原則なので、機能互換性のため bit32~bit127 を
入力する operand が追加されています。(VINSERTF128 も同様)

MOVSS    xmm1, m32    // SSE
VMOVSS   xmm1, m32    // AVX

メモリから読み込む場合 xmm1 の余った bit は 0 クリアされます。
AVX では xmm への転送は上位 128bit をクリアすることになっているため、
bit32~bit255 すべてが 0 になります。
AVX 対応 CPU で SSE 命令を使うと ymm の上位 128bit は非更新です。


Larrabee ではさらに SIMD が 512bit に拡張されるようです。
float だと 16個分ですが、256bit AVX の例を見ると 128bit SSE × 4 相当で
構成されている可能性があります。
また演算毎にレジスタの mask を指定できるようです。
mask の指定はおそらく入力側だと考えられます。shader のような書き込み mask だと、
AVX のルールで考えると VMOVSS のようなもの。そうでなければ GPU のように
内部でスカラー単位に分割して依存を管理しているのかもしれません。


関連エントリ
AMD SSE5 Shader のような新しい命令
SSE についてのメモ(2) SSE4など



Playstation 3 の Little Big Planet ベータをしばらくやってました。
(もうすぐ時間切れ)

little big planet

このゲーム、ほぼすべての画面で複数人同時にプレイできます。

(1) オンラインで繋ぐ
(2) コントローラを複数繋ぐ

合計 4人までです。

オンラインモードや複数人モードなどが分かれておらずシームレスです。

PS3 にローカルに繋いだコントローラからは常に参加可能で、
ポッド(メインメニュー) でも、ゲームモードで「ひとりで遊ぶ」を選んでも、
エディットモードでも付いてきます。
もともと単一のカメラなので、画面分割しなくても矛盾しません。

ゲームの「ひとりで遊ぶ」とは厳密にはプレイ人数のことではなく、
「オンライン接続の禁止=オフラインモード」を意味しているようです。


・ポッド
  メインメニューであり、個人毎のホームやロビーも兼ねています。
  フレンド登録しているプレイヤーがオンラインなら直接行くことが出来ます。
 
・ストーリー
  あらかじめ組み込まれているステージをプレイします。
  操作を覚えたりエディットで使える素材集めもここ。
  複数人で参加可能で、ネットに繋ぎたくないときは「ひとりで遊ぶ」を選びます。
  「オンライン」を選んだときはホストになります。

・クイックマッチ
  「オンライン」でプレイしているユーザーにランダムでつながるようです。
  ステージが終わるとホストの人のポッドに連れて行かれます。
  
・コミュニティ
  ユーザーが作った無数のステージを遊ぶことが出来ます。
  特に組み込みのステージとの違いもなく、複数人で同じように遊べます。

・ぼくの惑星
  自分でステージを自由に作ることが出来ます。
  アップロードすればコミュニティに登録されて誰でも遊べるようになります。

  アップロードしなくても、自分がホストの場合はポッドにいるユーザーで一緒に
  プレイすることが出来るようです。

  エディット時はオンラインユーザーは入れません。
  コントローラを複数繋いでいる場合は、最大4人まで同時にエディットできます。
  複雑なものとか大きなものは協力して作っていくことが可能で、
  二人以上でないとクリアできないトラップなども確認しながら作れます。


途中参加受け付け終了を意味するゲートロック・ポストをマップに配置しない限り
オンラインではいつでも参加出来てしまうようです。
クイックマッチで入った瞬間ゴールだったことが何度かありました。

ロードは速いので、ほとんどバックグラウンドで行われているのかもしれません。
たまに待たされることがありましたが、どちらかと言えばネット側の問題だった
ようです。


エディットもかなり力が入っていて、ツール1つ1つに丁寧なチュートリアルがあります。
裏で勝手に説明ムービーが流れているだけなので、すでに理解している場合は
さっさと先に進めることが可能。

エディット系ツールでは素材から自由に形を作ることが出来ます。
3D オブジェクトのペンで、絵を描くようにモデルが作られます。
基本的にマテリアルは使う素材によって決まっていて、見た目だけでなく
重さや滑りやすさ、つかめるかどうかといった特性も素材で決まります。

見た目を変えるにはステッカーを貼ります。いわゆるテクスチャ。
エディットモードだけでなくプレイ中もステージ内のオブジェクトにステッカーを
貼り替えできます。
USB カメラがあれば、取り込んでステッカーを作ることも可能です。

エディット中も物理シミュレートは有効になっており、空中に置いたものは落ちるし
ぶつかると倒れます。
動くと困るときは、十字キーの上で物理シミュレートを一時停止します。
巻き戻しのような操作でいつでも Undo/Redo 可能なのも便利。

画面は 3D ですが、画面の奥行きには制限があります。
使えるのは 3 ラインまでで、厚みの幅も固定。
コリジョンは 3D だけどオブジェクトの移動は 2D。

オブジェクトは組み合わせてのり付けしたり、ボルトや紐で組み合わせて形状を
作り上げていきます。

機能的なコネクタもあって、回転するモーターや伸び縮みするピストンなど
スイッチで切換えられます。

ジョイントで繋がれた物体の物理シミュレートや、スイッチの配線だけで様々な
ものが連動し、仕組みを作り上げていくことが可能です。
どう使うかは決められたものではなく、どれもこれも工夫次第。

フラグ管理とかスクリプト等といったゲームの都合による設定は極力排除されていて、
身の回りに近い理解しやすい世界が徹底されています。

エディット自体、一歩引いた次元の違う無機質なツールでは無く、
1つの世界として繋がっており、同じように楽しめるゲームの一部といったところ。


これらはベータ版を元にしているので製品版では変更される可能性があります。



2008/10/09
Little Big Planet

ここずっと PS3 の Little Big Planet ベータやってます。はまっています。
道路標識をチェックポイント(コンティニューポイント)と見間違えたくらい。

オンラインにあがっている様々なステージをプレイするだけでも延々遊べそうなのに、
エディットが非常に楽しいです。

自由度が高く、シンプルな物理ルールで出来ているので、
工夫次第で出来そうなことがいくらでもあります。
いかにもゲームっぽいお約束な決まり事にとらわれないのがいい。

littlebigplanet




Windows の Interlocked 系 API は atomic な操作に使われます。
例えば InterlockedIncrement() は load と store を含みますが、その間に他の
スレッドが同じメモリを書き換えることなく処理が完了するよう調整されます。

x64 でコンパイルするとこれらの Interlocked API はインライン展開されるようです。
下記のように同機能の intrinsic 命令が用意されおり、x64 では単なる別名として
定義されていました。

InterlockedCompareExchange Function
_InterlockedCompareExchange Intrinsic Functions

x86 でも直接 _InterlockedCompareExchange() を使えば組み込み命令として機能します。
実際のコードは下記の通り。

x64:
 lock cmpxchg dword ptr [mem32],edx  // InterlockedCompareExchange
 lock cmpxchg qword ptr [mem64],rdx  // InterlockedCompareExchange64

x86:
 lock cmpxchg dword ptr [mem32],edx   // InterlockedCompareExchange
 lock cmpxchg8b qword ptr [mem64]     // InterlockedCompareExchange64

InterlockedIncrement() + x64 の場合

// 返値参照あり
mov ecx,1
lock xadd    dword ptr [mem],ecx
inc ecx

// 返値参照無し
lock add     dword ptr [mem],1

返値を参照するかどうかによって、命令そのものも置き換わっています。
単なる関数や asm 文の inline ではなく、組み込み命令であることがよくわかります。

以前紹介した Gamefest2008 のスライドによると DirectX11 の Compute Shader
には下記の命令が追加されるようです。

 InterlockedAdd()
 InterlockedMin()
 InterlockedMax()
 InterlockedOr()
 InterlockedXor()
 InterlockedCompareWrite()
 InterlockedCompareExchange()

Gamefest 2008 Presentations
「Direct3D 11 Computer Shader More Generality for Advanced Techniques」

InterlockedMin()/InterlockedMax() は Win32 API に無い命令です。
書いてみるとこんな感じでしょうか。(厳密な動作は未検証)

template<typename T>
void InterlockedMin( T volatile* mem, T val )
{
    union {
        T      fval;
        long   ival;
    }	cur;
    do{
        cur.fval= *mem;
        if( cur.fval <= val ){
            break;
        }
    }while( _InterlockedCompareExchange(
                reinterpret_cast<long volatile*>( mem ),
                *reinterpret_cast<unsigned long*>( &val ),
                cur.ival ) != cur.ival );
}


関連エントリ
Direct3D11 Compute Shader など
SSE3 の monitor mwait 命令



SSE3 で monitor / mwait 命令が追加されています。
HT やマルチコアなど、ハードウエアスレッドの同期効率を上げるために有効
らしいですが、使ったことがないので調べてみました。

monitor で監視アドレスを与えた後、mwait 命令は監視アドレスに何らかの
書き込みがあるまで待機します。
メモリの更新をハード的に検出する動作は RISC 系の atomic 命令 ll/sc に
似ています。

イベント待ちのような動作なので様々な通知に使えそうです。ただこれが OS では
なく CPU そのものの命令で実行されるため、いくつかの疑問も生じます。
CPU レベルの命令でアプリケーションがこのような動作を行って問題無いのか、
割り込みやコンテキストスイッチ等でどのように振る舞うのか、
mwait に復帰できるのか、monitor の状態がリストアされるのか、など。

intrin.h を include するだけで、_mm_monitor() / _mm_mwait() の
intrinsic 命令が使えます。
実際に x86 でも x64 でもコンパイルは可能ですが、無効な命令となり実行は
出来ませんでした。
CPUID を調べると、MONITOR/MWAIT に対応していることは確認できます。

Intel 64 and IA-32 Architectures Software Developer's Manuals
日本語技術資料のダウンロード

マニュアルによるとどうやら特権命令らしく、無条件で使えるのはレベル 0
の場合のみ、特権レベル 1~3 での動作も可能だけど、そのためには何らかの
条件がいるそうです。
また MONITOR/WAIT が使えるかどうかは MSR IA32_MISC_ENABLES (1a0) の
bit18 の設定にも依存し、この値が 0 だと CPUID のフラグも落ちるとのこと。
この値も設定されており問題はなさそうです。

Manual の Volume 3A 7.11.3 で、特権レベル 1 以上の場合でこれらの命令が
使えるかどうか判定する方法が載っています。intrinsic で書くと次の通り。

__try{
    _mm_monitor( memory, 0, 0 );
}
__except( 1 ){
   // 使用できない
}

つまり Illegal Instruction が発生するのは特権レベル 0 以外は使えないことを
意味しているようです。何らかの設定で無効にされているのか、それとも
もともと使えないものなのか、その条件はわかりませんでした。

マニュアルを見ると mwait の動作は、割り込み等によって頻繁に解除される
ようです。mwait に復帰することはなく、監視したメモリの値を調べて解除原因を
判断する必要があるようです。

また監視メモリの領域は CPU 依存で、CPUID の 0x05 で調べることが出来ます。
手持ちの CPU では下記の通り。最小も最大も 0x40 == 64 でした。

CPUID (CPU-Z によるレジスタダンプ)
・Atom N270
 0x00000005 0x00000040 0x00000040 0x00000003 0x00020220
・Core2 Duo E6600
 0x00000005 0x00000040 0x00000040 0x00000003 0x00000020

よって何らかの変数を監視するよう割り当てても、同じ 64byte 以内に
割り当てられた他の変数へアクセスによって解除される可能性もあります。

(1) 判定用メモリ領域 64byte (CPUIDで判定) を用意して初期値を入れる
(2) monitor 実行
(3) monitor 命令実行中に書き換えられている可能性があるので判定する。
  書き換わっていたら値によって適切な分岐。
(4) 書き換わっていなければ mwait
(5) 解除されたらその要因を調べる。
  値が書き換わっていたら値によって分岐。
  書き換わっていなければ (2) へ戻る。

もし使うならこのような手順になるようです。
つまりスピンロック時に監視アドレスを与えて停止させられるため、
ループ中に導入することでバスアクセスを減らし、効率を上げることが出来ます。
でも使えませんでした。



以前こちら で触れたように 対応機種一覧 で非対応と書いてありますが 購入してみました。

ATOK for WindowsMobile

EMONSTER lite S12HT へもインストールは可能で、一応 ctrlswapmini lite を
使って、2タッチ/ポケベル入力を行うことが出来ました。トグル入力も可能ですが
キーだけで文字種切り替えが出来ないので難があります。

「非対応」と書かれている理由は、やはり ATOK だけではテンキーによる文字入力が
出来ないためでしょう。
外部でトグル入力やポケベル入力出来るソフトなどを組み込めば、テンキーでも
それなりに使用できるものになると思われます。

また今まで他の機種に内蔵されていた ATOK とほぼ同じで、キーコマンドへの対応
状況や反応も同じ。ソフトからの制御も同じように出来そうです。

例えば Wnn や FSKAREN ではできなかった、確定のみで改行しないキーコードが
使えるため ctrlswapmini との相性も良いです。
ただし ctrlswapmini lite 1.02 は、Wnn 対応のためにこの動作を省いているので
今のところ恩恵がありません。

ATOK 設定の「バージョン番号」のタブにも、特にバージョン番号らしきものが
無いので、手持ちの EM・ONE 内蔵のものと完全に同じかどうかはわかりません。

現在 EMONSTER lite S12HT には、これで 4つの IME が同居しています。
同時に使えるのは一つだけで切り替えは再起動を伴うため、メモリ的にも特に
問題はなさそうです。

使用できる IME のまとめ

    確定のみ テンキー文字入力 外付けキーボード
MS-IME   ○      ×        ○
内蔵Wnn   ×      ○        △(スライドで切換え)
FSKAREN   ×      ○        ×
ATOK    ○      ×        ○


テンキーによるトグル入力処理は、サポートソフトを何も入れない単体の状態だと
Wnn と FSKAREN のみ可能です。
ただし IME 自体が自前でテンキーのトグル処理を行っているので、それぞれ
持っている機能や細かい操作性が異なります。このあたりは好みの問題も出てくる
でしょう。2タッチ/ポケベル入力はそのままでは出来ません。

テンキーの文字入力処理に対応すると数字キーを乗っ取ってしまうために QWERTY
キーボードとの同居が出来なくなります。外付けキーボードを使った場合などに
問題が生じます。
上の表でも、テンキー入力と外付けキーボード対応はほぼ排他です。

唯一 FSKAREN のみ、テンキーのスライドに応じてモードを切換えてくれるので、
一応両方使うことが出来ます。
テンキー専用機種とそうでない機種との違いは、FSKAREN 自体のバイナリを
個別に分けることで対応しているようです。


●外付けキーボードとの相性で問題が生じる原因

・テンキーによる文字入力に対応していると、数字キーが乗っ取られてしまう
  IME 側でテンキー入力処理を一時的に解除する機能が必要

・変換操作がスペースや変換キーでできない(カーソルキーのみなど)
  操作キーをカスタマイズできる機能が必要
  または外付けキーボードを考慮したキーバインドをあらかじめ行っておく

・変換や文字入力モードを切り替えできない
  テンキーに特化した IME だと、漢字、全/半、ひらカタキーなどで文字種を
  切換えられないものがある。


●ctrlswapmini との相性で問題が生じる原因

・キーストロークだけで文字種を変更できないものがある
   そのため IME 制御を行って、IME の on/off だけで英数とかな入力を
   切換えなければならない。

・変換バッファの確定だけ行って改行しないキー操作が必要
   IME 制御を行う場合、未確定バッファを捨てないで済むために必要。
   IME 制御をしなくても良いなら無くても何とかなる。

・一時かなモードの使用
   ローマ字入力モードでありながら、かな入力のシミュレートが出来る
   特殊なキーシーケンス。英語キーボードと見なす端末だとそもそも
   かな入力自体ができないようです。

プログラム側から見ると、MS-IME + 日本語キーボードとみなす場合が一番問題が
少ないです。次はおそらく ATOK だと思いますが、単独でテンキー入力出来ないし
まだほとんど調べていないため、まだ何ともいえません。


関連エントリ
WindowsMobile IME FSKAREN / ATOK
EMONSTER lite S12HT IME FSKAREN