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

问题描述:

我试图来衡量我的代码性能的改进,当我多核设备上运行多线程我的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方法

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); 
    } 

} 
+0

FWIW,这被称为“线程亲和性”,甚至在标准Java中都不支持 - 至少[不在JCL中](http://*.com/questions/2238272/java-thread-affinity) 。 – 2013-02-17 06:54:33

+0

你的矩阵乘法是如何实现的?我不知道JIT是否执行循环操作。如果不是,则矩阵乘法可以由存储器传输而不是处理器内计算控制。我建议用很少或没有内存访问的东西代替纯计算的东西。 – 2013-02-17 07:12:50

+0

@PatriciaShanahan出于测试目的,我将两个8x8浮点数组相乘 - 您会建议什么? – afahim 2013-02-17 07:17:17

可以让内核的使用上运行我知道我可以编写代码,可以确保我的每一个任务/线程正在运行不同的核心,而不是一个?

,它会自动被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激活一个线程或另一个线程时)可能足够大,以致可以抵消多个线程的好处。

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

+0

感谢@assylias,我已经用代码更新了这个问题,现在可以请你看一下吗?让我知道如果你想要更多的信息 – afahim 2013-02-17 07:02:48

+0

@afahim看到我的编辑。 – assylias 2013-02-17 07:19:57

+0

谢谢 - 我会看看这是否会给我带来性能提升 – afahim 2013-02-17 10:11:30

Android有该限制运行AsynchTask。你不能手动让你的线程运行在某个核心上。最好的方法是使用ThreadPoolExecutor来控制线程的数量。通过这样的ThreadPoolExecutor会自动单独的线程在内核根据

+0

谢谢@PrinceVegeta - 我也添加了代码到我的问题 - 这是什么你谈论时提到ThreadPoolExecutor? – afahim 2013-02-17 07:04:04