月別アーカイブ: 2009年6月

メビウス PC-NJ70A (7) 一ヶ月後

モニター開始から一ヶ月。とはいえ SDK 等の動きもないので、特に何も変わって
ないというのが正直なところです。
HDD なのでアプリケーションのインストールで困ることもなく、容量も書き込み
速度も気にせずに使っています。

主な用途は 32bit OS での動作テストや、テキストメモ取り PC として。
基本的にはこれまで使ってきたノート PC と全く一緒です。
売りの光センサー液晶パッドはあまり活用できていないので、SDK が公開されるか
追加アプリが登場するまで眠らせておくかもしれません。
サイズも重さも決して悪いスペックではないのですが、今だと他にもっと小型軽量な
良い選択肢があるだけに悩ましいところです。

● Windows7 RC

Windows7 RC で使用しています。詳しいインストール手順はこちら。
メビウス PC-NJ70A (3) Windows7 RC を入れる

Windows7 RC で液晶パッドへのアプリの追加
メビウス PC-NJ70A (5) サブモニタ

Windows7 なのは主に動作テストのためと、標準の Home Basic ではリモートデスク
トップなどいくつか機能制限が生じるためです。

個人的に行っている設定

ネットブック系 PC は横長のワイド画面が多く、縦方向は狭くなっています。
WindowsVista までは、設定次第でタスクバーの上にアプリケーションウィンドウを
重ねることが出来ました。
Windows7 はできないので、タスクバーを画面の左端に配置しています。
アプリケーションで上下幅をめいっぱいまで使えるように。
タスクバーをわずかに横にのばすと、時刻だけでなく日付も表示できます。

pc-nj70a
pc-nj70a

●マウス

Bluetooth の外付けマウスを使用しています。

SONY VGP-BMS33

光センサー液晶パッドはマウスモードで表示を消す設定にしていますが、
何らかのタイミングで液晶パッドのバックライトが点灯してしまいます。

 SHARP 液晶パッド設定→マウスモード時に、液晶パッドの表示を消す

サスペンドから復帰したタイミングや、省電力設定でメインディスプレイの電源が
切れた場合、その復帰と同時に液晶パッドも点灯してしまうようです。
真ん中ボタンでいったんパッドのモードを切り替えるとバックライトが消えます。

持ち歩いてて一度、光センサー液晶パッドの反応が悪くほとんど操作出来なくなる
ことがありました。室内だったので、汗などによるパッド部の汚れが原因では
ないかと思います。外付けのマウスは必須となりました。

●アドオンジャケット

アドオンジャケットは天板の保護にもなるし、好きなメモとか挟んでおけるので
おもしろい仕組みです。欠点は 100g ほど重くなること。
持ち歩く用途を考えた場合どちらを優先するか悩みます。
結局軽量化を考えて取り外しました。

●通信

外では UQ WiMAX を使用しています。
こちらはモニターではなく購入品。
まだエリアが限られていますが、一度つながれば外でも高速な通信が可能です。
7月から正式サービスが始まることもあり、以前使えなかった場所でもつながるように
なってきました。

●インストールソフトウエアメモ

インストールしている主なソフト。
Google Chrome
ATOK2008
DirectX SDK March 2009
UD01SS Utility
Vim 7.2

関連エントリ
メビウス PC-NJ70A (6) ユーザーインターフェース
メビウス PC-NJ70A (5) サブモニタ
メビウス PC-NJ70A (4) 使用感
メビウス PC-NJ70A (3) Windows7 RC を入れる
メビウス PC-NJ70A (2) 初期セットアップとメモリ増設
メビウス PC-NJ70A 液晶センサータッチパッド
メビウス PC-NJ70A 画面解像度とタッチ
Windows7 beta で UQ WiMAX

iPhone 3GS 入手

昨日の朝に入手。比較的手に入れやすそうな店を選んだけれどさすがに混雑していて
しばらく待たされました。iPhone 3GS

手に入れたあと周りからきかれるのは「速い?」「速くなった?」ばかり。
正直あまり速いとか実感していないのですが、事実上目立った違いがそれしかない
ということでしょうか。
おそらく前使っていたのが比較的速い iPod touch 2G で、通信も無線LAN しか
使っていなかったせいでしょう。3G の通信で遅いと感じるなんて贅沢になりました。

中身は大幅に入れ替わっているようで、iPhone 3G のおよそ 2倍だそうです。

iPhone 3G    : ARM11         412MHz   8stage  128MB
iPod touch 2 : ARM11         533MHz   8stage  128MB
iPhone 3GS   : ARM Cortex-A8 600MHz  13stage  256MB

core が違うので単純な比較は出来ませんが、クロック周波数で 約1.46倍。
さらに Cortex-A8 はスーパースカラで 2命令同時発行らしいので、2パイプ動作して
実質 1.4倍程度と考えると (1.4*1.46= 2倍) ちょうど良い感じです。
その代わりインオーダー発行なので命令並びに依存するし、パイプラインの
ステージ数もだいぶ深くなっています。

wikipedia ARM architecture

メインプロセッサもそうですが、PowerVR SGX は ShaderModel 3.0 が動作する
はずなので、本当に違いが出るのは今後対応アプリが出揃ってからになるでしょう。

表面上変わってない、違いが少ないというのはむしろすごいことです。
過去にずっと長いこと日本製 PDA を使っていましたが、アプリ開発上の難関は
ユーザーインターフェースの互換性でした。
新製品が出るたびにボタン配列も全部変わってしまうし、そのたびにいちいち
プログラムを修正して、新しい操作方法を考えて、対応アプリを出さないと
いけなかったからです。
対する Palm は頑なにボタン配列を守り続けていました。

当時メーカーの方に話を聞く機会がありましたが、曰く商品コンセプトありきだとのこと。
毎回どこで売るのかコンセプトを考えて、ハードもそれに合わせてデザインする。
ソフトウエアもあわせて必要になれば調達すれば良い、とのお話でした。
商売としては正しいし全く異論はないのですが、ソフトウエア開発者としては
そこに何の未来も見いだせなかったのは事実です。
ZAURUS から手を引いた理由の1つはここにあります。

今の携帯電話もそうかもしれません。
ZERO3 も非常に使いやすくて気に入っていたのに、なかなか良い点が新型に引き継がれ
ません。良い感じにカスタマイズできても、新型に乗り換えるとまた同じことを最初から
やり直しです。
新たに発生した使いづらいところを穴埋めしていく作業なのです。

iPhone の魅力の一つは操作方法がずっと変わらないだろうと安心できること。
ビジョンがあって貫かれているからこそ、目先の商品コンセプトに振り回される
ことがないんでしょう。
速度とか OS3.0 の細かな変更点とかいろいろありますが、性能が上がって機能が
増えても、重要なところが大きく変わらないからこそずっと使い続けていけるはず。

これまで iPod touch 2G を使っていました。音楽プレイヤー扱いながら、
過去に使ってきた PDA の中では一番使いやすくて実用的だったという印象です。
OS3.0 への更新も、ソフトウエアをダウンロードしただけなのに Bluetooth が
使えるようになりました。
1200円でハードウエアも一緒に付いてきたような得した感じです。

HID はありませんでした。PS3 も Wii もコントローラは Bluetooh なので、もしか
したらキーボードだけでなくゲームコントローラもつながっていたかもしれない
と思うと少々残念です。

iPhone 3GS は iPod touch と比べると厚みもあって大きく感じます。
その代わりどこでも通信できて GPS とコンパスも使えるし、持ち歩くものを1つ
減らせます。乗り換える決め手となったのは MMS で、メールアドレスも変わらずに
従来の携帯電話を置き換えられるようになりました。

SMS/MMS はメーラーというよりチャットのような画面レイアウトで、フォルダではなく
送信相手毎に分類されます。
最初悩んだのは MMS の送信が出来ないこと。上の「メール」というボタンを押すと
ただの E-Mail になってしまいます。
下にある1行の入力欄が SMS/MMS 送信用の本文でした。検索だと思ってました。
いろいろ慣れない部分も多いので、これから慣れます。

Direct3D11/DirectX11 ComputeShader 4.0 を使う

DirectX11 の ComputeShader が実際に動くようになりました。

Direct3D11 GeForce driver 186.08 beta

ComputeShader 4.0 は FeatureLevel 10.0。つまり 1世代前の GPU で動作します。
cs4.0/4.1 の存在自体は November 2008 SDK でも確認できました。
しかしながら実際に使うためにはドライバの対応を待つ必要があったわけです。

本来の ComputeShader (cs5.0) の仕様に対して cs4.0 はサブセットとなります。
機能制限のある cs4.0 は、ぱっと見 PixelShader とほとんど違わないし
どこにメリットがあるのかあまりわからないかもしれません。
とりあえず目に付いた ComputeShader4.0 の利点は次の通り。

・シェーダーがバッファに書き込みできる
・共有メモリへアクセスできる

描画パイプラインに組み込まれたシェーダーの場合、ストリームとして動作するため
出力位置は固定でした。
ComputeShader は戻り値を持たず、代わりに UnorderedAccessView を通して
リソースの任意の位置にデータを書き込むことができます。

共有メモリはスレッド間でデータの受け渡しができるプロセッサ内部のローカルメモリです。
高速アクセス可能で他のスレッドが書き込んだ値を参照することもできます。

VertexShader 等を通さずに直接シェーダーのみ実行できるのも ComputeShader
の特徴となります。

●実行とデータの受け渡し

ComputeShader を実行する命令は Dispatch() です。

iDeviceContext->CSSetShader( iCS, NULL, 0 );
UINT	v= 0;
iDeviceContext->CSSetUnorderedAccessViews( 0, 1, &iOutputUAView, &v );
iDeviceContext->CSSetShaderResources( 0, 1, &iInputView );
iDeviceContext->Dispatch( 1, 1, 1 );

この例では入力が ShaderResourceView (SRV)、出力は
UnroderedAccessView (UAV) です。

入力データは何らかの形で SRV のリソースに書き込んでおきます。
ConstantBuffer や Texture へ書き込む手順と変わらないので難しくありません。

実行結果は UAV で受け取ります。
UAV のリソースは RenderTarget 同様 GPU が書き込むため D3D11_USAGE_DEFAULT
を指定しておきます。
デバッグ時など、結果を何らかの形で CPU で受け取りたい場合は
D3D11_USAGE_STAGING のバッファにコピーしなければなりません。

STAGING リソースから読み込む場合 Map() を使いますが、STAGING への Map は
ChildContext で実行することができませんでした。
STAGING は直接メモリアクセスしているのに、コマンドをバッファにためるだけでは
意味がないので当然かもしれません。
スレッド対応のためにすべて Deferred Context 化している場合は注意が必要です。
Immediate Context を使います。

(1) SRV リソースへ書き込み
  ・UpdateSubresource() → USAGE_DEFAULT
  ・Map() → USAGE_STAGING → CopyResource() → USAGE_DEFAULT
  ・Map() → USAGE_DYNAMIC
(2) 実行 Dispatch()
(3) UAV から結果受け取り
  ・USAGE_DEFAULT → CopyResource() → USAGE_STAGING → Map()

このように、ComputeShader の場合 CPU とのデータやりとりも一般のシェーダーと
同じ手順が必要になります。
CUDA とか ATI Stream (CAL) より若干手間がいるかもしれません。

ComputeShader 4.x の場合、UAV は RAW または Structured Buffer のみ使用できます。
同時に与えられる UAV も 1つだけです。

● ComputeShader の実行回数と ID

PixelShader なら 2次元の面積で描画するピクセル数が決定します。
このピクセルの数だけ Shader を実行することになります。

ComputeShader の場合 3次元の体積で実行するスレッドの数を指定できます。

例えば XYZ= ( 2, 3, 1 ) の場合、2 x 3 x 1 = 6 スレッド走ります。
各スレッドは自分がどの座標に対応しているのか 3次元の id 番号を
受け取ることができるわけです。

実行するスレッドの個数の指定は二カ所で行います。

1. Dispatch() の引数
2. ComputeShader のアトリビュート numthreads 指定

[numthreads(3,2,1)]  // ←これ
void cmain1(
		uint3 did : SV_DispatchThreadID,
		uint3 gid: SV_GroupThreadID,
		uint3 group: SV_GroupID,
		uint gindex : SV_GroupIndex
				)
{
	int	index= did.x + did.y * 10;
~

両者の指定は似ていますが別物です。
6次元の id 値を持っているといえるかもしれません。

・1グループ内のスレッド実行回数の定義

[numthreads()] で指定するのは 1グループ内で実行するスレッドの数です。
シェーダーのコンパイル時に決定するので static な値となります。

  uint3 SV_GroupThreadID // グループ内のスレッド番号

semantic SV_GroupThreadID はグループ内の id 番号を受け取ることができます。
[numthreads(3,2,1)] は次の 6 通り。

(0,0,0) (1,0,0) (2,0,0) (0,1,0), (1,1,0), (2,1,0)

  int SV_GroupIndex // グループ内の通し番号

SV_GroupIndex はグループ内の連番です。
[numthreads(3,2,1)] の場合 0~5 の連番を受け取ります。

・グループ自体を何回実行するか指定する

Dispatch() の引数は、シェーダーで定義したスレッド Group をさらに何回実行するか
指定します。例えば [numthreads(3,2,1)] を Dispatch( 2, 1, 1 ) で呼び出すと
合計 12スレッドプログラムが走ることになります。

  uint3 SV_GroupID // グループの番号

SV_GroupID はグループにつけられた番号です。
例えば Dispatch( 10, 2, 1 ) で呼び出すと (0,0,0)~(9,1,0) まで。
同じグループの中のスレッドはすべて同じ値です。

  uint3 SV_DispatchThreadID // 3次元の通し番号

SV_DispatchThreadID は numthreads も Dispatch も区別無く、3次元に展開した
スレッドの通し番号になります。
例えば [numthreads(3,2,1)] を Dispatch( 4, 9, 1 ) で呼び出すと 216スレッド。
(3*4, 2*9, 1*1) の範囲なので (0,0,0)~(11,17,0) までの値を取ります。

[numthreads(3,2,1)] を Dispatch( 2, 1, 1 ) で呼び出した場合の ID 一覧。

SV_GroupID  SV_GroupThreadID  SV_GroupIndex  SV_DispatchThreadID
(0,0,0)     (0,0,0)           0              (0,0,0)
(0,0,0)     (1,0,0)           1              (1,0,0)
(0,0,0)     (2,0,0)           2              (2,0,0)
(0,0,0)     (0,1,0)           3              (0,1,0)
(0,0,0)     (1,1,0)           4              (1,1,0)
(0,0,0)     (2,1,0)           5              (2,1,0)
(1,0,0)     (0,0,0)           0              (3,0,0)
(1,0,0)     (1,0,0)           1              (4,0,0)
(1,0,0)     (2,0,0)           2              (5,0,0)
(1,0,0)     (0,1,0)           3              (3,1,0)
(1,0,0)     (1,1,0)           4              (4,1,0)
(1,0,0)     (2,1,0)           5              (5,1,0)

ComputeShader4.x の場合スレッド数の 3番目の値は必ず 1 でなければなりません。
つまり PixelShader 同様 2次元の id 指定に制限されます。

● Group

上記のようにスレッドの実行にはグループという概念があります。
プログラムの実行はこのグループ単位に行われているようです。

・スレッド共有メモリは group 毎に確保される
・共有メモリへのアクセスは group 単位で同期できる

●共有メモリ

ComputeShader はローカルな共有メモリにアクセスすることができます。
メモリ空間にマップされるわけではないので Buffer より高速です。
ShaderResource と違い読み書きも可能です。
同一グループ内の他のスレッドと共有できます。他のスレッドでも書き込んだ値を参照可能です。

・レジスタ = スレッド固有
・共有メモリ = グループ内のみ共有
・リソース(Buffer)

Shader プログラム内で groupshared 宣言すると共有メモリになります。

ComputeShader 4.x ではいくつか制限があります。
容量は 16KB までです。
また共有メモリの宣言はグループ内のスレッド数と同数でなければならず、
書き込めるのは自分の SV_GroupIndex に対応するメモリだけ。
宣言できる共有メモリも1つだけです。
その代わり Structured のように構造体を与えることが可能です。

struct SharedMem {
	float2	fl;
	uint	id;
};

groupshared SharedMem	buf[6]; // 3x2

[numthreads(3,2,1)]
void cmain(
		uint3 did : SV_DispatchThreadID,
		uint3 gid: SV_GroupThreadID,
		uint3 group: SV_GroupID,
		uint gindex : SV_GroupIndex
				)
{
	buf[  gindex ].fl.x= gindex;
~

groupshared 指定は、アセンブラコードだと下記の宣言になります。
g0 が共有メモリです。

dcl_tgsm_structured g0, 32, 6

●同期

ComputeShader 4.x の場合 Interlock 系の Atomic なオペレーション命令は
ありませんが、メモリアクセスに対する Barrier 同期は使えるようです。

GroupMemoryBarrierWithGroupSync();
GroupMemoryBarrier();
AllMemoryBarrierWithGroupSync();
AllMemoryBarrier();

GeForce 用ドライバ 186.08 beta ではこれらの命令が動作しませんでした。
命令のコンパイル自体は可能だし DebugLayer も無言だったので、ドライバがまだ
対応していないだけかもしれません。
Reference Driver を使うと Shader4.0 でも動作しました。

アセンブラでは sync 命令が挿入されています。

sync_g              GroupMemoryBarrier()
sync_g_t            GroupMemoryBarrierWithGroupSync()
sync_uglobal_g      AllMemoryBarrier()
sync_uglobal_g_t    AllMemoryBarrierWithGroupSync()

関連エントリ
Direct3D11/DirectX11 (6) D3D11 の ComputeShader を使ってみる
Direct3D11/DirectX11 (4) FeatureLevel と旧 GPU の互換性、テクスチャ形式など
Direct3D11 (DirectX11) シェーダーの書き込み RWBuffer 他

Direct3D11 GeForce driver 186.08 beta

masafumi さんのところで DirectX 11 対応ドライバが
動作したとの報告があがってました。

新 masafumi’s Diary Direct3D11対応ドライバ

CheckFeatureSupport() の結果を調べてみました。

ドライバ 186.08

[NVIDIA GeForce 9800 GT ]
   vmem:497MB sysmem:0MB shmem:2811MB
   flag=0 
  (Direct3D11)
   *HARDWARE  = 10.0 (a000)
     feature threading  DriverConcurrentCreates=1
     feature threading  DriverCommandLists=0
     feature d3d10_x ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x=1
     feature doubles  DoublePrecisionFloatShaderOps=0
[ATI Radeon HD 4670]
   vmem:504MB sysmem:0MB shmem:2811MB
   flag=0 
  (Direct3D11)
   *HARDWARE  = 10.1 (a100)
     feature threading  DriverConcurrentCreates=0
     feature threading  DriverCommandLists=0
     feature d3d10_x ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x=0
     feature doubles  DoublePrecisionFloatShaderOps=0

動いています。threading DriverConcurrentCreates と
d3d10_x ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x
が 1 になりました。

以前の結果はこちら

関連エントリ
Direct3D10/11 DXGI1.1 とリモート GPU (アダプタ)

メビウス PC-NJ70A (6) ユーザーインターフェース

タッチパッドとか操作性とか、多少使いづらかったとしてもそれはそれ。
「これでしかできないことがある」のは確かです。
光センサー液晶パッドはまだまだ初物。

今後ソフトウエアの改良によって他の PC と同じ操作性へ近づけていくことは可能でしょう。
でもメビウス PC-NJ70A と同じことが他のパソコンで出来るわけではありません。

これまで書いてきたように、それ以外を割り切ったのが一番の特徴です。
普段持ち歩いているとついついただの普通のパソコンとして見てしまいがち。
あらためて光センサー液晶パッドについて考えてみます。

使っていてあまりわくわくしないのはなぜでしょう。
多少欠点があっても、何かしら今後良くなりそうな可能性の片鱗が見えれば
たいした問題ではないはずです。

従来のパソコンにない新しい部分が、現状だと他のデバイスでも出来ることの
寄せ集めでしかなく、しかも劣っていることが原因かもしれません。

他に良いものがあることをユーザーは知ってますし、自分も常時 iPod touch を
持ち歩いています。
ようするに今の光センサー液晶パッドでは、マルチタッチを使った操作は全く快適では
ないということ。

ではどうすればよいか考えてみました。

●苦手なこと

使っていると光センサー液晶パッドと比較的相性の良い操作、苦手な操作がわかってきます。

良い

 ・ペン操作
 ・ボタン

だめ

 ・ドラッグ系
 ・ジェスチャ入力
    二本指スクロール・拡大縮小・回転

手描きのペン入力は割と素直に使えます。
手書き文字入力も想像より快適でした。線を加える毎に即座に文字が絞り込まれていきます。
レスポンスも速く、自分が行った操作とフィードバックが直結しています。
でも純粋なタブレット PC と違い、キーボードがあるから使わなくても困らないのも事実。

電卓やピアノといったシンプルなボタンを活用するユーザーインターフェースも
不満が少なく相性が良いといえます。
感圧式と違って触った時点で反応するので、押した感触がわかりやすいようです。

逆にドラッグ操作でオブジェクトを動かすような操作は苦手です。
タッチ位置にオブジェクトがついてこないし、遅延が目立つし、見た目とずれが
あるため慣れるまで思うように操作出来ません。

ジェスチャ系も同様です。
たとえばズーム操作では、読み込みが間に合わなかったとしても画像を拡大表示して
ごまかし、見た目の反応速度を上げるテクニックが良く用いられます。
液晶パッドの場合はそれ以前の問題で、ただの拡大ですら更新エリアが大きいため
描画の負担となり現実的ではないのです。

●描画更新が遅いならただのボタンの方が良い

結局 描画の更新を減らす工夫が何より大切だといえそうです。

・できるだけボタンなどスタティックなユーザーインターフェースにする。
・ジェスチャ系は操作中ワイヤーフレームで表示してあとから更新する。

といったことを考え、ハードウエアの性能を考慮したユーザーインターフェースを
採用します。以下具体例。

・2本指のスクロール

初めてリスト一覧を見たとき、最初にスクロールバーを探してしまいました。
2本指のスクロールは いわれないと わからないし、描画が遅くて操作できているのか
出来ていないのか判断しづらくなっています。
なぜかスクロールバーも常時表示されていません。
そのせいでスライドしすぎて止まらなくなり、ますます戸惑うことに。

液晶パッドは画面が広いので、いっそ専用のスライド領域を設けてしまった方が
良いのではないでしょうか。見た目でわかりやすいし、スライドした量を描画すれば
操作出来ていると安心できます。

・ページ切り替えとボタン

広い面積のスクロールは苦手なので、直接ページを切り替えられるボタンがあった
方が迅速だしわかりやすいです。タブ切り替えのように。
フォトモードの秒数指定ボタンは最初ページ切り替えだと勘違いしました。

・ハードウエアボタン

触れただけで反応するタッチ面に対して、クリックボタンは少々力がいります。
ボタンの説明として「次ページ」「マウス操作へ」「前ページ」とわかりやすく表示
してありますが、むしろここの文字をタッチしたくなります。

・マッチ棒のパズル

マッチ棒をスライドで動かすのはたいへんです。
描画が遅くて思わぬところに落としてしまうことも。
しかも関係ない位置においてしまうと操作回数がカウントされて失敗扱いです。

ゲーム内容を考えると、動かしたいマッチ棒をタッチしてその後異動先をタッチ
するだけで十分だと思います。
ハードウエアスペックに応じた操作仕様にするだけで大幅に遊びやすくなるはずです。

・拡大縮小回転

個別にボタンを用意するか、タッチに合わせたワイヤーフレーム等の演出が
合っているように思います。

液晶パッド部の解像度はかなり高いです。
メインの液晶画面が 1024×600 ドットなのに対して 854×480 ドットもあります。
縦横ともにおよそ 20% 小さいだけ。
手書きイラストのキャプチャ選択も全体を 80% の縮小表示にして、ワイヤーで選択
範囲が表示されているだけで十分な気がします。

●まとめ

書き出してみたらあまりたいしたことではありませんでした。
操作ではなく描画の問題で、結論はハードウエアの能力を考慮したユーザー
インターフェースにするという一点のみです。

あとは画像取り込みとかスキャナ機能とか、何かしら光センサー液晶パッドでないと
出来ない使い方があると良いですね。

関連エントリ
メビウス PC-NJ70A (5) サブモニタ
メビウス PC-NJ70A (4) 使用感
メビウス PC-NJ70A (3) Windows7 RC を入れる
メビウス PC-NJ70A (2) 初期セットアップとメモリ増設
メビウス PC-NJ70A 液晶センサータッチパッド
メビウス PC-NJ70A 画面解像度とタッチ