C++11 многопоточность очень низкая производительность в нейронной сети
Я новичок в алгоритмах многопоточности ЦП и пытаюсь реализовать стандартный трехслойный алгоритм параллельной прямой передачи нейронной сети. Проблема в том, что параллельная версия примерно в 10 раз медленнее... Я думаю, что причина в слишком большом количестве потоков. Я использую Intel i7 920 с 4 ядрами, гиперпоточность отключена. ОС Fedora 20, компилятор GCC 4.8.2
Есть идеи, как улучшить производительность?
template<class T, class TM>
void NeuralNetwork<T, TM>::feedForwardParallel()
{
thread t0(&NeuralNetwork<T, TM>::parallel_sum0, this, block_size0, 0);
thread t1(&NeuralNetwork<T, TM>::parallel_sum0, this, block_size0, block_size0);
thread t2(&NeuralNetwork<T, TM>::parallel_sum0, this, block_size0, 2*block_size0);
thread t3(&NeuralNetwork<T, TM>::parallel_sum0, this, block_size0, 3*block_size0);
t0.join();
t1.join();
t2.join();
t3.join();
thread t4(&NeuralNetwork<T, TM>::parallel_sum1, this, block_size1, 0);
thread t5(&NeuralNetwork<T, TM>::parallel_sum1, this, block_size1, block_size1);
thread t6(&NeuralNetwork<T, TM>::parallel_sum1, this, block_size1, 2*block_size1);
thread t7(&NeuralNetwork<T, TM>::parallel_sum1, this, block_size1, 3*block_size1);
t4.join();
t5.join();
t6.join();
t7.join();
thread t8 (&NeuralNetwork<T, TM>::parallel_sum2, this, 1, 0);
thread t9 (&NeuralNetwork<T, TM>::parallel_sum2, this, 1, 1);
t8.join();
t9.join();
}
template <class T, class TM>
void NeuralNetwork<T, TM>::parallel_sum0(int size, int start)
{
T sum = 0;
for (int i = start; i < start+size; i++)
{
for (int j = 0; j < INPUT_NEURONS; j++)
sum += inputN[j] * weightsIH[j][i];
sum += weightsIH[INPUT_NEURONS][i];
hidden1N[i] = sigmoid(sum);
}
}
template <class T, class TM>
void NeuralNetwork<T, TM>::parallel_sum1(int size, int start)
{
T sum = 0.0;
for (int i = start; i < start+size; i++)
{
for (int j = 0; j < HIDDEN_NEURONS1; j++)
sum += hidden1N[j] * weightsHH[j][i];
sum += weightsHH[HIDDEN_NEURONS1][i];
hidden2N[i] = sigmoid(sum);
}
}
template <class T, class TM>
void NeuralNetwork<T, TM>::parallel_sum2(int size, int start)
{
T sum = 0.0;
for (int i = start; i < start+size; i++)
{
for (int j = 0; j < HIDDEN_NEURONS2; j++)
sum += hidden2N[j] * weightsHO[j][i];
sum += weightsHO[HIDDEN_NEURONS2][i];
outputN[i] = sigmoid(sum);
}
}
template<class T, class TM>
T NeuralNetwork<T, TM>::sigmoid(T val) {
return tanh(val);
}
1 ответ
Создание новых потоков очень дорого, а стоимость создания нового потока просто больше, чем вычисление всего, что вам нужно, в одном потоке. Вместо этого вы должны использовать пулы потоков (например, OpenMP сделает это за вас автоматически). Или вы можете использовать std::async
с std::launch::async | std::launch::deferred
флаги вместо.