2015-09-16 71 views
1

我一直在使用java版本的libsvm來處理許多數據挖掘問題。 但是我注意到,即使我們有多核計算機,libsvm只使用一個核心,它也不會並行解決問題。當我在FAQ中搜索時,有一個C++解決方案[http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f432]。現有的Java類看起來像這樣。在多核計算機上並行化LIBSVM - Java

@Override 
float[] get_Q(int i, int len) 
{ 
    float[][] data = new float[1][]; 
    int start, j; 
    if ((start = cache.get_data(i, data, len)) < len) 
    { 
     for (j = start; j < len; j++) 
     { 
      data[0][j] = (float) (y[i] * y[j] * kernel_function(i, j)); 
     } 

    } 
    return data[0]; 
} 

我在java中也使用了相同的概念 - 改變類SVC_Q中get_Q的for循環,如下所示。

@Override 
float[] get_Q(int i, int len) 
{ 

    float[][] data = new float[1][]; 
    int start, j; 
    if ((start = cache.get_data(i, data, len)) < len) 
    { 
     ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime() 
       .availableProcessors()); // number of threads 

     for (j = start; j < len; j++) 
     { 
      final int count = j; 
      executorService.submit(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        data[0][count] = (float) (y[i] * y[count] * kernel_function(i, count)); 
       } 
      }); 

     } 
     executorService.shutdown(); 

    } 
    return data[0]; 
} 

儘管現在改變之後,它使用我機器中的所有核心,結果都在下降。新測試集的正確分類實例的百分比從78%降至58%。訓練時間也沒有減少。所以顯然我做得不對。 有沒有一種合適的方式來並行化libsvm?我在代碼中犯的錯誤是什麼?

回答

-1

如果您不知道如何編寫多線程/並行代碼,請避免嘗試並行化任何代碼。

在這種特殊情況下,you need to wait for the executor to finish all of its jobs.在返回結果之前。

但是,這並不意味着kernel_function方法是線程安全的。

+0

謝謝,這解決了準確性問題,即使執行時間保持不變,所以我猜kernel_function不是線程安全的。但我不知道爲什麼常見問題不得不在C液++這樣, 的#pragma OMP並行私人(j)的時間表(引導) \t \t \t爲(J =啓動;Ĵ Tharindu

+0

什麼OMP pgrama你寫的和你寫的不是100%相同的。你的代碼在這裏有很大的開銷,爲每個元素啓動一個工作。這就是爲什麼我建議你不要試圖對代碼進行並行化,如果你對編寫多線程代碼一無所知。我建議你閱讀本文(http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=pd_sim_14_1?ie=UTF8&refRID=08GYEMBGRC75QHPEZQ4D&dpID=51YGGeOM%2B-L&dpSrc=sims&preST=_AC_UL160_SR104 %2C160_),然後再嘗試自行進行這些更改。 –

+0

線程安全與加速無關,它是一個方法/變量是否安全*可以同時用於多個線程。 –