如何确保我的线程/进程在不同的核心上运行

时间:2013-02-17 06:34:45

标签: java android multithreading performance android-asynctask

当我在多核设备(如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);
    }

}

2 个答案:

答案 0 :(得分:3)

Android有限制。你不能手动让你的线程在某个核心上运行。最好的方法是使用ThreadPoolExecutor来控制线程数。通过这种方式,ThreadPoolExecutor将根据内核的使用情况自动将线程分离到内核中运行

答案 1 :(得分: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激活一个或另一个线程时)可能足够大,可以抵消多个线程的好处。

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