использование #pragma omp parallel для замедления работы программы

Моя программа на C++ выполняется около 300 секунд. Внутри моей программы мне нужно разделить мои векторы. Анализатор VS сообщает, что это занимает около 15% времени выполнения. вот код:

template <class T> myVector<T> cWisDivide(myVector<T> &vec1, 

myVector<T> &vec2)
{
    try
    {
        if (vec1._rows == vec2._rows)
        {
            myVector<T> result(vec1._rows);
            //#pragma omp parallel for 
            for (int r = 1; r <= vec1._rows; r++)
            {
                if (vec2(r) != 0)
                {
                    result(r) = vec1(r) / vec2(r);
                }
                else
                {
                    throw std::runtime_error("");
                }
            }
            return result;
        }
    }
    catch (const exception &e)
    {
        ....
    }
}

эта функция вызывается много раз. Если я использую #pragma ... перед циклом, загрузка процессора остается на 100% в течение примерно 350 с. что больше, чем время последовательного запуска программы.

Я был бы признателен, если бы кто-нибудь мог помочь мне в этом вопросе.


person Javad R    schedule 08.02.2015    source источник
comment
Насколько велик vec1._rows?   -  person Oliver Charlesworth    schedule 08.02.2015
comment
r в цикле for должен быть определен перед самим циклом for. Вот так: int r; #pragma.... for(r = 1...)   -  person Michał Walenciak    schedule 08.02.2015
comment
Попробуйте проработать параллельную область дальше наружу. Если вы вызываете функции много раз, вы также платите за инициализацию каждый раз, когда вы ее вызываете.   -  person Chiel    schedule 08.02.2015
comment
@MichałWalenciak Мм, нет, для параллели для помещения переменной цикла вне цикла означает, что ее «последнее» значение должно быть сохранено omp. Это дополнительные накладные расходы, и они замедлят его. (немного).   -  person user3710044    schedule 08.02.2015
comment
@javad, ты на Windows, верно? Taskman на винде говорит 25% на одно ядро ​​на 4-ядерной машине. Действительно глупый вопрос здесь ... вы используете многоядерную машину, не так ли?   -  person user3710044    schedule 08.02.2015
comment
@user3710044: посмотрите здесь: en. wikipedia.org/wiki/ в примере for. Он говорит: Обратите внимание, что счетчики итераций j и k должны быть закрытыми. Если вы хотите пометить что-то как public или private, оно должно уже существовать (поэтому должно быть видно до #pragma)   -  person Michał Walenciak    schedule 08.02.2015
comment
@MichałWalenciak, правда, но тогда переменная цикла, определенная в цикле, по определению является частной.   -  person user3710044    schedule 08.02.2015
comment
Вы компилируете в режиме релиза? Вы включили OpenMP в MSVC?   -  person Z boson    schedule 09.02.2015


Ответы (2)


Это может пойти не так по нескольким причинам:

  1. не зная типа result, вполне возможно, что должны быть встроены барьеры, чтобы избежать состояния гонки при его изменении - вы можете избежать этого, имея параллельные результирующие векторы, которые вы затем объединяете.
  2. затраты на копирование для векторов vec1 и vec2 могут быть больше, чем вознаграждение за производительность.

в общем, это вопрос о параллелизуемых векторных типах - обратитесь к выбранной вами документации openMP, чтобы узнать больше о параллельно доступных типах.

person Marcus Müller    schedule 08.02.2015

Во всяком случае, я только что посмотрел и из спецификации OMP ...

• Бросок, выполненный внутри области цикла, должен вызывать возобновление выполнения в той же итерации области цикла, и тот же поток, который породил исключение, должен его перехватить.

Я знал, что мне не нравится внешний вид исключения.

OpenMP API V4.0 стр. 59.

person user3710044    schedule 08.02.2015