Неожиданный вывод в параллельном блоке OpenMP

Следующая программа, если я правильно понимаю, должна создать не более 10 потоков и запустить параллельный блок omp:

#include <iostream>
#include <omp.h>
using namespace std;

int main()
{
    omp_set_num_threads(10);
#pragma omp parallel
    {
        int id = omp_get_thread_num();

        printf("%d %d %d\n", id, omp_get_num_threads(), omp_get_max_threads());
    }
    return 0;
}

Вывод показывает, что он был запущен 12 раз. Но omp_get_num_threads() = 1 во всех тредах и почему-то omp_get_max_threads = 12 кроме первой темы.

выход :

0 1 10
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12
0 1 12

Я скомпилировал точно такой же код со строкой cmd: g++ -fopenmp .\openMp.c -o prog в терминале кода VS, результат был ожидаемым и правильным:

1 10 10
2 10 10
3 10 10
4 10 10
0 10 10
5 10 10
6 10 10
7 10 10
8 10 10
9 10 10
  • Я добавил libomp.lib в: Свойства конфигурации > Компоновщик > Ввод > Дополнительные зависимости.
  • -fopenmp -Xclang в C/C++ добавлены флаги > Дополнительные параметры
  • C/C++ > Все параметры > Поддержка Open MP > Да
  • Не уверен, существует ли libomp.dll, не могу найти его в каталоге установки MSVC.

Примечание. Я использую 6-ядерный процессор с 12 логическими процессорами.

Невозможно воспроизвести на VS2022 (17.2.5) на 10-ядерном процессоре: каждая строка имеет свой идентификатор потока, и все строки имеют одинаковое количество потоков (10)/максимальное количество потоков (10). Кстати, каким должен быть флаг -Xclang? Я получаю ignoring unknown option '-Xclang', когда добавляю это. То же самое касается -fopenmp.

wohlstad 09.06.2024 13:28

Я думаю, что -Xclang и -fopenmp не для MSVC. Параметр «Открыть поддержку MP > Да» должен быть тем, что вам нужно (который устанавливает /openmp).

wohlstad 09.06.2024 13:35

Непонятно, что такое ваш компилятор и среда: вы говорите о «коде VS», а затем о «MSVC». Эти двое совершенно разные. AFAIK, первый не может использовать компилятор MSVC. Фактически, вы говорите, что используете GCC. Однако вы также используете -Xclang. Каждый компилятор использует свою собственную реализацию OpenMP. Выберите один конкретный компилятор и не меняйте и не смешивайте параметры, относящиеся к другим компиляторам. Смешение сред выполнения OpenMP обычно приводит к проблемам, подобным той, что есть у вас (или к очень плохим проблемам с производительностью, а также к сбоям).

Jérôme Richard 09.06.2024 13:42

Кстати, использовать omp_set_num_threads вручную таким образом — вообще плохая идея, даже в целях тестирования. Вместо этого используйте OMP_NUM_THREADS, это более гибко. В некоторых редких случаях добавление предложения num_threads в параллельный раздел может подойти, если приложению требуется фиксированное количество потоков, которое никогда не должно устанавливаться пользователем (редко).

Jérôme Richard 09.06.2024 13:48

@JérômeRichard ОП добавил тег Visual Studio (а не код VS), а также описание настроек проекта, похоже, соответствует Visual Studio. Однако я согласен, что ФП должен уточнить, чтобы убедиться.

wohlstad 09.06.2024 13:56

Меня ввел в заблуждение этот ответ, мне не следовало добавлять .lib и флаги. Спасибо всем.

maths soso 09.06.2024 14:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

единственное, что вам нужно сделать в MSVC, чтобы включить openmp, это включить его с помощью

  • C/C++ > Язык > Поддержка Open MP > Да

этот шаг эквивалентен добавлению аргумента командной строки /openmp

проблема, которую вы видите, вызвана ручной привязкой libomp.lib, вам следует удалить ее. вам также не следует передавать -fopenmp -Xclang, так как это аргументы clang, а не аргументы MSVC.

Если вы работаете с несколькими компиляторами и платформами, я рекомендую вам использовать систему сборки для автоматической настройки вашей цепочки инструментов. В CMake эти флаги встроены Как установить флаги компоновщика для OpenMP в функции try_compile CMake и в большинстве IDE включая VSCode и Visual Studio, они хорошо поддерживают CMake, и вам не нужно изучать особенности каждого компилятора.

В ОП указано, что он использует «код VS» и командную строку g++ -fopenmp .\openMp.c -o prog. Поскольку AFAIK MSVC не поддерживает GCC, а код VS — это совершенно другое программное обеспечение, чем MSVC, я не думаю, что ответ MSVC подходит для OP. Я думаю, что необходимо разъяснение ФП.

Jérôme Richard 09.06.2024 13:45

@JérômeRichard, его вопрос разделен на две части: одна в MSVC, которая не работает, другая в gcc, которая работает, ему просто интересно, почему поведение MSVC отличается от поведения gcc, синтаксис вопроса действительно сбивает с толку, но этот ответ поможет ему.

Ahmed AEK 09.06.2024 13:46

Это действительно имело бы смысл (посмотрим, так ли это). Обратите внимание, что среда выполнения MSVC OpenMP устарела, и лично я бы не рекомендовал использовать ее, кроме как в целях тестирования (особенно на больших-маленьких процессорах, таких как самые последние процессоры Intel). Поскольку экспериментальная версия использует среду выполнения Clang, она также может случайно решить проблему OP (хотя прямое связывание библиотеки OMP действительно плохо).

Jérôme Richard 09.06.2024 14:01

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