Como fazer o tempo correto do código Android RenderScript no Nvidia Shield
Eu implementei uma pequena CNN no RenderScript e quero criar um perfil do desempenho em diferentes hardwares. No meu Nexus 7, os tempos fazem sentido, mas no NVIDIA Shield, não.
O CNN (LeNet) é implementado em 9 camadas residentes em uma fila, o cálculo é realizado em sequência. Cada camada é cronometrada individualmente.
Aqui está um exemplo:
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
A distribuição dos horários é quase correta para o nexo, com conv1 e conv2 (camadas de convolução) demorando a maior parte do tempo. Mas no escudo, os tempos vão muito além do que é razoável para as camadas 2 a 4 e parecem se reunir no final. A camada softmax é um trabalho relativamente pequeno, então 40ms é muito grande. Meu método de temporização deve estar com defeito ou algo mais está acontecendo.
O código executando as camadas se parece com isso:
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++;
}
Entendo que, uma vez que forEach_ () retorne, o trabalho deve estar concluído. Em qualquer caso, mRS.finish () deve fornecer uma barreira final. Mas, observando os horários, a única explicação razoável é que os trabalhos ainda são processados em segundo plano.
O aplicativo é muito simples, basta executar o teste da MainActivity e imprimir no logcat. O Android Studio cria o aplicativo como uma versão e o executa no dispositivo conectado por USB.
(1) Qual é a maneira correta de cronometrar os processos RenderScript? (2) É verdade que, quando forEach_ () retorna, os threads gerados pelo script são garantidos? (3) No meu aplicativo de teste, eu simplesmente corro diretamente do MainActivity. Isso é um problema (além de bloquear o thread da interface do usuário e deixar o aplicativo sem resposta)? Se isso influencia o tempo ou causa a estranheza, qual é a maneira correta de configurar um aplicativo de teste como esse?