RenderScriptで小さなCNNを実装し、別のハードウェアでパフォーマンスをプロファイルしたいと思っています。私のNexus 7では時が意味をなさないが、NVIDIA Shieldではそうではありません。Nvidia ShieldでAndroid RenderScriptコードの正しいタイミングを行う方法
CNN(LeNet)は、キューに常駐する9つのレイヤーで実装され、計算が順番に実行されます。各レイヤーは個別にタイミングが取られます。ここ
は一例であり:
conv1 pool1 conv2 pool2 resh1 ip1 relu1 ip2 softmax
nexus7 11.177 7.813 13.357 8.367 8.097 2.1 0.326 1.557 2.667
shield 13.219 1.024 1.567 1.081 0.988 14.588 13.323 14.318 40.347
時間の分布はCONV1とCONV2(畳み込み層)がほとんどの時間を取ると、ネクサスのための右の程度です。しかし、盾の上では、時間はレイヤ2〜4のために妥当なものを超えて下がり、最後に向かって集まるように見えます。ソフトマックスレイヤーは比較的小さいジョブなので、40msは大きすぎます。私のタイミング方法は間違っていなければならない、または何か他のことが起こっている。
double[] times = new double[layers.size()];
int layerindex = 0;
for (Layer a : layers) {
double t = SystemClock.elapsedRealtime();
//long t = System.currentTimeMillis(); // makes no difference
blob = a.forward(blob); // here we call renderscript forEach_(), invoke_() etc
//mRS.finish(); // makes no difference
t = SystemClock.elapsedRealtime() - t;
//t = System.currentTimeMillis() - t; // makes no difference
times[layerindex] += t; // later we take average etc
layerindex++;
}
それは一度forEach_()リターンが、ジョブが終了することになっている私の理解です:レイヤーを実行している
のコードは次のようになります。いずれにしても、mRS.finish()は最終的な障壁となります。しかし、時代を見れば、唯一の妥当な説明は、仕事はまだバックグラウンドで処理されているということです。
アプリはとてもシンプルですが、私はMainActivityからテストを実行してlogcatに出力します。 Androidスタジオは、アプリをリリースとして構築し、USBで接続されたデバイス上で実行します。
(1)RenderScriptプロセスを実行する正しい方法は何ですか? (2)forEach_()が返ってくると、スクリプトによって生成されたスレッドが確実に実行されることは保証されていますか? (3)私のテストアプリケーションでは、単にMainActivityから直接実行します。これは問題ですか(UIスレッドをブロックしてアプリを応答しないようにする以外)?これがタイミングに影響を与えたり、奇妙なことが起こった場合、このようなテストアプリケーションを設定する適切な方法は何ですか?
CNNの略? –
畳み込みニューラルネットワーク。 – frankhond