【问题标题】:How can I make sure my threads / processes are running on different cores如何确保我的线程/进程在不同的内核上运行
【发布时间】:2013-02-01 20:09:50
【问题描述】:

当我在多核设备(如 S3)和单核 android 设备上运行多线程 android 应用程序时,我试图衡量我的代码的性能改进。为了衡量性能,我按顺序运行任务而不是并行运行。我已经实现了普通的 Java 线程,这似乎没有什么不同。因此我尝试了 AsynchTask,但我只得到了一点性能提升。

您能否告诉我如何编写代码来确保我的每个任务/线程都在不同的内核上运行,而不是在单个内核上运行?如果这不可能,我如何才能最大限度地为我的应用使用多个内核?

这是执行任务的 Activity 的 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);
    }

}

【问题讨论】:

  • FWIW,这被称为“线程关联”,甚至在标准 Java 中都不支持 - 至少 not in the JCL。
  • 您的矩阵乘法是如何实现的?我不知道 JIT 是否进行循环操作。如果不是,矩阵乘法可以由内存传输而不是处理器内计算来支配。我建议替换为纯计算的东西,很少或没有内存访问。
  • @PatriciaShanahan 出于测试目的,我将两个 8x8 浮点数组相乘 - 您还有什么建议?
  • 8x8 应该足够小以适合缓存,因此如果您对它们进行足够多的操作以使其可测量,那么它应该受 CPU 限制。

标签: java android multithreading performance android-asynctask


【解决方案1】:

Android 对此有限制。您不能手动使您的线程在某个核心上运行。最好的方法是您可以使用 ThreadPoolExecutor 来控制线程数。这样 ThreadPoolExecutor 会根据内核的使用情况自动分离线程在内核中运行

【讨论】:

  • 感谢@PrinceVegeta - 我还在我的问题中添加了代码 - 这就是你在提到 ThreadPoolExecutor 时所说的吗?
【解决方案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 激活一个或另一个线程时)可能会大到足以抵消多线程的好处。

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

【讨论】:

  • 谢谢@assylias,我已经用代码更新了问题,你现在可以看看吗?如果您想了解更多信息,请告诉我
猜你喜欢
  • 1970-01-01
  • 2010-12-26
  • 1970-01-01
  • 2011-11-24
  • 2018-05-29
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
  • 2013-07-13
相关资源
最近更新 更多