2013-02-17 46 views
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方法

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://stackoverflow.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

回答

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激活一個線程或另一個線程時)可能足夠大,以致可以抵消多個線程的好處。

另一個可能的瓶頸是同步:如果您不斷通過線程交換數據,這也會導致很多開銷。

+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

3

Android有該限制運行AsynchTask。你不能手動讓你的線程運行在某個核心上。最好的方法是使用ThreadPoolExecutor來控制線程的數量。通過這樣的ThreadPoolExecutor會自動單獨的線程在內核根據

+0

謝謝@PrinceVegeta - 我也添加了代碼到我的問題 - 這是什麼你談論時提到ThreadPoolExecutor? – afahim 2013-02-17 07:04:04

相關問題