1

当我在多核设备(如 S3)与单核 android 设备上运行我的多线程 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 自动处理。如果您没有看到任何性能提升,最可能的原因是:

  • 任务不可并行(例如,您计算两个结果,但第二个取决于第一个,因此它们按顺序运行)
  • 这些任务不受 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);
    }
});

完成后不要忘记关闭执行程序。

现在,性能改进将因许多因素而异。在您的情况下,如果任务的生命周期太短,则上下文切换开销(当 CPU 激活一个或另一个线程时)可能足够大,以至于可以抵消多线程的好处。

另一个可能的瓶颈是同步:如果你在线程之间不断地交换数据,这也会导致很多开销。

于 2013-02-17T06:43:17.230 回答