Android 4.3 で OpenGL ES 3.0 が導入されましたが、Adreno 320 では
一部動作に問題がありました。
具体的には Uniform Block を使用すると glLinkProgram でエラーが発生します。
Android 4.4 ではこの問題が直っており、正しく動作することが確認できました。
GPU のドライバが更新されたためだと考えられます。
以前の症状について詳しくは こちら。
他にも glIntergerv() (Query) の値など修正が入っているようです。
・CPU/GPU OpenGL ES Extension (Mobile GPU)
OpenGL ES 3.0 が動くデバイスもかなり増えてきました。
Android 4.4 なら Nexus 7 (2013) が使えるので、動作確認は比較的容易に
なったのではないかと思います。
ただ実際のアプリケーションでは、確実に OS が更新されるとわかっている
Nexus 以外で利用するのは正直厳しいと言えます。
他にも OpenGL ES 3.0 が使えるかどうかの判定がうまくいかないことがあります。
・OpenGL ES : Checking OpenGL ES Version
GPU によっては 3.0 を渡して Context を作ってもエラーにならず、
OpenGL ES 1.1 の Context を返すものがあります。
(おそらくドライバが 2.0 かそれ以外で判別している)
2番目の Version 番号を使う方法は Android ではうまくいきます。
Nexus 10, Nexus 7 (2013) ともに 2.0 context を作っても GL_VERSION は
3.0 を返すためです。
ただし iOS や PC では作成した context と同じバージョン文字列を返すので
少々不自然な気もします。
関連エントリ
・iPhone 5s の Apple A7 GPU
・Adreno 320 の OpenGL ES 3.0 と Uniform Block
・Nexus 7 (2013) の Adreno 320 と OpenGL ES 3.0 (Android 4.3)
一部動作に問題がありました。
具体的には Uniform Block を使用すると glLinkProgram でエラーが発生します。
Android 4.4 ではこの問題が直っており、正しく動作することが確認できました。
GPU のドライバが更新されたためだと考えられます。
以前の症状について詳しくは こちら。
# Nexus 7 (2013) Android 4.3 GL_VERSION: OpenGL ES 3.0 V@14.0 GL_RENDERER: Adreno (TM) 320 GL_VENDOR: Qualcomm GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00
# Nexus 7 (2013) Android 4.4 GL_VERSION: OpenGL ES 3.0 V@53.0 AU@ (CL@3776187) GL_RENDERER: Adreno (TM) 320 GL_VENDOR: Qualcomm GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00
他にも glIntergerv() (Query) の値など修正が入っているようです。
・CPU/GPU OpenGL ES Extension (Mobile GPU)
OpenGL ES 3.0 が動くデバイスもかなり増えてきました。
Android 4.4 なら Nexus 7 (2013) が使えるので、動作確認は比較的容易に
なったのではないかと思います。
ただ実際のアプリケーションでは、確実に OS が更新されるとわかっている
Nexus 以外で利用するのは正直厳しいと言えます。
他にも OpenGL ES 3.0 が使えるかどうかの判定がうまくいかないことがあります。
・OpenGL ES : Checking OpenGL ES Version
GPU によっては 3.0 を渡して Context を作ってもエラーにならず、
OpenGL ES 1.1 の Context を返すものがあります。
(おそらくドライバが 2.0 かそれ以外で判別している)
2番目の Version 番号を使う方法は Android ではうまくいきます。
Nexus 10, Nexus 7 (2013) ともに 2.0 context を作っても GL_VERSION は
3.0 を返すためです。
ただし iOS や PC では作成した context と同じバージョン文字列を返すので
少々不自然な気もします。
関連エントリ
・iPhone 5s の Apple A7 GPU
・Adreno 320 の OpenGL ES 3.0 と Uniform Block
・Nexus 7 (2013) の Adreno 320 と OpenGL ES 3.0 (Android 4.3)
2013/11/25
Android SmartWatch スマートウオッチのスペック比較表
Smart Watch をまとめてみました。
単体でアプリが動くものだけです。
・Smartwatch
関連エントリ
・Android SmartWatch SmartQ ZWatch (4) アプリの管理
・Android SmartWatch SmartQ ZWatch (3) 腕に関数電卓
・Android SmartWatch SmartQ ZWatch (2)
・Android 4.1 SmartWatch SmartQ Z Watch
単体でアプリが動くものだけです。
・Smartwatch
関連エントリ
・Android SmartWatch SmartQ ZWatch (4) アプリの管理
・Android SmartWatch SmartQ ZWatch (3) 腕に関数電卓
・Android SmartWatch SmartQ ZWatch (2)
・Android 4.1 SmartWatch SmartQ Z Watch
2013/11/20
Android SmartWatch SmartQ ZWatch (4) アプリの管理
壁紙も貼れます。

LiveWallpaper は無理っぽい。
PDF も開けるのでドキュメントを入れておくことも一応出来ます。

画面は小さいけどマルチタッチ使えました。
拡大縮小操作が可能で、とりあえずプログラムで 4点まで取れることは確認。
ES File Explorer が動きました。
(壁紙の設定も ES File Explorer から)
これで PC につないで adb コマンドを打たなくても
アプリの管理 (主に uninstall) ができるようになります。
左上のアイコンからスライドメニューを開いて、
Tools の中の AppManager を選ぶと下記の通り。

これでアプリの削除が簡単です。
Home 画面はセンターが時計 Widget (上下で face 切り替え)、
右側がアプリ一覧、左側が Widget です。
Wedget はサイズによらず、画面いっぱいに引き伸ばされるようです。

関連エントリ
・Android SmartWatch SmartQ ZWatch (3) 腕に関数電卓
・Android SmartWatch SmartQ ZWatch (2)
・Android 4.1 SmartWatch SmartQ Z Watch


LiveWallpaper は無理っぽい。
PDF も開けるのでドキュメントを入れておくことも一応出来ます。

画面は小さいけどマルチタッチ使えました。
拡大縮小操作が可能で、とりあえずプログラムで 4点まで取れることは確認。
ES File Explorer が動きました。
(壁紙の設定も ES File Explorer から)
これで PC につないで adb コマンドを打たなくても
アプリの管理 (主に uninstall) ができるようになります。
左上のアイコンからスライドメニューを開いて、
Tools の中の AppManager を選ぶと下記の通り。


これでアプリの削除が簡単です。
Home 画面はセンターが時計 Widget (上下で face 切り替え)、
右側がアプリ一覧、左側が Widget です。
Wedget はサイズによらず、画面いっぱいに引き伸ばされるようです。

関連エントリ
・Android SmartWatch SmartQ ZWatch (3) 腕に関数電卓
・Android SmartWatch SmartQ ZWatch (2)
・Android 4.1 SmartWatch SmartQ Z Watch
2013/11/19
Android SmartWatch SmartQ ZWatch (3) 腕に関数電卓

キーの数を減らして長押しに割り当ててみました。
これなら押せます。(右側の文字は長押し)

メニューも出ます。

ヒストリやメモリー保存もあり。
・ちょっと電卓 ZW (Google Play) (2013/12/01追加)
関連エントリ
・Android SmartWatch SmartQ ZWatch (2)
・Android 4.1 SmartWatch SmartQ Z Watch
2013/11/18
Android SmartWatch SmartQ ZWatch (2)
大きさ (下:Z Watch、上:iPod nano 6G)

画面サイズ、解像度は同じです。1.54inch 240x240 (220dpi)
当時 iPod nano (6G) で動くアプリを作りたいと思っていました。
LiveView はレスポンスに難がありましたが、単独でアプリを走らせられる
SmartWatch ならいろいろ出来そうです。
・SmartQ Z Watch
SmartWatch は 2種類あります。
(1) サブモニタ型
・一般の Smartphone や Tablet のサブモニタとして利用する
・単体ではアプリケーションが動作せず Dumb Terminal に近い
・キー入力をサーバーに送り、画面出力だけ Bluetooth で受け取る
・もっと単純なものは特定の通知だけを受け取ることができる
(2) 単独動作可能
・一般の Smartphone や Tablet を小さくして腕時計形状にしたもの
・Android 等の OS がそのまま乗っておりアプリを走らせられる
・アプリを使って (1) のような使い方もできるが、データはローカルに蓄積される
(1画面ごとに通信するわけではない)
Sony の LiveView/MN2 系は (1) で、ZWatch は (2) に相当します。
Z Watch は右側面に電源ボタンと Back ボタンがあります。
Back ボタンは長押しで Home 相当。
左側はヘットホン端子のみで、USB&充電を兼ねています。
時計画面は Home の Widget に相当するようです。
デザインは切り替え可能。
普段はバックライトが消えていて時刻を確認できませんが、
腕のアクションで一時的に画面を点灯させることができます。
水平状態から手前に傾けるイメージ。
知らないうちに点灯してる場合結構あります。
角度をつけて机に置いた状態でも反応してしまうのが難点。
Home には他にも画面単位で Widget を追加できます。
アプリの追加や削除には PC が必要。(adb 接続方法はこちら)
Mac OS X でも adb でつながります。
adb shell では su 可能。
Android 4.1 + 1GHz single core CPU + RAM 512MB + ROM 4GB なので、
安価な Android 端末としては十分な性能。
ただし画面が小さいので、通常アプリは表示や操作に制限があります。
UI は専用に作らないと厳しいでしょう。
ソフトキーボードは入っていません。
マニュアルを読む限り、同期用に Android 端末を登録すれば
リモートキーボードとして使えるようです。
・AKIBA PC Hotline: SmartDevices(智器) Z Watch
・AKIBA PC Hotline: 中華な腕時計型デバイスがまた登場、Android 4.3ベースで1万5千円
設定の言語選択に日本語はありませんが、上記ページを見ると
日本語も表示されていることが確認できます。
公式サイトや上のページでは Android 4.3 と書かれていますが、
API Level は 16 を返します。つまり Android 4.1 相当。
ZWatch の JZ4775 は Paladin の JZ4770 と違い 3D GPU が搭載されていません。
OpenGL ES 2.0 を使ったアプリケーションは起動できませんでした。
↓レイアウトを調整してみました。使ってみるとこれでもまだボタンが小さく感じます。

関連エントリ
・Android 4.1 SmartWatch SmartQ Z Watch

画面サイズ、解像度は同じです。1.54inch 240x240 (220dpi)
当時 iPod nano (6G) で動くアプリを作りたいと思っていました。
LiveView はレスポンスに難がありましたが、単独でアプリを走らせられる
SmartWatch ならいろいろ出来そうです。
・SmartQ Z Watch
SmartWatch は 2種類あります。
(1) サブモニタ型
・一般の Smartphone や Tablet のサブモニタとして利用する
・単体ではアプリケーションが動作せず Dumb Terminal に近い
・キー入力をサーバーに送り、画面出力だけ Bluetooth で受け取る
・もっと単純なものは特定の通知だけを受け取ることができる
(2) 単独動作可能
・一般の Smartphone や Tablet を小さくして腕時計形状にしたもの
・Android 等の OS がそのまま乗っておりアプリを走らせられる
・アプリを使って (1) のような使い方もできるが、データはローカルに蓄積される
(1画面ごとに通信するわけではない)
Sony の LiveView/MN2 系は (1) で、ZWatch は (2) に相当します。
Z Watch は右側面に電源ボタンと Back ボタンがあります。
Back ボタンは長押しで Home 相当。
左側はヘットホン端子のみで、USB&充電を兼ねています。
時計画面は Home の Widget に相当するようです。
デザインは切り替え可能。
普段はバックライトが消えていて時刻を確認できませんが、
腕のアクションで一時的に画面を点灯させることができます。
水平状態から手前に傾けるイメージ。
知らないうちに点灯してる場合結構あります。
角度をつけて机に置いた状態でも反応してしまうのが難点。
Home には他にも画面単位で Widget を追加できます。
アプリの追加や削除には PC が必要。(adb 接続方法はこちら)
Mac OS X でも adb でつながります。
adb shell では su 可能。
Android 4.1 + 1GHz single core CPU + RAM 512MB + ROM 4GB なので、
安価な Android 端末としては十分な性能。
ただし画面が小さいので、通常アプリは表示や操作に制限があります。
UI は専用に作らないと厳しいでしょう。
ソフトキーボードは入っていません。
マニュアルを読む限り、同期用に Android 端末を登録すれば
リモートキーボードとして使えるようです。
・AKIBA PC Hotline: SmartDevices(智器) Z Watch
・AKIBA PC Hotline: 中華な腕時計型デバイスがまた登場、Android 4.3ベースで1万5千円
設定の言語選択に日本語はありませんが、上記ページを見ると
日本語も表示されていることが確認できます。
公式サイトや上のページでは Android 4.3 と書かれていますが、
API Level は 16 を返します。つまり Android 4.1 相当。
ZWatch の JZ4775 は Paladin の JZ4770 と違い 3D GPU が搭載されていません。
OpenGL ES 2.0 を使ったアプリケーションは起動できませんでした。
↓レイアウトを調整してみました。使ってみるとこれでもまだボタンが小さく感じます。

関連エントリ
・Android 4.1 SmartWatch SmartQ Z Watch
2013/11/16
Android 4.1 SmartWatch SmartQ Z Watch
SmartQ Z Watch を買ってみました。Android の SmartWatch です。
Bluetooth 経由の RemoteDisplay だった LiveView と違い、
単体で Android 4.1 が動作しています。

スペックによると中身は Ingenic JZ4775。
CPU は Xburst 1.0GHz で ainol Novo 7 Paladin と同じ mips です。
RAM も同じく 512MB。下記は ZWatch 実機より cpuinfo。
基本的には他の SmartWatch と同じように、母艦となる Android Smartphone
と Bluetooth 同期する使い方が想定されているようです。
そのため内蔵のアプリケーションは最小限で設定項目もごくわずか。
アプリケーション管理も無いので、単独で Z Watch 側のアプリの
追加や削除を行う方法が見当たりませんでした。
USB 接続で MTP ストレージとして認識するのでアクセスは容易です。
内部ストレージに update.zip を転送して、
Settings から Firmware Upgrade を選ぶだけでファームウエアの更新が可能。
Firmware 1.9 に更新したところ FileManager が追加されており、
Z Watch 単独で内部のファイルを閲覧できるようになりました。
FileManager で apk を開くと一度ブロックされますが、
ここから提供元不明アプリのインストールを許可することが可能です。
(設定からは出来なかった)
また偶然 Settings → About の Model number を連打していたら
Usb debug を Enable に切り替えられることがわかりました。
再び連打すると Disable になります。
Driver は inf 書き換えで google のものを利用できます。
USB 接続で adb が使えるようになったので、任意アプリの
install / uninstall 方法が確保できたことになります。
画面が狭いだけで普通の Android Device と変わらないようです。
内部ストレージ (/sdcard) は 2GB、System ストレージ (/data) が
およそ 1GB (900MB free) となっています。
install したアプリアイコンもメニューに追加されており実行できます。
Eclipse から直接デバッグも可能。
下記画像は ADT (DDMS) からキャプチャ。

↑ Chot Calculator も画面が小さくキーが潰れてるが一応動作 (NDK使用)
母艦と同期するサブ画面的な用途ではなく、
単独でさまざまなアプリを入れて持ち歩ける超小型デバイスとしても
活用できるのではないかと思っています。
関連エントリ
・Android 4.0 MIPS で RenderScript, ainol Novo 7 Paladin の浮動小数点演算速度
・Android 4.0 ainol Novo 7 Paladin、MIPS CPU の NDK と Vivante GPU
・Android LiveView MN800 プラグインの作り方
・LiveView MN800 Android のマイクロディスプレイ
Bluetooth 経由の RemoteDisplay だった LiveView と違い、
単体で Android 4.1 が動作しています。

スペックによると中身は Ingenic JZ4775。
CPU は Xburst 1.0GHz で ainol Novo 7 Paladin と同じ mips です。
RAM も同じく 512MB。下記は ZWatch 実機より cpuinfo。
system type : s2122b processor : 0 cpu model : Ingenic Xburst V4.15 FPU V0.0 BogoMIPS : 812.64 wait instruction : yes microsecond timers : no tlb_entries : 32 extra interrupt vector : yes hardware watchpoint : yes, count: 1, address/irw mask: [0x0fff] microMIPS : no ASEs implemented : mxu shadow register sets : 1 kscratch registers : 0 core : 0 VCED exceptions : not available VCEI exceptions : not available Hardware : s2122b
基本的には他の SmartWatch と同じように、母艦となる Android Smartphone
と Bluetooth 同期する使い方が想定されているようです。
そのため内蔵のアプリケーションは最小限で設定項目もごくわずか。
アプリケーション管理も無いので、単独で Z Watch 側のアプリの
追加や削除を行う方法が見当たりませんでした。
USB 接続で MTP ストレージとして認識するのでアクセスは容易です。
内部ストレージに update.zip を転送して、
Settings から Firmware Upgrade を選ぶだけでファームウエアの更新が可能。
Firmware 1.9 に更新したところ FileManager が追加されており、
Z Watch 単独で内部のファイルを閲覧できるようになりました。
FileManager で apk を開くと一度ブロックされますが、
ここから提供元不明アプリのインストールを許可することが可能です。
(設定からは出来なかった)
また偶然 Settings → About の Model number を連打していたら
Usb debug を Enable に切り替えられることがわかりました。
再び連打すると Disable になります。
Driver は inf 書き換えで google のものを利用できます。
USB 接続で adb が使えるようになったので、任意アプリの
install / uninstall 方法が確保できたことになります。
画面が狭いだけで普通の Android Device と変わらないようです。
内部ストレージ (/sdcard) は 2GB、System ストレージ (/data) が
およそ 1GB (900MB free) となっています。
install したアプリアイコンもメニューに追加されており実行できます。
Eclipse から直接デバッグも可能。
下記画像は ADT (DDMS) からキャプチャ。


↑ Chot Calculator も画面が小さくキーが潰れてるが一応動作 (NDK使用)
母艦と同期するサブ画面的な用途ではなく、
単独でさまざまなアプリを入れて持ち歩ける超小型デバイスとしても
活用できるのではないかと思っています。
関連エントリ
・Android 4.0 MIPS で RenderScript, ainol Novo 7 Paladin の浮動小数点演算速度
・Android 4.0 ainol Novo 7 Paladin、MIPS CPU の NDK と Vivante GPU
・Android LiveView MN800 プラグインの作り方
・LiveView MN800 Android のマイクロディスプレイ
2013/11/03
Android NDK r9b と ARMv7A の hard-float 補足
要するに新しい Android NDK r9b に入れ替えると
実行が速くなってプログラムサイズも小さくなるということです。
Android.mk に下記の行を追加してコンパイルするだけ。
より詳しくはこちら
関連エントリ
・Android NDK r9b と ARMv7A の hard-float
実行が速くなってプログラムサイズも小さくなるということです。
Android.mk に下記の行を追加してコンパイルするだけ。
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) LOCAL_CFLAGS += -mhard-float LOCAL_LDFLAGS += -Wl,--no-warn-mismatch endif
より詳しくはこちら
関連エントリ
・Android NDK r9b と ARMv7A の hard-float
2013/11/01
Android NDK r9b と ARMv7A の hard-float
Android 4.4 (KitKat) とともに NDK r9b がリリースされています。
RenderScript 対応などいくつか新しい機能がありますが、
その中に ARMv7A の hard-float 対応が含まれています。
ちょうど NDK を使った関数電卓アプリを作っているところだったので試してみました。
・Android NDK
・ちょっと電卓
Android/iOS など ARM デバイスではこれまで float ABI として softfp が用いられていました。
関数呼び出しなどの引数は、浮動小数点数であっても必ず整数レジスタ r を経由しており、
FPU の有無にかかわらず共通化出来るようになっています。
その代わり VFP が搭載されているデバイスでの実行効率とコード効率がわずかに犠牲になっています。
これまでの iOS/Android スマートフォンで VFP が搭載されていないのは
MSM7225 など一部の ARM11 (ARMv6, Android では ARMv5TE) に限られていました。
ARMv7A では存在しておらず softfp を用いる必要はありませんでした。
Android NDK r9b で hard-float に対応したので VFP/NEON レジスタを直接用いた
関数呼び出しが可能となっています。
●コンパイル方法
NDK で hard-float を指定する手順は下記の通り。
Android.mk に追加します。
ただし対応しているコンパイラは gcc のみで clang ではまだ使用できません。
このオプションを指定できるのは ARMv7A ( TARGET_ARCH_ABI = armeabi-v7a ) の場合だけです。
●外部ライブラリの宣言
システムや外部ライブラリは softfp でコンパイルされているので、
コンパイラに ABI の違いを正しく認識させる必要があります。
NDK r9b 付属のヘッダでは、各関数に下記の宣言が追加されています。
これは softfp 関数の呼び出しであることを意味しています。
例えば NDK 付属の math.h ヘッダを見ると下記のように宣言されています。
__NDK_FPABI_MATH__ や __NDK_FPABI__ は sys/cdefs.h で定義されています。
●コンパイル結果と libm の hard_float
実際に hard-float でコンパイルした結果は下記の通り。
ローカル関数呼び出しは直接 d0 レジスタが用いられていることがわかります。
↓これまでの softfp でコンパイルすると下記の通り。
64bit 倍精度浮動小数点数は r0/r1 と 2つの 32bit 整数レジスタを使って
受け渡しが行われています。
hard-float でコンパイルした場合も、外部のライブラリ呼び出しでは
下記のように r0/r1 レジスタへのへのコピーが発生します。
ただし libm は hard-float でコンパイルした static ライブラリが付属しているので、
直接 VFP/NEON レジスタによる呼び出しも出来ます。
-lm (libm) の代わりに -lm_hard (libm_hard) を指定します。
この場合ヘッダの attribute 宣言を外す必要があるので -D_NDK_MATH_NO_SOFTFP=1 も
必要です。
↓ libm 呼び出しでもレジスタ転送が無くなりました。
アプリケーションコードは小さくなりますが libm_hard は static なので
プログラムコード全体は増えます。
● libm 以外のライブラリ呼び出し
浮動小数点数を用いるライブラリは libm 以外にもあります。
例えば OpenGL ES 2.0 関数にも attribute 宣言が追加されています。
実際に glClearColor() を呼び出してみると、hard-float でも r0-r3 へのコピーが
行われていることがわかります。
libm 以外では特に hard-float 版が用意されているわけではないので
softfp 同様の転送が行われます。
実際のアプリケーションでどの程度の差が出るかわかりませんが、
NDK でさらに最適化出来る余地ができました。
もっとも、iOS の方はすでに ARMv8 に移行しつつあります。
Android も 64bit 化が行われればこのような違いを意識する必要は無くなるでしょう。
関連エントリ
・Nexus 7 の Ubuntu で ARM の abi softfp と hard-float を比べる
RenderScript 対応などいくつか新しい機能がありますが、
その中に ARMv7A の hard-float 対応が含まれています。
ちょうど NDK を使った関数電卓アプリを作っているところだったので試してみました。
・Android NDK
・ちょっと電卓
Android/iOS など ARM デバイスではこれまで float ABI として softfp が用いられていました。
関数呼び出しなどの引数は、浮動小数点数であっても必ず整数レジスタ r を経由しており、
FPU の有無にかかわらず共通化出来るようになっています。
その代わり VFP が搭載されているデバイスでの実行効率とコード効率がわずかに犠牲になっています。
これまでの iOS/Android スマートフォンで VFP が搭載されていないのは
MSM7225 など一部の ARM11 (ARMv6, Android では ARMv5TE) に限られていました。
ARMv7A では存在しておらず softfp を用いる必要はありませんでした。
Android NDK r9b で hard-float に対応したので VFP/NEON レジスタを直接用いた
関数呼び出しが可能となっています。
●コンパイル方法
NDK で hard-float を指定する手順は下記の通り。
Android.mk に追加します。
LOCAL_CFLAGS += -mhard-float LOCAL_LDFLAGS += -Wl,--no-warn-mismatch
ただし対応しているコンパイラは gcc のみで clang ではまだ使用できません。
このオプションを指定できるのは ARMv7A ( TARGET_ARCH_ABI = armeabi-v7a ) の場合だけです。
●外部ライブラリの宣言
システムや外部ライブラリは softfp でコンパイルされているので、
コンパイラに ABI の違いを正しく認識させる必要があります。
NDK r9b 付属のヘッダでは、各関数に下記の宣言が追加されています。
これは softfp 関数の呼び出しであることを意味しています。
__attribute__((pcs("aapcs")))
例えば NDK 付属の math.h ヘッダを見ると下記のように宣言されています。
// math.h より抜粋 double acos(double) __NDK_FPABI_MATH__; double asin(double) __NDK_FPABI_MATH__;
__NDK_FPABI_MATH__ や __NDK_FPABI__ は sys/cdefs.h で定義されています。
// sys/cdefs.h より一部抜粋 #define __NDK_FPABI__ __attribute__((pcs("aapcs"))) #define __NDK_FPABI_MATH__ __NDK_FPABI__
●コンパイル結果と libm の hard_float
実際に hard-float でコンパイルした結果は下記の通り。
ローカル関数呼び出しは直接 d0 レジスタが用いられていることがわかります。
// hard-float // t_value f_bittof( t_value val ) vcvt.u32.f64 s0, d0 vcvt.f64.f32 d0, s0 bx lr
↓これまでの softfp でコンパイルすると下記の通り。
64bit 倍精度浮動小数点数は r0/r1 と 2つの 32bit 整数レジスタを使って
受け渡しが行われています。
// softfp // t_value f_bittof( t_value val ) vmov d6, r0, r1 vcvt.u32.f64 s15, d6 vcvt.f64.f32 d6, s15 vmov r0, r1, d6 bx lr
hard-float でコンパイルした場合も、外部のライブラリ呼び出しでは
下記のように r0/r1 レジスタへのへのコピーが発生します。
// hard-float (-lm) vmov r0, r1, d0 bl 0 <floor> vmov d0, r0, r1
ただし libm は hard-float でコンパイルした static ライブラリが付属しているので、
直接 VFP/NEON レジスタによる呼び出しも出来ます。
LOCAL_CFLAGS += -mhard-float -D_NDK_MATH_NO_SOFTFP=1 LOCAL_LDFLAGS += -Wl,--no-warn-mismatch -lm_hard
-lm (libm) の代わりに -lm_hard (libm_hard) を指定します。
この場合ヘッダの attribute 宣言を外す必要があるので -D_NDK_MATH_NO_SOFTFP=1 も
必要です。
↓ libm 呼び出しでもレジスタ転送が無くなりました。
// hard-float (-lm_hard) b 0 <floor>
アプリケーションコードは小さくなりますが libm_hard は static なので
プログラムコード全体は増えます。
● libm 以外のライブラリ呼び出し
浮動小数点数を用いるライブラリは libm 以外にもあります。
例えば OpenGL ES 2.0 関数にも attribute 宣言が追加されています。
// GLES2/gl2.h より GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); // GLES2/gl2platform.h #define GL_APICALL KHRONOS_APICALL // KHR/khrplatform.h より抜粋 # define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__
実際に glClearColor() を呼び出してみると、hard-float でも r0-r3 へのコピーが
行われていることがわかります。
// hard-float (debug build) vstr s0, [fp, #-8] vstr s1, [fp, #-12] vstr s2, [fp, #-16] vstr s3, [fp, #-20] ; 0xffffffec ldr r0, [fp, #-8] ldr r1, [fp, #-12] ldr r2, [fp, #-16] ldr r3, [fp, #-20] bl 0 <glClearColor>
libm 以外では特に hard-float 版が用意されているわけではないので
softfp 同様の転送が行われます。
実際のアプリケーションでどの程度の差が出るかわかりませんが、
NDK でさらに最適化出来る余地ができました。
もっとも、iOS の方はすでに ARMv8 に移行しつつあります。
Android も 64bit 化が行われればこのような違いを意識する必要は無くなるでしょう。
関連エントリ
・Nexus 7 の Ubuntu で ARM の abi softfp と hard-float を比べる