2013/02/28
Android で WebGL (Chrome)
Android 向けに新しい Chrome がリリースされ、WebGL 対応になったようです。
・「膨大な変更」でパフォーマンス向上した「Chrome for Android」最新版
WebGL を有効にする方法 (手順は PC版 Chrome と同じです)
(1) URL に "about:flags" と入力 (または "chrome://flags")
(2) リスト内の "WebGL を有効にする" を有効にする
(3) ブラウザの再起動
有効になっているかどうか下記の手順で確認できます。
(機能を有効にしても GPU によっては使えない可能性があります。)
(1) URL 欄に"chrome://gpu-internals" と入力
(2013/04/07 追記: 新しい Chrome は gpu-internals ではなく "chrome://gpu" に変更されています)

Android には様々なブラウザアプリケーションが揃っているので、
これまでも WebGL を使うことができました。
Opera , Firefox はすでに Android 版で WebGL に対応しており
3D 描画ができるようになっています。
Chrome の正式版はこれまで未対応でしたが、
先行配信されていた Chrome Beta ではすでに機能が入っていました。
WebGL の次は NativeClient へと、徐々に対応機能が広がっていくものと考えられます。
・「膨大な変更」でパフォーマンス向上した「Chrome for Android」最新版
WebGL を有効にする方法 (手順は PC版 Chrome と同じです)
(1) URL に "about:flags" と入力 (または "chrome://flags")
(2) リスト内の "WebGL を有効にする" を有効にする
(3) ブラウザの再起動
有効になっているかどうか下記の手順で確認できます。
(機能を有効にしても GPU によっては使えない可能性があります。)
(1) URL 欄に
(2013/04/07 追記: 新しい Chrome は gpu-internals ではなく "chrome://gpu" に変更されています)

Android には様々なブラウザアプリケーションが揃っているので、
これまでも WebGL を使うことができました。
Opera , Firefox はすでに Android 版で WebGL に対応しており
3D 描画ができるようになっています。
Chrome の正式版はこれまで未対応でしたが、
先行配信されていた Chrome Beta ではすでに機能が入っていました。
WebGL の次は NativeClient へと、徐々に対応機能が広がっていくものと考えられます。
2013/02/24
PlayStation 4
PC では 4 core x HT でハードウエア 8 スレッドは当たり前になりましたが、
完全に独立した 8 core でプログラムを走らせる機会はまだあまり多くありません。
1 core あたりの演算能力がどの程度かわかりませんが、
うまく並列化できれば最大 8倍 (数倍)のパフォーマンスを見積もれるのは
ユニークだと思います。
ゲーム機は Xbox360 や PS3 の時点で multi core + HT (Hardware Multi Threading)
が当たり前となっています。
ただし core の数と高い動作クロック数を維持するために、
これまでは非常にシンプルなデザインの CPU core が用いられていました。
PPE+SPE で 8 core 搭載する Cell はもちろん、3 core の Xenon も
pipeline は in-order で、単体の実行効率はあまり高くありません。
その代わり 2 thread を interleave することで見かけのレイテンシを減らしています。
3.2GHz の 1個は、ある意味 1.6GHz 2個相当といえるのかもしれません。
比較的単純な In-order の core に HT を組み合わせて
高いクロックで走らせる手法は Atom に近い考え方です。
ただし Atom は省電力に用い、ゲーム機は高性能化のためで目的が異なります。
また Atom は interleave ではなく、さらに core あたりの演算能力は
Cell PPE, Xenon の方が高くなっています。
PS4 の CPU はこれまでと違い、比較的実行効率の高い core が多数
並列に存在していることになります。
ハイエンド core ではありませんが out-of-order の 2並列なので、
おそらく Cell/Xenon/Atom よりも、
クロック周波数に対して違和感ない速度で動作するのではないかと予想されます。
Cell/Xenon/Atom は HT 依存 In-order であり
ピーク性能は高くても single thread では性能を引き出すことができないため、
クロック周波数よりも遅い印象を受けるからです。
速いけどピーキーな CPU が多数存在していた前世代から、
PC と同じように比較的扱いやすい CPU core で均等な 8並列に移行したのだと
考えられます。
GPU 性能に関してもバス速度で推測出来ます。
176GB/sec の帯域があるそうなので、少なくてもこれくらい必要とするだけの能力が
システム全体に備わっていると言えます。
PCハイエンドの GPU では VRAM が 200GB/s を優に超えているのですが、
VRAM 容量では single で 8GB 搭載したビデオカードは自分が知る限りでは
まだ無かったように思います。
今までできなかったメモリをふんだんに使用したアルゴリズムが
利用できるようになりそうです。
おそらく CPU 性能や演算能力ではモバイルデバイスの進化の方が速いので、
数年後に追いつかれる可能性があります。
ですが GPU とバス帯域に関しては、据え置き専用機としてのアドバンテージが
十分備わっているといえるのではないでしょうか。
ユーザーとして欲しいかどうかは置いといて、
開発者としてはどのようなアルゴリズムを実装してみようかと、
いろいろと考えるだけでも楽しみなハードウエアではないかと思います。
モバイルデバイスの方が進化が早いと思っていましたが少々興味を持ちました。
関連エントリ
・2007/01/22: PS3 PPU は速いのか
完全に独立した 8 core でプログラムを走らせる機会はまだあまり多くありません。
1 core あたりの演算能力がどの程度かわかりませんが、
うまく並列化できれば最大 8倍 (数倍)のパフォーマンスを見積もれるのは
ユニークだと思います。
ゲーム機は Xbox360 や PS3 の時点で multi core + HT (Hardware Multi Threading)
が当たり前となっています。
ただし core の数と高い動作クロック数を維持するために、
これまでは非常にシンプルなデザインの CPU core が用いられていました。
PPE+SPE で 8 core 搭載する Cell はもちろん、3 core の Xenon も
pipeline は in-order で、単体の実行効率はあまり高くありません。
その代わり 2 thread を interleave することで見かけのレイテンシを減らしています。
3.2GHz の 1個は、ある意味 1.6GHz 2個相当といえるのかもしれません。
比較的単純な In-order の core に HT を組み合わせて
高いクロックで走らせる手法は Atom に近い考え方です。
ただし Atom は省電力に用い、ゲーム機は高性能化のためで目的が異なります。
また Atom は interleave ではなく、さらに core あたりの演算能力は
Cell PPE, Xenon の方が高くなっています。
PS4 の CPU はこれまでと違い、比較的実行効率の高い core が多数
並列に存在していることになります。
ハイエンド core ではありませんが out-of-order の 2並列なので、
おそらく Cell/Xenon/Atom よりも、
クロック周波数に対して違和感ない速度で動作するのではないかと予想されます。
Cell/Xenon/Atom は HT 依存 In-order であり
ピーク性能は高くても single thread では性能を引き出すことができないため、
クロック周波数よりも遅い印象を受けるからです。
速いけどピーキーな CPU が多数存在していた前世代から、
PC と同じように比較的扱いやすい CPU core で均等な 8並列に移行したのだと
考えられます。
GPU 性能に関してもバス速度で推測出来ます。
176GB/sec の帯域があるそうなので、少なくてもこれくらい必要とするだけの能力が
システム全体に備わっていると言えます。
GC 2.6GB/s PS2 3.2GB/s (+VRAM 48GB/s) Xbox1 6.4GB/s Xbox360 22.4GB/s (+ED RAM 32GB/s) PS3 22.4GB/s (+CPU 25.6GB/s) ( 22.4 = 3.2 x7.0倍) PS4 176 GB/s (176.0 = 22.4 x7.8倍)
PCハイエンドの GPU では VRAM が 200GB/s を優に超えているのですが、
VRAM 容量では single で 8GB 搭載したビデオカードは自分が知る限りでは
まだ無かったように思います。
今までできなかったメモリをふんだんに使用したアルゴリズムが
利用できるようになりそうです。
おそらく CPU 性能や演算能力ではモバイルデバイスの進化の方が速いので、
数年後に追いつかれる可能性があります。
ですが GPU とバス帯域に関しては、据え置き専用機としてのアドバンテージが
十分備わっているといえるのではないでしょうか。
ユーザーとして欲しいかどうかは置いといて、
開発者としてはどのようなアルゴリズムを実装してみようかと、
いろいろと考えるだけでも楽しみなハードウエアではないかと思います。
モバイルデバイスの方が進化が早いと思っていましたが少々興味を持ちました。
関連エントリ
・2007/01/22: PS3 PPU は速いのか
2013/02/23
Nexus 7 Ubuntu Touch Developer Preview (2)
Nexus 7 の MultiROM が Ubuntu touch 対応となっています。
・xda: [WiFi&3G] MultiROM v8 (new recovery for Ubuntu Touch)
TWRP の新しいバージョン (2013/02/22以降) で
・xda: Ubuntu touch preview
この手順に従い install 可能となりました。
Android, Ubuntu Desktop, Ubuntu Touch を共存させて
起動時に選択することができます。
これでタブレットの利用には Android を、
単体でのプログラミングなら Ubuntu Desktop を、
Ubuntu Touch UI やアプリのテスト時に Desktop Preview を起動できます。
Ubuntu Touch Developer preview は adb 経由で chroot することからもわかるように、
Android 上に install した chroot 版 Linux に近い構造となっているようです。
HW アクセラレート対応の UI が乗っており、
Android SDK の AVD のようにアプリケーションの動作確認に利用することができます。
Ubuntu をベースとした Tablet/Phone 向け OS なので、
Android のようにタッチによる操作がしやすくなっています。
ただし Touch UI 上で Linux アプリがそのまま使えるわけではないので、
新しいプラットフォームと考えた方が良いでしょう。
UI 上で Linux らしさを期待するなら、今のところは Desktop 版との使い分けが
ベストだと思います。
関連エントリ
・Nexus 7 Ubuntu Touch Developer Preview
・Nexus 7 上に開発環境をつくる (4) Ubuntu 13.04
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
・xda: [WiFi&3G] MultiROM v8 (new recovery for Ubuntu Touch)
TWRP の新しいバージョン (2013/02/22以降) で
・xda: Ubuntu touch preview
この手順に従い install 可能となりました。
Android, Ubuntu Desktop, Ubuntu Touch を共存させて
起動時に選択することができます。
これでタブレットの利用には Android を、
単体でのプログラミングなら Ubuntu Desktop を、
Ubuntu Touch UI やアプリのテスト時に Desktop Preview を起動できます。
Ubuntu Touch Developer preview は adb 経由で chroot することからもわかるように、
Android 上に install した chroot 版 Linux に近い構造となっているようです。
HW アクセラレート対応の UI が乗っており、
Android SDK の AVD のようにアプリケーションの動作確認に利用することができます。
Ubuntu をベースとした Tablet/Phone 向け OS なので、
Android のようにタッチによる操作がしやすくなっています。
ただし Touch UI 上で Linux アプリがそのまま使えるわけではないので、
新しいプラットフォームと考えた方が良いでしょう。
UI 上で Linux らしさを期待するなら、今のところは Desktop 版との使い分けが
ベストだと思います。
関連エントリ
・Nexus 7 Ubuntu Touch Developer Preview
・Nexus 7 上に開発環境をつくる (4) Ubuntu 13.04
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
2013/02/22
Nexus 7 Ubuntu Touch Developer Preview
Nexus 7 等のモバイルデバイスで動く Ubuntu Touch を試してみました。
開発者向けです。
・Ubuntu Touch
Nexus 7 には下記のように通常の desktop 版 Ubuntu もあります。
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
↓この二つは別物です。
◎ Nexus 7 で動く Desktop 版 Ubuntu
◎ Nexus 7 で動く Ubuntu Touch Developer Preview
Desktop 版は PC と同一の豊富なアプリケーションを動かすことができる反面、
タッチだけの操作は必ずしも使いやすいとはいえませんでした。
キーボードやマウスを繋げば快適で、超小型のパソコンになります。
Ubuntu Touch は Android や iOS のように、タッチ操作に特化した UI が入ります。
まだ開発者向けで、操作に HOST PC が必要となることがあります。(2013/02/22現在)
● install
Desktop 版 Ubuntu の native install と同じように、本体の Android OS を置き換える形になります。
(Android のデータは全部消えます。)
MultiROM が対応すれば、他の環境と共存できるようになるかもしれません。
・Install
Ubuntu 上で走る installer が用意されています。
PC に Ubuntu が入っている状態なら上記の Install 手順に従うだけです。
コマンドは python で書かれているので、
手順がわかれば Windows から手動で入れることもできるかもしれません。
bootloader の unlock が必要です。
installer は fastboot だけでなく adb も使うので、
Android を起動し USB デバッグにチェックを入れておきます。
● UI
インストールが完了すると、端末上で Ubuntu Touch の UI を試すことが可能となります。
・ReleaseNotes
UI 上でできることがまだ少ないですが、ReleaseNotes に
書かれているように USB + adb 経由でシェルにログインできます。
端末上で shell が動いたらさらにコマンドを実行します。
これで ARM 版 Ubuntu 12.10 としてシェルが動きます。
ReleaseNotes にあるように ssh を入れておけば Wi-Fi 経由で login できます。
普通の Linux コマンドを install できるようです。コンパイラとか動きます。
残念ながら ubuntu-sdk は入れられませんでした。
関連エントリ
・Nexus 7 上に開発環境をつくる (4) Ubuntu 13.04
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
開発者向けです。
・Ubuntu Touch
Nexus 7 には下記のように通常の desktop 版 Ubuntu もあります。
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
↓この二つは別物です。
◎ Nexus 7 で動く Desktop 版 Ubuntu
◎ Nexus 7 で動く Ubuntu Touch Developer Preview
Desktop 版は PC と同一の豊富なアプリケーションを動かすことができる反面、
タッチだけの操作は必ずしも使いやすいとはいえませんでした。
キーボードやマウスを繋げば快適で、超小型のパソコンになります。
Ubuntu Touch は Android や iOS のように、タッチ操作に特化した UI が入ります。
まだ開発者向けで、操作に HOST PC が必要となることがあります。(2013/02/22現在)
● install
Desktop 版 Ubuntu の native install と同じように、本体の Android OS を置き換える形になります。
(Android のデータは全部消えます。)
MultiROM が対応すれば、他の環境と共存できるようになるかもしれません。
・Install
Ubuntu 上で走る installer が用意されています。
PC に Ubuntu が入っている状態なら上記の Install 手順に従うだけです。
コマンドは python で書かれているので、
手順がわかれば Windows から手動で入れることもできるかもしれません。
bootloader の unlock が必要です。
installer は fastboot だけでなく adb も使うので、
Android を起動し USB デバッグにチェックを入れておきます。
● UI
インストールが完了すると、端末上で Ubuntu Touch の UI を試すことが可能となります。
・ReleaseNotes
UI 上でできることがまだ少ないですが、ReleaseNotes に
書かれているように USB + adb 経由でシェルにログインできます。
adb root adb shell
端末上で shell が動いたらさらにコマンドを実行します。
ubuntu_chroot shell
これで ARM 版 Ubuntu 12.10 としてシェルが動きます。
ReleaseNotes にあるように ssh を入れておけば Wi-Fi 経由で login できます。
apt-get update apt-get install openssh-server
普通の Linux コマンドを install できるようです。コンパイラとか動きます。
残念ながら ubuntu-sdk は入れられませんでした。
関連エントリ
・Nexus 7 上に開発環境をつくる (4) Ubuntu 13.04
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
2013/02/18
Nexus 7 上に開発環境をつくる (4) Ubuntu 13.04
先週の Nexus 7 Ubuntu 13.04 image で、
新規インストールができない問題が出ていたようです。
古いバージョンなら大丈夫で、手元では 2013/02/05 の image が正しく動いています。
・xda: [WiFi&3G] MultiROM v8 - (4.2.2 kernel and 4.18 bootloader fix)
また MultiROM 環境の Ubuntu で、apt-get upgrade / dist-upgrade と
フル更新をかけると OS の起動に失敗するようになります。
こちらは TWRP の Recovery menu モードに入ってから
Advanced → MultiROM → List ROMs で 選択 → re-patch init
で修復できるとのことです。
>Re-patch init - this is available only for ubuntu. Use it when ubuntu
> cannot find root partition, ie. after apt-get upgrade which changed
> the init script.
Android 4.2.2 への更新が配信されていましたが、
自動で更新できなかったので手動で行いました。
・Gadget 好きの忘備録: Nexus7を4.2.2にUpdate
こちらによれば Factory Image を書き込めば良いとのことです。
boot と recovery はどうせ置き換えるので、system だけ書き込んでみました。
アーカイブ内の bat ファイルでは全パーティションを erase していましたが
そのまま実行しています。あくまで自己責任でお願いします。
また MultiROM 対応の kernel も 4.2.2 用に置き換えています。
関連エントリ
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
新規インストールができない問題が出ていたようです。
古いバージョンなら大丈夫で、手元では 2013/02/05 の image が正しく動いています。
・xda: [WiFi&3G] MultiROM v8 - (4.2.2 kernel and 4.18 bootloader fix)
また MultiROM 環境の Ubuntu で、apt-get upgrade / dist-upgrade と
フル更新をかけると OS の起動に失敗するようになります。
こちらは TWRP の Recovery menu モードに入ってから
Advanced → MultiROM → List ROMs で 選択 → re-patch init
で修復できるとのことです。
>Re-patch init - this is available only for ubuntu. Use it when ubuntu
> cannot find root partition, ie. after apt-get upgrade which changed
> the init script.
Android 4.2.2 への更新が配信されていましたが、
自動で更新できなかったので手動で行いました。
・Gadget 好きの忘備録: Nexus7を4.2.2にUpdate
こちらによれば Factory Image を書き込めば良いとのことです。
boot と recovery はどうせ置き換えるので、system だけ書き込んでみました。
アーカイブ内の bat ファイルでは全パーティションを erase していましたが
そのまま実行しています。あくまで自己責任でお願いします。
また MultiROM 対応の kernel も 4.2.2 用に置き換えています。
関連エントリ
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
2013/02/17
スレッド同期命令の比較 C++11 とコンパイラ
スレッド間の同期を取る方法は複数あります。
OS のカーネルオブジェクト、ライブラリ関数、OS 依存の API など。
他にも CAS のような最低限の atomic 操作を使って Spinlock を作ることができます。
もちろんハードウエアスレッド環境に限ります。
C++11 対応に伴いコンパイラも新しい atomic 命令に移行しています。
例えば gcc の builtin 命令は __sync_ から __atomic_ となり、
clang にも同様に __c11_atomic_ があります。
Windows の場合は OS に Interlocked~ API がありますが、
VC++ が生成する同名の Intrinsic バージョンもあります。
こちらも C++11 に従いメモリバリアを指定できる命令が追加されているようです。
・gcc 4.7.2 : Built-in functions for memory model aware atomic operations
・Clang 3.3 : Clang Language Extensions
・msdn : x86 Intrinsics List
↓各種 API による比較です。
3つのスレッドで同じカウンタをそれぞれ 50000回カウントしています。
100% 競合する状態で、ロック手段による違いを測定しています。
走らせた PC のスペックが異なることと、数値の変動が大きいため
単純な比較ができないのでご注意ください。
同じ OS 内で API による違いだけ見てください。
(1) Windows (Windows 8 + VS2012 Express)
カーネルオブジェクトである Mutex は非常に遅くなっています。
CriticalSection の方が2桁高速ですが、_Interlocked 命令を使った
SpinLock の方が更に速い結果となっています。
(2) Linux (Ubuntu 12.10 / 13.04)
x86/x64 は VMware Player によるテストなのでご了承ください。
特筆すべき点は pthread_mutex が SpinLock と全く変わらないか、
むしろ速いということです。
SpinLock を作る場合に atomic API の使い方を間違えると、
pthread_mutex よりも遅くなったり、ロックに失敗したりするようです。
X86/x64 の場合 gcc (4.7.2) builtin の __atomic_ でメモリアクセス方法に
__ATOMIC_SEQ_CST を指定すると pthread_mutex よりも低速でした。
__ATOMIC_RELAXED で pthread と同等になります。
また Legacy API ですが __sync_ を使った場合も pthread と同等の
速度となりました。
ARM (Cortex-A9) では RELAXED の場合メモリアクセスが競合し
正しくブロックされません。
上記テストは ARM の場合のみ SEQ_CST を指定しています。
また __sync_ も RELAXED 相当なためかロックされませんでした。
(3) MacOS X (10.8)
OSAtomic と phtread_mutex で大きな隔たりがあります。
同じ pthread の mutex でも、Linux と違い Windows のように
カーネルオブジェクトとして実装されている可能性があります。
API が同一でも OS と CPU によって挙動が違うことがわかりました。
Linux では pthread_mutex が最もよい選択ですが、
MacOS X では逆に pthread_mutex を避けた方が良いようです。
テストプログラムは下記のとおり。
関連?エントリ
・C++11 Rvalue Reference 右辺値参照
OS のカーネルオブジェクト、ライブラリ関数、OS 依存の API など。
他にも CAS のような最低限の atomic 操作を使って Spinlock を作ることができます。
もちろんハードウエアスレッド環境に限ります。
C++11 対応に伴いコンパイラも新しい atomic 命令に移行しています。
例えば gcc の builtin 命令は __sync_ から __atomic_ となり、
clang にも同様に __c11_atomic_ があります。
Windows の場合は OS に Interlocked~ API がありますが、
VC++ が生成する同名の Intrinsic バージョンもあります。
こちらも C++11 に従いメモリバリアを指定できる命令が追加されているようです。
// CAS gcc __atomic_compare_exchange_*() clang __c11_atomic_compare_exchange_*() Windows _InterlockedCompareExchange_*()
・gcc 4.7.2 : Built-in functions for memory model aware atomic operations
・Clang 3.3 : Clang Language Extensions
・msdn : x86 Intrinsics List
↓各種 API による比較です。
(1) Windows Win8 x86 Win8 x64 ------------------------------------------------------- SpinLock(intrinsic) 5852 6353 CriticalSection 20894 22610 Win32 Mutex 2537901 3790403 (2) Linux Linux x86 Linux x64 Linux ARM ------------------------------------------------------- SpinLock(gcc atomic) 12712 10641 27977 pthread mutex 13693 11796 23807 (3) MacOS X MacOS X x86 MacOS X x64 ------------------------------------------------------- SpinLock(OSAtomic) 9505 9070 pthread mutex 563013 467785 // 実行時間 単位=us
3つのスレッドで同じカウンタをそれぞれ 50000回カウントしています。
100% 競合する状態で、ロック手段による違いを測定しています。
走らせた PC のスペックが異なることと、数値の変動が大きいため
単純な比較ができないのでご注意ください。
同じ OS 内で API による違いだけ見てください。
(1) Windows (Windows 8 + VS2012 Express)
カーネルオブジェクトである Mutex は非常に遅くなっています。
CriticalSection の方が2桁高速ですが、_Interlocked 命令を使った
SpinLock の方が更に速い結果となっています。
(2) Linux (Ubuntu 12.10 / 13.04)
x86/x64 は VMware Player によるテストなのでご了承ください。
特筆すべき点は pthread_mutex が SpinLock と全く変わらないか、
むしろ速いということです。
SpinLock を作る場合に atomic API の使い方を間違えると、
pthread_mutex よりも遅くなったり、ロックに失敗したりするようです。
X86/x64 の場合 gcc (4.7.2) builtin の __atomic_ でメモリアクセス方法に
__ATOMIC_SEQ_CST を指定すると pthread_mutex よりも低速でした。
__ATOMIC_RELAXED で pthread と同等になります。
また Legacy API ですが __sync_ を使った場合も pthread と同等の
速度となりました。
ARM (Cortex-A9) では RELAXED の場合メモリアクセスが競合し
正しくブロックされません。
上記テストは ARM の場合のみ SEQ_CST を指定しています。
また __sync_ も RELAXED 相当なためかロックされませんでした。
(3) MacOS X (10.8)
OSAtomic と phtread_mutex で大きな隔たりがあります。
同じ pthread の mutex でも、Linux と違い Windows のように
カーネルオブジェクトとして実装されている可能性があります。
API が同一でも OS と CPU によって挙動が違うことがわかりました。
Linux では pthread_mutex が最もよい選択ですが、
MacOS X では逆に pthread_mutex を避けた方が良いようです。
テストプログラムは下記のとおり。
template<typename LockT> class LockTest { LockT lock; static int Counter; enum { MAX_LOOP= 50000 }; public: void thread_func() { for( int i= 0 ; i< MAX_LOOP ; i++ ){ lock.Lock(); Counter++; lock.Unlock(); } } void Run() { ClockTimer time; Counter= 0; Thread t0, t1, t2; t0.Run( this, &LockTest<LockT>::thread_func ); t1.Run( this, &LockTest<LockT>::thread_func ); t2.Run( this, &LockTest<LockT>::thread_func ); t0.Join(); t1.Join(); t2.Join(); time.Output(); assert( Counter == MAX_LOOP * 3 ); } };
関連?エントリ
・C++11 Rvalue Reference 右辺値参照
2013/02/16
OpenGL ES 3.0 と GPU
Khronos Conformant Products に OpenGL ES 3.0 の名前が
登場しています。
Intel HD Graphics 4000/2500
PowerVR Rouge Hood (PowerVR Series 6)
Snapdragon MSM8974 (Adreno 330)
Snapdragon MSM8064 (Adreno 320)
OpenGLES 3.0 API は GL 4.3 の互換モードや Emulator ですでにテスト可能(詳細)
ですが、モバイルデバイスでも HW の対応が進行しています。
ARM Mali はもちろん Vivante もすでに 3.0 に対応しているとのことです。
・Vivante
↑の i.MX6 Quad といえば thanko Android SmartTV Quad-core に使われています。
唯一対応が未定で 2.0 のままなのは Tegra シリーズだけとなっています。
NVIDIA には Desktop GPU があるため余裕があるのかもしれません。
関連エントリ
・OpenGL 4.3/GLES 3.0 次の圧縮テクスチャ ASTC
・OpenGL ES 3.0 と OpenGL ES 2.0 の互換性
・OpenGL ES 3.0 と Shader Model の関係、まとめ wiki の更新
・OpenGL ES 2.0/3.0 Emulator
・OpenGL 4.3 と GL_ARB_ES3_compatibility
登場しています。
Intel HD Graphics 4000/2500
PowerVR Rouge Hood (PowerVR Series 6)
Snapdragon MSM8974 (Adreno 330)
Snapdragon MSM8064 (Adreno 320)
OpenGLES 3.0 API は GL 4.3 の互換モードや Emulator ですでにテスト可能(詳細)
ですが、モバイルデバイスでも HW の対応が進行しています。
ARM Mali はもちろん Vivante もすでに 3.0 に対応しているとのことです。
・Vivante
↑の i.MX6 Quad といえば thanko Android SmartTV Quad-core に使われています。
唯一対応が未定で 2.0 のままなのは Tegra シリーズだけとなっています。
NVIDIA には Desktop GPU があるため余裕があるのかもしれません。
関連エントリ
・OpenGL 4.3/GLES 3.0 次の圧縮テクスチャ ASTC
・OpenGL ES 3.0 と OpenGL ES 2.0 の互換性
・OpenGL ES 3.0 と Shader Model の関係、まとめ wiki の更新
・OpenGL ES 2.0/3.0 Emulator
・OpenGL 4.3 と GL_ARB_ES3_compatibility
Nexus 7 の Ubuntu 13.04 は armhf (hard-float) です。
Android NDK は softfp なので、
Ubuntu の方が関数呼び出しが効率化されていると考えられます。
比べてみました。
↓gcc によるコンパイル結果 (softfp)
soft といっても浮動小数点演算をエミュレーション実行しているわけではなく、
上記のように VFP や NEON 等の HW 演算ユニットが使われています。
あくまで ABI (Calling Convention) の話で、関数の呼び出し時のレジスタの
使われ方が異なります。
softfp の場合は FPU (VFP) が無い場合 (soft) と互換性が取れるように、
レジスタ渡しの場合に浮動小数点値も整数レジスタ(r)に入ります。
上の結果でも、毎回整数レジスタ(r)に入った引数を VFP レジスタ(s)へ
コピーしていることがわかります。
-mfloat-abi=hard を指定すると↓下記のように不要な転送が無くなりました。
引数や戻り値としてそのまま VFP レジスタ(s)が使われています。
↓さらに vfpv4 を指定すると、fmacs の代わりに vfma が使われていることがわかります。
NEON 命令も試してみました。
-ffast-math を付けると neon 命令に変換できます。
↓softfp では 128bit x2 の値をレジスタだけで渡すことができません。
2つ目の引数が stack に入っています。
↓hard の場合すべてレジスタで受け渡し可能となります。
以上より hard-float の場合に下記の 2つのメリットあるようです。
(他にもあるかもしれません)
・整数レジスタとの転送が不要となる
・引数として利用可能なレジスタの個数が増える
具体的な速度は測定していませんが、より高速に実行できると考えられます。
Android NDK だけでなく iOS の新しいアーキテクチャ armv7s でも softfp
相当となっているようです。
関連エントリ
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
Android NDK は softfp なので、
Ubuntu の方が関数呼び出しが効率化されていると考えられます。
比べてみました。
// 元のソース float func2( float a, float b, float c ) { return a * b + c; } float func3( float a, float b, float c ) { return a + b - c; } float func1( float a, float b ) { return a * b + a; }
↓gcc によるコンパイル結果 (softfp)
// -marm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3 fmsr s14, r0 fmsr s13, r2 fmsr s15, r1 fmacs s13, s14, s15 fmrs r0, s13 bx lr fmsr s13, r0 fmsr s14, r1 fadds s15, s13, s14 fmsr s13, r2 fsubs s13, s15, s13 fmrs r0, s13 bx lr fmsr s13, r0 fmsr s15, r1 fmacs s13, s13, s15 fmrs r0, s13 bx lr
soft といっても浮動小数点演算をエミュレーション実行しているわけではなく、
上記のように VFP や NEON 等の HW 演算ユニットが使われています。
あくまで ABI (Calling Convention) の話で、関数の呼び出し時のレジスタの
使われ方が異なります。
softfp の場合は FPU (VFP) が無い場合 (soft) と互換性が取れるように、
レジスタ渡しの場合に浮動小数点値も整数レジスタ(r)に入ります。
上の結果でも、毎回整数レジスタ(r)に入った引数を VFP レジスタ(s)へ
コピーしていることがわかります。
-mfloat-abi=hard を指定すると↓下記のように不要な転送が無くなりました。
引数や戻り値としてそのまま VFP レジスタ(s)が使われています。
// -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3 fmacs s2, s0, s1 fcpys s0, s2 bx lr fadds s0, s0, s1 fsubs s0, s0, s2 bx lr fmacs s0, s0, s1 bx lr
↓さらに vfpv4 を指定すると、fmacs の代わりに vfma が使われていることがわかります。
// -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv4 vfma.f32 s2, s0, s1 fcpys s0, s2 bx lr fadds s0, s0, s1 fsubs s0, s0, s2 bx lr vfma.f32 s0, s0, s1 bx lr
NEON 命令も試してみました。
// 元のソース #include <arm_neon.h> float32x4_t func4( float32x4_t a, float32x4_t b ) { return a * b + a; }
-ffast-math を付けると neon 命令に変換できます。
↓softfp では 128bit x2 の値をレジスタだけで渡すことができません。
2つ目の引数が stack に入っています。
// -marm -march=armv7-a -mfloat-abi=softfp -mfpu=neon -ffast-math vmov d16, r0, r1 @ v4sf vmov d17, r2, r3 vld1.64 {d18-d19}, [sp:64] vmla.f32 q8, q9, q8 vmov r0, r1, d16 @ v4sf vmov r2, r3, d17 bx lr
↓hard の場合すべてレジスタで受け渡し可能となります。
// -marm -march=armv7-a -mfloat-abi=hard -mfpu=neon -ffast-math vmla.f32 q0, q1, q0 bx lr
以上より hard-float の場合に下記の 2つのメリットあるようです。
(他にもあるかもしれません)
・整数レジスタとの転送が不要となる
・引数として利用可能なレジスタの個数が増える
具体的な速度は測定していませんが、より高速に実行できると考えられます。
Android NDK だけでなく iOS の新しいアーキテクチャ armv7s でも softfp
相当となっているようです。
関連エントリ
・Nexus 7 上に開発環境をつくる (3) Ubuntu
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
2013/02/14
Nexus 7 上に開発環境をつくる (3) Ubuntu
Nexus 7 に Ubuntu 13.04を入れています。
Bluetooth が使えるようになりかなり実用度が増しました。
下記はあくまで 2013/02/14 現在のものです。
日々更新されていますので、そのまま鵜呑みにせずその時点での
最新情報を探すようにしてください。
●オンラインストレージ
NetWalker の時は ARM で動く Dropbox が無く不便だったのですが、
今では Ubuntu One が入っているので全く困らなくなりました。
同様に使えるオンラインストレージで、もちろん ARM で動きます。
5GB まで無料。
● WiMAX / 有線LAN
WiMAX ルーターに Wi-Fi でつながるのは当たり前ですが、
USB による有線接続も可能でした。試したのは下記の 2機種。
・NEC Aterm WM3600R
・NEC Aterm WM3800R
USB Host にケーブルでつなぐだけで認識します。
駅前など Wi-Fi が混雑していて安定しない場所で使えるかもしれません。
有線 LAN アダプタ LUA3-U2-ATX も使えています。
●テザリング
同様に SB iPhone5, au HTC J butterfly HTL21 も USB 接続しましたが
こちらはつながりません。
もちろん Wi-Fi や Bluetooth ではテザリングできます。
Bluetooth の場合はペアリングだけではだめで、
「Use your mobile phone as a network device (PAN/NAP)」
のチェックが必要です。
その後端末側から接続を選ぶ→右上の Network のポップアップから
端末名を選択する流れになります。
●スクリーンキーボード
リサイズ出来ます。
横画面で大きめにしておくとタッチしやすくなります。
マウスポインタアイコンで拡張パネルが開き、右ボタン等の操作が可能ですが、
複雑な操作をしていると固まる事が多いです。
マウスは使えるので、タッチが反応しない場合や突然ロック画面に飛ばされた
場合は、マウスをつないで再起動した方が良いです。
●armhf
こちらのコメントにも書きましたが hard-float なので、
NDK より呼び出し効率が上がっているものと考えられます。
続きます。
関連エントリ
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
Bluetooth が使えるようになりかなり実用度が増しました。
下記はあくまで 2013/02/14 現在のものです。
日々更新されていますので、そのまま鵜呑みにせずその時点での
最新情報を探すようにしてください。
●オンラインストレージ
NetWalker の時は ARM で動く Dropbox が無く不便だったのですが、
今では Ubuntu One が入っているので全く困らなくなりました。
同様に使えるオンラインストレージで、もちろん ARM で動きます。
5GB まで無料。
● WiMAX / 有線LAN
WiMAX ルーターに Wi-Fi でつながるのは当たり前ですが、
USB による有線接続も可能でした。試したのは下記の 2機種。
・NEC Aterm WM3600R
・NEC Aterm WM3800R
USB Host にケーブルでつなぐだけで認識します。
駅前など Wi-Fi が混雑していて安定しない場所で使えるかもしれません。
有線 LAN アダプタ LUA3-U2-ATX も使えています。
●テザリング
同様に SB iPhone5, au HTC J butterfly HTL21 も USB 接続しましたが
こちらはつながりません。
もちろん Wi-Fi や Bluetooth ではテザリングできます。
Bluetooth の場合はペアリングだけではだめで、
「Use your mobile phone as a network device (PAN/NAP)」
のチェックが必要です。
その後端末側から接続を選ぶ→右上の Network のポップアップから
端末名を選択する流れになります。
●スクリーンキーボード
リサイズ出来ます。
横画面で大きめにしておくとタッチしやすくなります。
マウスポインタアイコンで拡張パネルが開き、右ボタン等の操作が可能ですが、
複雑な操作をしていると固まる事が多いです。
マウスは使えるので、タッチが反応しない場合や突然ロック画面に飛ばされた
場合は、マウスをつないで再起動した方が良いです。
●armhf
こちらのコメントにも書きましたが hard-float なので、
NDK より呼び出し効率が上がっているものと考えられます。
続きます。
関連エントリ
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
・Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0
2013/02/13
C++11 Rvalue Reference 右辺値参照
C++11 の新機能を使うとオブジェクトの無駄なコピーを減らすことができます。
記述が簡単になるなど、C++11 にはいろいろ便利に使える追加機能があります。
Rvalue Reference の場合はむしろコードが増えるのですが、
うまく使うことでプログラムの動作を効率化することができます。
とりあえず適当に文字列型を作ってみます。
copy 時に文字列バッファの複製が発生します。
例えばこんな感じ。
C++11 の Rvalue Reference を使うと特定のケースで copy を move に変換出来ます。
対応コードを追加したのが下記の形。
これで転送元を捨てても構わない場合に copy ではなく破壊転送 (move) が行われます。
上の場合はメモリを確保し直す必要がないので効率が上がります。
転送元を捨てても構わないケースの代表が、
一時確保されたオブジェクトである rvalue 右辺値です。
また明示的に std::move() をつければ任意の値を破壊転送することができます。
これで C++11 の場合は (1),(2) において copy が消えます。
どちらも一時的な object が作られているからです。
さらに適当なベクターを作ってみます。
ループさせてどの程度高速化されるか測ってみます。
差が出るように作ったので C++11 でコンパイルした方が速いのは当然なのですが、
実際にメモリ確保の回数が半減していることがわかります。
特定のケースで明らかな無駄を省いているだけなので、通常はここまで差がでません。
例えば (3) の場合何もせずに copy を減らすことはできません。
move の場合は結局 move 用に別の API を設けていることになります。
またオブジェクトだけでなく、copy が発生する API を経由する場合も
copy の他に move 用の別のルートを追加する必要があります。
途中で move() や forward() を付け忘れると、オブジェクトまで到達しないで
途切れてしまいます。
上の MyVector 自体も複製できるようにしてみます。
下記のように MyVector を代入できるようになりました。
この (5) のケースでは完全な move となり string のメモリ確保が発生しません。
ですが std::move() を付け忘れると move でなく MyString の copy になります。
下記のように alloc/free が増えます。(5) でも同じです。
記述が簡単になるなど、C++11 にはいろいろ便利に使える追加機能があります。
Rvalue Reference の場合はむしろコードが増えるのですが、
うまく使うことでプログラムの動作を効率化することができます。
とりあえず適当に文字列型を作ってみます。
class MyString { char* Name; private: void Clear() { delete[] Name; Name= NULL; } void Copy( const char* str ) { Clear(); size_t length= strlen(str)+1; Name= new char[length]; memcpy( Name, str, sizeof(char)*length ); } void DeepCopy( const MyString& src ) { Copy( src.Name ); } public: MyString() : Name( NULL ) {} MyString( const MyString& src ) : Name( NULL ) { DeepCopy( src ); } MyString( const char* str ) : Name( NULL ) { Copy( str ); } ~MyString() { Clear(); } MyString& operator=( const MyString& src ) { DeepCopy( src ); return *this; } };
copy 時に文字列バッファの複製が発生します。
例えばこんな感じ。
MyString str1; MyString str2; str1= "abcdefg"; // -- (1) str2= MyString( "ABCDEF" ); // -- (2) str1= str2; // -- (3)
C++11 の Rvalue Reference を使うと特定のケースで copy を move に変換出来ます。
対応コードを追加したのが下記の形。
#include <string.h> #include <utility> #ifndef IS_CPP11 # define IS_CPP11 (__cplusplus > 199711L) #endif int AllocCount; int FreeCount; class MyString { char* Name; private: void Clear() { if( Name ){ FreeCount++; } delete[] Name; Name= NULL; } void Copy( const char* str ) { Clear(); size_t length= strlen(str)+1; Name= new char[length]; memcpy( Name, str, sizeof(char)*length ); AllocCount++; } void DeepCopy( const MyString& src ) { Copy( src.Name ); } public: MyString() : Name( NULL ) {} MyString( const MyString& src ) : Name( NULL ) { DeepCopy( src ); } MyString( const char* str ) : Name( NULL ) { Copy( str ); } ~MyString() { Clear(); } MyString& operator=( const MyString& src ) { DeepCopy( src ); return *this; } //-- ↓ここから追加分 #if IS_CPP11 MyString( MyString&& src ) { Name= src.Name; src.Name= NULL; } MyString& operator=( MyString&& src ) { char* tmp= Name; Name= src.Name; src.Name= tmp; return *this; } #endif };
これで転送元を捨てても構わない場合に copy ではなく破壊転送 (move) が行われます。
上の場合はメモリを確保し直す必要がないので効率が上がります。
転送元を捨てても構わないケースの代表が、
一時確保されたオブジェクトである rvalue 右辺値です。
また明示的に std::move() をつければ任意の値を破壊転送することができます。
これで C++11 の場合は (1),(2) において copy が消えます。
どちらも一時的な object が作られているからです。
さらに適当なベクターを作ってみます。
template<typename T> class MyVector { T* Buffer; T* Ptr; size_t BufferSize; private: void Clear() { delete[] Buffer; Buffer= Ptr= NULL; } public: MyVector() : Buffer( NULL ), Ptr( NULL ), BufferSize( 0 ) {}; MyVector( size_t size ) : BufferSize( size ) { Ptr= Buffer= new T[size]; } ~MyVector() { Clear(); } size_t Size() const { return Ptr - Buffer; } T& operator[]( size_t index ) { return Buffer[index]; } const T& operator[]( size_t index ) const { return Buffer[index]; } void PushBack( const T& src ) { assert( Ptr < Buffer + BufferSize ); *Ptr++= src; } #if IS_CPP11 void PushBack( T&& src ) { assert( Ptr < Buffer + BufferSize ); *Ptr++= std::forward<T>(src); } #endif };
ループさせてどの程度高速化されるか測ってみます。
// main.cpp int main() { AllocCount= 0; FreeCount= 0; { const int LOOP_MAX= 100000; MyVector<MyString> string_list( LOOP_MAX ); for( int i= 0 ; i< LOOP_MAX ; i++ ){ string_list.PushBack( "12345" ); } } printf( "alloc=%d free=%d\n", AllocCount, FreeCount ); return 0; }
差が出るように作ったので C++11 でコンパイルした方が速いのは当然なのですが、
実際にメモリ確保の回数が半減していることがわかります。
Prog time output c03 0m0.015s alloc=200000 free=200000 c11 0m0.009s alloc=100000 free=100000
# Makefile mac: clang++ -std=c++11 -stdlib=libc++ -O4 main.cpp -o c11 clang++ -std=c++03 -stdlib=libc++ -O4 main.cpp -o c03 linux: g++ -std=c++11 -O4 main.cpp -o g11 g++ -std=c++03 -O4 main.cpp -o g03 clang++ -std=c++11 -O3 main.cpp -o c11 clang++ -std=c++03 -O3 main.cpp -o c03 win: cl /O2 main.cpp /Fev11.exe -DIS_CPP11=1 cl /O2 main.cpp /Fev03.exe -DIS_CPP11=0
特定のケースで明らかな無駄を省いているだけなので、通常はここまで差がでません。
例えば (3) の場合何もせずに copy を減らすことはできません。
move の場合は結局 move 用に別の API を設けていることになります。
またオブジェクトだけでなく、copy が発生する API を経由する場合も
copy の他に move 用の別のルートを追加する必要があります。
途中で move() や forward() を付け忘れると、オブジェクトまで到達しないで
途切れてしまいます。
上の MyVector 自体も複製できるようにしてみます。
template<typename T> class MyVector { T* Buffer; T* Ptr; size_t BufferSize; private: void Clear() { delete[] Buffer; Buffer= Ptr= NULL; } #if IS_CPP11 void Move( MyVector&& src ) { Clear(); BufferSize= src.BufferSize; Ptr= Buffer= new T[BufferSize]; for( int i= 0 ; i< BufferSize ; i++ ){ *Ptr++= std::move(src[i]); //-- (4) } } #endif void DeepCopy( const MyVector& src ) { Clear(); BufferSize= src.BufferSize; Ptr= Buffer= new T[BufferSize]; for( int i= 0 ; i< BufferSize ; i++ ){ *Ptr++= src[i]; } } public: MyVector() : Buffer( NULL ), Ptr( NULL ), BufferSize( 0 ) {}; MyVector( size_t size ) : BufferSize( size ) { Ptr= Buffer= new T[size]; } ~MyVector() { Clear(); } size_t Size() const { return Ptr - Buffer; } void PushBack( const T& src ) { assert( Ptr < Buffer + BufferSize ); *Ptr++= src; } #if IS_CPP11 void PushBack( T&& src ) { assert( Ptr < Buffer + BufferSize ); *Ptr++= std::forward<T>(src); } #endif T& operator[]( size_t index ) { return Buffer[index]; } const T& operator[]( size_t index ) const { return Buffer[index]; } MyVector& operator=( const MyVector& src ) { DeepCopy( src ); return *this; } #if IS_CPP11 MyVector& operator=( MyVector&& src ) { Move( std::move(src) ); return *this; } #endif };
下記のように MyVector を代入できるようになりました。
この (5) のケースでは完全な move となり string のメモリ確保が発生しません。
int main() { AllocCount= 0; FreeCount= 0; { const int LOOP_MAX= 100000; MyVector<MyString> string_list( LOOP_MAX ); for( int i= 0 ; i< LOOP_MAX ; i++ ){ string_list.PushBack( "12345" ); } MyVector<MyString> string_list2( LOOP_MAX ); string_list2= std::move(string_list); // -- (5) } printf( "alloc=%d free=%d\n", AllocCount, FreeCount ); return 0; }
ですが std::move() を付け忘れると move でなく MyString の copy になります。
下記のように alloc/free が増えます。(5) でも同じです。
c03 alloc=300000 free=300000 c11 alloc=200000 free=200000 ( (5) or (6) の move 無し ) c11 alloc=100000 free=100000
2013/02/12
SoC spec list
●Bluetooth
前回の記事では未対応と書きましたが、その直後 2013/02/02 以降の ROM で
Bluetooth が使えるようになっています。
・ubuntu wiki: Using the Device
給電しながら外部キーボードやマウスが使えるようになりました。
●Nexus 7 に Android 端末をつなぐ
SDK を install できるわけではありませんが adb は使えます。
USB Host に他の Android 端末をつないで adb で接続できます。
端末によっては充電しようとするので、セルフパワー(ACアダプタ付き) USB ハブを
経由した方が良いと思います。

↑HTC J butterfly HTL21 をつないで "adb devices" や "adb shell" 等が可能です。
Host の Nexus 7 (RAM 1GB A9 1.2GHz) よりも butterfly (RAM 2GB Krait 1.5GHz)
の方が性能が高いので本当は逆にしたいところです。
●3D / OpenGL ES 2.0
OpenGL でないため GLX は動作しないものの、
描画には OpenGL ES v2.0 + EGL が使われています。
・NVIDIA: Linux For Tegra
↑上の NVIDIA サイトのドキュメントにあるように mesa-utils-extra を入れると
OpenGL ES 2.0 を使ったアプリの動作を確認できます。

glxinfo の代わりに es2_info コマンドでドライバの確認ができるようです。
WebGL も試しましたが、Firefox/Chromium とも動作しませんでした。
フラグ自体は有効に出来ます。
●software
Software center の Installed tab が開きませんが、
Unity の dash 画面でアプリケーションの uninstall ができます。
Launcher 一番上のボタンで dash 画面を開いてタブを切り替え、
Installed の中でアイコンを右クリックです。
関連エントリ
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
前回の記事では未対応と書きましたが、その直後 2013/02/02 以降の ROM で
Bluetooth が使えるようになっています。
・ubuntu wiki: Using the Device
給電しながら外部キーボードやマウスが使えるようになりました。
●Nexus 7 に Android 端末をつなぐ
SDK を install できるわけではありませんが adb は使えます。
sudo apt-get install android-tools-adb
USB Host に他の Android 端末をつないで adb で接続できます。
端末によっては充電しようとするので、セルフパワー(ACアダプタ付き) USB ハブを
経由した方が良いと思います。

↑HTC J butterfly HTL21 をつないで "adb devices" や "adb shell" 等が可能です。
Host の Nexus 7 (RAM 1GB A9 1.2GHz) よりも butterfly (RAM 2GB Krait 1.5GHz)
の方が性能が高いので本当は逆にしたいところです。
●3D / OpenGL ES 2.0
OpenGL でないため GLX は動作しないものの、
描画には OpenGL ES v2.0 + EGL が使われています。
・NVIDIA: Linux For Tegra
↑上の NVIDIA サイトのドキュメントにあるように mesa-utils-extra を入れると
OpenGL ES 2.0 を使ったアプリの動作を確認できます。
sudo apt-get install mesa-utils-extra /usr/bin/es2gears

glxinfo の代わりに es2_info コマンドでドライバの確認ができるようです。
WebGL も試しましたが、Firefox/Chromium とも動作しませんでした。
フラグ自体は有効に出来ます。
●software
Software center の Installed tab が開きませんが、
Unity の dash 画面でアプリケーションの uninstall ができます。
Launcher 一番上のボタンで dash 画面を開いてタブを切り替え、
Installed の中でアイコンを右クリックです。
関連エントリ
・Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
2013/02/03
Android Tablet Nexus 7 上に開発環境をつくる (Ubuntu)
Bitbucket などクラウド系のリポジトリサービスを使うと、
どこでもソースコードをチェックできるので非常に便利です。
電車の中や外出時だろうと、ちょっとした空き時間にブラウザだけで
コードを追うことができます。
そのうち欲が出てきて、どうせならこのままコードを手直ししたいとか
コンパイルもできたらいいのに、とか思うようになります。
最近のモバイルデバイスは非常に性能が高いので、
クロス開発でなく自分でコンパイルしてもそれなりに速いはずです。
Android 端末なら各種 Linux 環境を install できそうなので試してみました。

Nexus 7 で動く Ubuntu 13.04
●開発環境として
gcc, clang はもちろん、python, git, mercurial などそのまま使えるので
ライブラリのコンパイルや arm CPU のテストには十分です。
RAM は 1GB しかありませんが、CPU も 4core なのでコンパイルも予想より
高速でした。
パフォーマンスも NetWalker の時代とは比べ物にならず、
Atom NetBook でコンパイルするよりも快適です。
実際にコンパイル速度を比べてみました。
C++ の lib のコンパイルで Debug/Release 両方生成しています。
すべてコマンドラインからのビルドで HW thread の数だけ並列化しています。
CPU だけでなくストレージの速度なども大きく影響しているので一概には言えませんが、
このサイズで持ち歩けてこの速度でビルドできるなら満足です。
用途にもよりますが、すでに "動かしてみた" レベルではなくなっているといえます。
● Nexus 7 で動く Linux 環境
・LINUX ON ANDROID
・AndroidLinux.com
・Ubuntu Nexus 7 Desktop Installer
大きく分けて二通りあり、Android として boot したままソフトウエア環境を
置き換えるタイプと、Native に最初から Linux として boot するタイプです。
前者は Android が動作したまま、chroot したプロセスのみが
あたかも Desktop Linux であるかのように振舞います。
Android 環境と併存するため比較的抵抗が少ないですが、
母体となる Android の root 権限が必要となるため、
何らかの方法で取得しておかなければなりません。
冒頭のコンパイル速度比較にある Optimus Pad (L-06C) はこちらです。
Android 上から起動して ssh 経由でコマンドラインのみ使用しています。
Window System が Native なものではないので GUI は期待出来ませんが
コマンドラインベースなら十分使える印象でした。
後者は bootloader を unlock して完全に新たな OS で置き換えます。
PC の HDD を消してクリーンインストールするようなものです。
実際は OS を置き換えなくても、Android の起動イメージを残したまま
boot 時のセレクタで切り替えることができるらしいので試してみました。
↓下記ページを参考にさせて頂きました。
・Nexus 7でUbuntuをUSBメモリにインストールしてデュアルブートで起動して使う方法。
USB メモリがなくても内蔵ストレージにも共存可能な形で install できました。
・xda-developers: [WiFi&3G] MultiROM v7 - updated recovery (Feb 02)
bootloader を unlock したあとに Multi boot 可能な bootloader を入れて、
install 機能を持った recovery tool を用いて OS image を書き込みます。
もちろんこれらの作業はすべて自己責任で行うことになります。
●使ってみて
Window の描画や文字が一部欠けたりとまだ不安定なところがあります。
その代わり HW アクセラレートがきいておりそれなりに高速です。
VAIO type P (Z500系 Atom) に入れた Ubuntu 12.10 よりも快適です。
タッチ操作できるようにカスタマイズされておりスクリーンキーボードも使えます。
きちんと日本語キーボードの配列に切り替わりますが、なぜか '_' の入力ができません。
縦画面にも回転できます。
・ubuntu Using the Device
現時点 (2013/02/03) で Bluetooth がまだ使えないようです。
USB Host ケーブルを使えば USB 外付けの Mouse や Keyboard をつなげることができます。
Ubuntu の豊富なソフトウエアを利用できる点が魅力です。
試しに blender を install してみましたが、GLX が無く起動しませんでした。
gimp は動きました。
Chromium ブラウザをしばらく使っていると画面全体が壊れることがあります。
おそらくメモリ不足なので、swap を作った方が良いのかもしれません。
Tegra4 の Cortex-A15 や Qualcomm Krait 等、新しい世代の CPU では
I/O 含めてさらに高速に動作するはずです。
PC 無しに、Android アプリの自己開発ができるようになると面白いかもしれません。
・続きます「Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0」
どこでもソースコードをチェックできるので非常に便利です。
電車の中や外出時だろうと、ちょっとした空き時間にブラウザだけで
コードを追うことができます。
そのうち欲が出てきて、どうせならこのままコードを手直ししたいとか
コンパイルもできたらいいのに、とか思うようになります。
最近のモバイルデバイスは非常に性能が高いので、
クロス開発でなく自分でコンパイルしてもそれなりに速いはずです。
Android 端末なら各種 Linux 環境を install できそうなので試してみました。

Nexus 7 で動く Ubuntu 13.04
●開発環境として
gcc, clang はもちろん、python, git, mercurial などそのまま使えるので
ライブラリのコンパイルや arm CPU のテストには十分です。
RAM は 1GB しかありませんが、CPU も 4core なのでコンパイルも予想より
高速でした。
パフォーマンスも NetWalker の時代とは比べ物にならず、
Atom NetBook でコンパイルするよりも快適です。
実際にコンパイル速度を比べてみました。
CPU OS HW thread Compiler 実行時間 --------------------------------------------------------------------- 1. Nexus 7 (Cortex-A9) Ubuntu arm 13.04 4 clang 3.2 12.5 sec 2. Nexus 7 (Cortex-A9) Ubuntu arm 13.04 4 gcc 4.7.2 18.2 sec 3. Optimus Pad (Cortex-A9) Ubuntu arm 12.04 2 clang 3.0 21.2 sec 4. Optimus Pad (Cortex-A9) Ubuntu arm 12.04 2 gcc 4.6.3 29.2 sec 5. VAIO type P (Atom Z540) Ubuntu x86 12.10 2 clang 3.0 26.1 sec 6. VAIO type P (Atom Z540) Ubuntu x86 12.10 2 gcc 4.7.2 33.5 sec 7. VAIO type P (Atom Z540) Windows 7 x86 2 vs2012 87.8 sec 8. NetWalker (Cortex-A8) Ubuntu arm 9.04 1 gcc 4.3.3 91.2 sec 9. Mac HDD(Core i7-3615QM) Windows 8 x64 8 vs2012 5.1 sec 10.Mac HDD(Core i7-3615QM) Win8 x64 + NDK 8 gcc 4.7 4.9 sec 11.Mac HDD(Core i7-3615QM) Win8 x64 + NaCl 8 gcc 4.4.3 4.1 sec 12.Mac HDD(Core i7-3615QM) Win8+VMP+u12.10 4 clang 3.0 1.6 sec 13.Mac HDD(Core i7-3615QM) Win8+VMP+u12.10 4 gcc 4.7.2 2.6 sec 14.Mac HDD(Core i7-3615QM) Win8+VMP+u +NaCl 4 gcc 4.4.3 3.0 sec 15.Mac SSD(Core i5-3210M) OSX10.8 x64 4 clang 4.2 2.3 sec 16.Mac SSD(Core i5-3210M) OSX10.8 x64 +NDK 4 gcc 4.7 6.4 sec 17.Mac SSD(Core i5-3210M) OSX+Para+u12.10 2 clang 3.0 3.0 sec 18.Mac SSD(Core i5-3210M) OSX+Para+u12.10 2 gcc 4.7.2 4.4 sec 19.Mac SSD(Core i5-3210M) OSX+Para+u +NaCl 2 gcc 4.4.3 4.1 sec 20.Mac (Core2 Duo P7350) Ubuntu x64 12.10 2 clang 3.2 4.3 sec 21.Mac (Core2 Duo P7350) Ubuntu x64 12.10 2 gcc 4.7.2 6.8 sec 22.Mac (Core2 Duo P7350) Ubuntu x64 + NDK 2 gcc 4.7 10.0 sec 実行時間が少ない方が高速 ・NDK= Android 向け build (NDK r8d) ・NaCl= Native Client 向け build (pepper_23) ・VMP=Windows の VMware Player 上で Ubuntu 12.10 x64 (4core) ・Para=MacOS X の Paralles8 上で Ubuntu 12.10 x64 (2core)
C++ の lib のコンパイルで Debug/Release 両方生成しています。
すべてコマンドラインからのビルドで HW thread の数だけ並列化しています。
CPU だけでなくストレージの速度なども大きく影響しているので一概には言えませんが、
このサイズで持ち歩けてこの速度でビルドできるなら満足です。
用途にもよりますが、すでに "動かしてみた" レベルではなくなっているといえます。
spec 詳細 Nexus 7 Tegra3 Cortex-A9 x4 1.2GHz RAM 1GB Optimus Pad L-06C Tegra2 Cortex-A9 x2 1.0GHz RAM 1GB VAIO type P Atom Z540 x1 HT2 1.83GHz RAM 2GB NetWalker PC-Z1 i.MX515 Cortex-A8 x1 0.8GHz RAM 0.5GB Mac HDD Core i7-3615QM x4 HT8 2.3GHz RAM 16GB Mac Book SSD Core i5-3210M x2 HT4 2.5GHz RAM 8GB Mac mini HDD Core2 Duo P7350 x2 2.0GHz RAM 8GB
● Nexus 7 で動く Linux 環境
・LINUX ON ANDROID
・AndroidLinux.com
・Ubuntu Nexus 7 Desktop Installer
大きく分けて二通りあり、Android として boot したままソフトウエア環境を
置き換えるタイプと、Native に最初から Linux として boot するタイプです。
前者は Android が動作したまま、chroot したプロセスのみが
あたかも Desktop Linux であるかのように振舞います。
Android 環境と併存するため比較的抵抗が少ないですが、
母体となる Android の root 権限が必要となるため、
何らかの方法で取得しておかなければなりません。
冒頭のコンパイル速度比較にある Optimus Pad (L-06C) はこちらです。
Android 上から起動して ssh 経由でコマンドラインのみ使用しています。
Window System が Native なものではないので GUI は期待出来ませんが
コマンドラインベースなら十分使える印象でした。
後者は bootloader を unlock して完全に新たな OS で置き換えます。
PC の HDD を消してクリーンインストールするようなものです。
実際は OS を置き換えなくても、Android の起動イメージを残したまま
boot 時のセレクタで切り替えることができるらしいので試してみました。
↓下記ページを参考にさせて頂きました。
・Nexus 7でUbuntuをUSBメモリにインストールしてデュアルブートで起動して使う方法。
USB メモリがなくても内蔵ストレージにも共存可能な形で install できました。
・xda-developers: [WiFi&3G] MultiROM v7 - updated recovery (Feb 02)
bootloader を unlock したあとに Multi boot 可能な bootloader を入れて、
install 機能を持った recovery tool を用いて OS image を書き込みます。
もちろんこれらの作業はすべて自己責任で行うことになります。
●使ってみて
Window の描画や文字が一部欠けたりとまだ不安定なところがあります。
その代わり HW アクセラレートがきいておりそれなりに高速です。
VAIO type P (Z500系 Atom) に入れた Ubuntu 12.10 よりも快適です。
タッチ操作できるようにカスタマイズされておりスクリーンキーボードも使えます。
きちんと日本語キーボードの配列に切り替わりますが、なぜか '_' の入力ができません。
縦画面にも回転できます。
・ubuntu Using the Device
現時点 (2013/02/03) で Bluetooth がまだ使えないようです。
USB Host ケーブルを使えば USB 外付けの Mouse や Keyboard をつなげることができます。
Ubuntu の豊富なソフトウエアを利用できる点が魅力です。
試しに blender を install してみましたが、GLX が無く起動しませんでした。
gimp は動きました。
Chromium ブラウザをしばらく使っていると画面全体が壊れることがあります。
おそらくメモリ不足なので、swap を作った方が良いのかもしれません。
Tegra4 の Cortex-A15 や Qualcomm Krait 等、新しい世代の CPU では
I/O 含めてさらに高速に動作するはずです。
PC 無しに、Android アプリの自己開発ができるようになると面白いかもしれません。
・続きます「Nexus 7 上に開発環境をつくる (2) Bluetooth と OpenGL ES 2.0」