1

マルチスレッド Android アプリをマルチコア デバイス (S3 など) とシングル コア Android デバイスで実行したときのコードのパフォーマンスの向上を測定しようとしています。パフォーマンスを測定するために、タスクを順次実行するか、並行して実行します。通常の Java スレッドを実装しましたが、違いはないようです。このようにAsynchTaskを試してみましたが、パフォーマンスは少ししか改善されませんでした。

単一のコアではなく、各タスク/スレッドが異なるコアで実行されるようにするコードを作成する方法を教えてください。それが不可能な場合、アプリで複数のコアを最大限に活用するにはどうすればよいですか?

タスクを実行するアクティビティの onCreate メソッドのコードを次に示します。

protected void onCreate(Bundle savedInstanceState)  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_local_executor);

    multiplicationTask t1 = new multiplicationTask();
    t1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);       

    multiplicationTask t2 = new multiplicationTask();
    t2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

    multiplicationTask t3 = new multiplicationTask();
    t3.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

    multiplicationTask t4 = new multiplicationTask();
    t4.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

}

onCreate メソッドから実行される AsynchTask は次のとおりです。

class multiplicationTask extends AsyncTask<Integer, Integer, String> {

    protected void onPreExecute()
    {
        Log.v("PrintLN", "Executing Task");
    }

    @Override
    protected String doInBackground(Integer... params) {
     //Do lots of floating point operations that are independent of anything whatsoever
    }


    protected void onPostExecute(String result) {
        Log.v("PrintLN", "Done Task: " + resulting_time);
    }

}
4

2 に答える 2

3

Android にはそのための制限があります。特定のコアでスレッドを手動で実行することはできません。最良の方法は、ThreadPoolExecutor を使用してスレッドの数を制御することです。これにより、ThreadPoolExecutor は、コアの使用状況に応じて、コアで実行するスレッドを自動的に分離します。

于 2013-02-17T06:42:38.807 に答える
2

単一のコアではなく、各タスク/スレッドが異なるコアで実行されるようにするコードを作成する方法を教えてください。

これは、JVM / android によって自動的に処理されます。パフォーマンスの向上が見られない場合、最も可能性の高い理由は次のとおりです。

  • タスクは並列化できません (たとえば、2 つの結果を計算しますが、2 番目の結果は最初の結果に依存するため、順番に実行されます)。
  • タスクは CPU バウンドではありません (つまり、巨大なファイルを読み取る場合、ボトルネックは CPU ではなくストレージの速度であり、スレッドを追加しても役に立ちません)。
  • 十分なスレッドを開始していない / 開始したスレッドが多すぎる

より具体的な答えが必要な場合は、スレッドを作成して開始するコードを示し、タスクが何をするかを考えることをお勧めします。

編集

AsyncTask の主な用途は、UI と対話する短いバックグラウンド タスクを実行することです。あなたの場合、単純なエグゼキューターの方がおそらく良いでしょう。作成するための基本的な構文は次のとおりです。

private static final int N_CPUS = Runtime.getRuntime().availableProcessors() + 1;
private final ExecutorService executor = Executors.newFixedThreadPool(N_CPUS);

そしてそれを使用するには:

executor.submit(new Runnable() {
    public void run() {
        Log.v("PrintLN", "Executing Task");
        //your code here
        Log.v("PrintLN", "Done Task: " + resulting_time);
    }
});

完了したら、executor をシャットダウンすることを忘れないでください。

現在、パフォーマンスの向上は多くの要因によって異なります。あなたの場合、タスクの寿命が短すぎると、コンテキスト切り替えのオーバーヘッド (CPU が 1 つのスレッドまたは別のスレッドをアクティブにするとき) が十分に大きくなり、複数のスレッドの利点が相殺される可能性があります。

別の考えられるボトルネックは同期です。スレッド間で継続的にデータを交換すると、これも多くのオーバーヘッドを引き起こします。

于 2013-02-17T06:43:17.230 に答える