2015-09-16 2 views
1

Я использую java-версию libsvm для многих проблем с интеллектуальным анализом данных. Однако я заметил, что даже когда у нас многоядерный компьютер, libsvm использует только одно ядро, он не распараллеливает проблему. Когда я искал в FAQ, было решение C++ [http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f432]. Существующий класс Java выглядит следующим образом.Parallelize 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 - изменение цикла for get_Q в классе SVC_Q, как показано ниже.

@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 = ПУСК; 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

Быть потокобезопасным не имеет ничего общего с ускорением, это то, является ли метод/переменная * безопасным * использоваться из более чем одного потока одновременно. –