Я использую 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? Какая ошибка я делаю в своем коде?
Спасибо, это решило проблему точности, хотя время, затраченное на выполнение, остается неизменным, поэтому я думаю, что kernel_function не является потокобезопасным. Но мне интересно, почему ФАК решение в C++, как это, #pragma OMP параллельно для частного (J) график (управляемый) \t \t \t для (J = ПУСК; J
Tharindu
Какого 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_), прежде чем предпринимать эти изменения самостоятельно. –
Быть потокобезопасным не имеет ничего общего с ускорением, это то, является ли метод/переменная * безопасным * использоваться из более чем одного потока одновременно. –