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 флаги вместо.

Другие вопросы по тегам