Не работает openmp visual studio 2019

OpenMP и Visual Studio

OpenMP позволяет легко создавать параллельные программы для систем с общей памятью (много­ядерных и многопроцессорных). В этой статье я расскажу о том, как включить OpenMP в самой рас­пространённой среде программирования – Visual Studio. Согласно официальной версии Micro­soft, OpenMP поддерживается только в версиях Professional среды разработки Visual Studio 2005/2008/2010. Однако бесплатная Visual Studio Express обладает тем же компилятором, что и версия Professional. Поэтому после небольшой «доработки напильником» параллельные OpenMP-программы будут компилироваться и, главное, работать даже в Visual Studio Express.

OpenMP от Microsoft реализован посредством следующих компонентов:

  1. компилятор C++, входящий в состав Visual Studio;
  2. заголовочный файл omp.h;
  3. библиотеки стадии компиляции: vcomp.lib и vcompd.lib (последняя используется для отлад­ки);
  4. библиотеки времени выполнения: vcomp90.dll и vcomp90d.dll. Цифры в названии могут разли­чаться: в Visual Studio 2005 вместо 90 стоят цифры 80.

В бесплатной Visual Studio Express перечисленные библиотеки отсутствуют.

OpenMP и Visual Studio Express

Если вы хотите создавать параллельные OpenMP-программы под Windows, то самый удобный спо­соб – это воспользоваться Visual Studio 2005/2008/2010 Professional. Напоминаю, что она бес­платна для студентов и аспирантов. Кроме того, вы можете купить Visual Studio Professional за $600 (конечно, существует ещё и третий вариант, но мы о нём не будем говорить).

Если на вашем компьютере установлена версия Professional – переходите к следующему разделу статьи. В этом разделе рассмотрим случай, когда по каким-либо причинам вы вынуждены использо­вать Visual Studio Express.

Visual Studio Express – это бесплатная урезанная версия Visual Studio. Нас будет интересовать вер­сия 2008 года. Скачать её можно отсюда: http://www.microsoft.com/exPress/download/. Естествен­но, программировать будем на C++, поэтому выби­райте Visual C++ 2008.

Программа установки будет загружать данные из Интернета (примерно 100 мегабайт), поэтому вы можете сэкономить немного трафика, отключив установку Microsoft Silverlight и Microsoft SQL Server, если они вам не требуются.

После установки Visual Studio Express нам понадо­бится добавить в неё OpenMP-компоненты. Легаль­ный бесплатный способ сделать это – установить Windows SDK for Windows Server 2008 and .NET Framework 3.5. Во время установки этого пакета программ будет произведено обновление Visual Studio. Процесс обновления не смотрит, какая именно версия Visual Studio у вас установлена (Express или Professional), поэтому во время установ­ки будут «случайно» добавлены недостающие компоненты.

Так как мы ставим Windows SDK только ради OpenMP, то нам не нужен тот гигабайт документации, который идёт в комплекте. Рекомендую оставить только следующие элементы:

Рисунок 1. Необходимые нам компоненты SDK

К сожалению, в состав SDK не входит библиотека vcomp90d.dll, поэтому на данный момент в Visual Studio Express вы сможете запускать только OpenMP-программы, откомпилированные в ре­жиме Release. Я нашёл способ обойти и это ограничение, об этом читайте далее (раздел «Отладка OpenMP-программы в Visual Studio Express»).

Использование OpenMP в Visual Studio

После того, как вы выполнили шаги, описанные в предыдущем разделе, уже не важно, какой верси­ей Visual Studio вы пользуетесь. Покажу шаг за шагом, как создать проект с поддержкой OpenMP в этой среде разработки. Прежде всего, нужно запустить Visual Studio, и выбрать File→New→Project. Появится окно создания проекта. Выберите тип проекта «Win32», шаблон – «Win32 Console Application». Введите осмысленное имя проекта, выберите папку для хранения проекта, уберите галочку «Create directory for solution»:

Рисунок 2. Окно создания проекта

Нажмите кнопку «OK», появится окно настройки будущего проекта. Выберите вкладку «Application Settings», и включите галку «Empty project»:

Читайте также:  Как настроить активити лаунчер

Рисунок 3. Окно настройки будущего проекта

По нажатию кнопки «Finish» проект будет создан. Никаких видимых изменений в главном окне Visual Studio не произойдёт. Только имя проекта в заголовке окна как бы говорит нам о том, что мы ра­ботаем с проектом.

Теперь нажмите Project→Add New Item, появится окно добавления элементов в проект. Добавьте .cpp-файл в проект:

Рисунок 4. Окно добавления элементов в проект

После этого вам будет предоставлено окно для ввода исходного кода программы. Будем выполнять тесты на следующем коде, проверяющем различные аспекты функционирования OpenMP:

Листинг 1. Простейшая программа, использующая OpenMP

Запустите программу, нажав Debug→Start Without Debugging. Если всё было сделано правильно, программа откомпилируется (если спросит вас, компилировать ли, нажмите «Yes»), затем запу­стится и выведет test = 999:

Рисунок 5. Результат работы программы из листинга 1

«Как же так?! – скажете вы – Ведь программа должна была вывести ноль, причём дважды!». Дело в том, что OpenMP ещё не включен, и поэтому соответствующие директивы были проигнорированы компилятором.

Для включения OpenMP нажмите Project→OMP Properties (OMP – имя проекта из моих примеров). Слева вверху появившегося окна выберите «All Configurations» и в разделе Configuration Properties→C/C++→Language включите «OpenMP Support»:

Рисунок 6. Включаем OpenMP в свойствах проекта

После этого снова запустите программу, нажав Debug→Start Without Debugging. На этот раз про­грамма выведет test = 0 дважды:

Рисунок 7. Результат работы программы из листинга 1 с включённым OpenMP

Ура! OpenMP работает.

Примечание. Если вы используете Visual Studio Express, то выберите текущую конфигурацию «Release», иначе работать не будет (читайте далее):

Рисунок 8. Выбор текущей конфигурации

Отладка OpenMP-программы в Visual Studio Express

Как было сказано ранее, даже после установки Windows SDK у нас не будет в наличии необходимой для отладки библиотеки vcomp90d.dll, поэтому мы пока не можем отлаживать OpenMP програм­му в Visual Studio Express. Простое копирование имеющейся библиотеки vcomp90.dll и переимено­вание её в vcomp90d.dll не сработает, ибо не совпадёт контрольная сумма и версия, указанные во встраиваемом в exe-файл манифесте. Поэтому будем «копать» с противоположной стороны.

При компиляции в конфигурации «Debug» («Отладка»), заголовочный файл omp.h требует библио­теку vcompd.lib (она у нас имеется), которая, в свою очередь, требует vcomp90d.dll (отсутству­ет). Лицензия не позволяет нам использовать в приложениях модифицированные заголовочные файлы от Microsoft, поэтому вместо модификации omp.h включим его в нашу программу следую­щим образом, чтобы он не догадался о включённом режиме отладки:

Листинг 2. Включаем omp.h «хитрым» способом

Приведённого действия не достаточно для того, чтобы всё работало (пока мы исправили лишь ма­нифест, встраиваемый в программу). Дело в том, что Visual Studio в режиме отладки по прежнему автоматически (из-за включённого OpenMP) прилинковывает vcompd.lib, требующую vcomp90d.dll. Чтобы это исправить, снова зайдите в настройки проекта (Project→OMP Properties), выберите на этот раз Configuration: «Debug». В разделе Configuration Properties→Linker→Input укажите, что vcompd.lib прилинковывать не нужно, а vcompd.lib – нужно:

Рисунок 9. Заменяем библиотеку в свойствах проекта

Проверим теперь, работает ли отладка, и действительно ли программа работает параллельно. По­ставьте точку останова на строке с выводом значения переменной. Для этого нажмите левой кноп­кой мыши не серую полоску слева от исходного кода:

Рисунок 10. Точка останова

После этого запустите программу в режиме отладки: Debug→Start Debugging (не забудьте вер­нуть текущую конфигурацию «Debug», см. рисунок 8). Программа запустится – и сразу же остано­вится на точке останова. Во вкладке «Threads» мы видим, что программа действительно работает, используя два потока:

Рисунок 11. Отладка OpenMP-программы в Visual Studio Express

Источник

/openmp (Включить поддержку OpenMP)

Заставляет компилятор обрабатывать #pragma omp директивы для поддержки OpenMP.

Синтаксис

/openmp
/openmp:experimental
/openmp:llvm

Remarks

#pragma omp используется для указания директив и предложений. Если параметр /openmp не указан при компиляции, компилятор игнорирует предложения и директивы OpenMP. Вызовы функций OpenMP обрабатываются компилятором, даже если /openmp не указаны.

Читайте также:  Как понять что глонасс не работает

Компилятор C++ в настоящее время поддерживает стандарт OpenMP 2,0. однако Visual Studio 2019 теперь также предлагает функции SIMD. Чтобы использовать SIMD, Скомпилируйте с помощью /openmp:experimental параметра. Этот параметр включает как обычные функции OpenMP, так и функции OpenMP SIMD, недоступные при использовании /openmp параметра.

начиная с Visual Studio 2019 версии 16,9 можно использовать экспериментальный /openmp:llvm вариант вместо /openmp для целевой среды выполнения OpenMP LLVM. В настоящее время поддержка в рабочем коде недоступна, так как требуемые библиотеки DLL либомп не являются распространяемыми. Параметр поддерживает те же директивы OpenMP 2,0, что и /openmp . И поддерживают все директивы SIMD, поддерживаемые /openmp:experimental параметром. Он также поддерживает параллельные индексы целых чисел без знака в соответствии со стандартом OpenMP 3,0. Дополнительные сведения см. в разделе Улучшенная поддержка OpenMP для C++ в Visual Studio.

В настоящее время /openmp:llvm параметр работает только в архитектуре x64. Параметр несовместим с /clr или /ZW .

Приложения, скомпилированные с помощью /openmp и, /clr могут выполняться только в одном процессе домена приложения. Несколько доменов приложений не поддерживаются. Это значит, что при запуске конструктора модуля ( .cctor ) он обнаруживает, компилируется ли процесс с помощью /openmp , и если приложение загружается в среду выполнения, не используемую по умолчанию. Дополнительные сведения см. в статьях appdomain , /clr (компиляция среды CLR)и Инициализация смешанных сборок.

При попытке загрузить приложение, скомпилированное с помощью /openmp и, и /clr в домен приложения, не заданный по умолчанию, TypeInitializationException исключение создается вне отладчика, и OpenMPWithMultipleAppdomainsException в отладчике создается исключение.

Эти исключения также могут возникать в следующих ситуациях.

Значение, если приложение компилируется с использованием /clr , но не /openmp и загружается в домен приложения, не заданный по умолчанию, где процесс включает приложение, скомпилированное с помощью /openmp .

При передаче /clr приложения в служебную программу, например regasm.exe, которая загружает целевые сборки в домен приложения, не используемый по умолчанию.

Управление доступом для кода среды CLR не работает в регионах OpenMP. Если атрибут управления доступом для кода CLR применяется за пределами параллельной области, он не будет действовать в параллельной области.

Корпорация Майкрософт не рекомендует создавать /openmp приложения, допускающие частично доверенные вызывающие объекты. Не используйте AllowPartiallyTrustedCallersAttribute или любые атрибуты управления доступом для кода CLR.

Установка данного параметра компилятора в среде разработки Visual Studio

Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

Разверните страницу Свойства > языка C/C++ > язык .

Измените свойство поддержки OpenMP .

Установка данного параметра компилятора программным способом

Пример

В следующем примере показаны некоторые эффекты запуска пула потоков по сравнению с использованием пула потоков после его запуска. При условии, что 64-разрядная, одноядерная, Двухъядерный процессор, пул потоков занимает около 16 мс для запуска. После этого пул потоков будет немного излишним.

При компиляции с помощью /openmp второй вызов test2 никогда не выполняется дольше, чем при компиляции с помощью /openmp- , так как отсутствует запуск пула потоков. В миллионах итераций /openmp версия выполняется быстрее, чем /openmp- версия второго вызова test2. При 25 итерациях обе /openmp- /openmp версии регистрируются меньше, чем степень гранулярности часов.

Если в приложении имеется только один цикл и оно выполняется менее чем на 15 мс (оно корректируется на приблизительную нагрузку на компьютер), /openmp может быть неприемлемо. Если это более высокое значение, можно использовать /openmp .

Источник

/openmp (Enable OpenMP Support)

Causes the compiler to process #pragma omp directives in support of OpenMP.

Syntax

/openmp
/openmp:experimental
/openmp:llvm

Remarks

#pragma omp is used to specify Directives and Clauses. If /openmp isn’t specified in a compilation, the compiler ignores OpenMP clauses and directives. OpenMP Function calls are processed by the compiler even if /openmp isn’t specified.

Читайте также:  Беспроводные bluetooth наушники wireless cat ear headphones bt028c настроить

The C++ compiler currently supports the OpenMP 2.0 standard. However, Visual Studio 2019 also now offers SIMD functionality. To use SIMD, compile by using the /openmp:experimental option. This option enables both the usual OpenMP features, and OpenMP SIMD features not available when using the /openmp switch.

Starting in Visual Studio 2019 version 16.9, you can use the experimental /openmp:llvm option instead of /openmp to target the LLVM OpenMP runtime. Support currently isn’t available for production code, since the required libomp DLLs aren’t redistributable. The option supports the same OpenMP 2.0 directives as /openmp . And, it supports all the SIMD directives supported by the /openmp:experimental option. It also supports unsigned integer indices in parallel for loops according to the OpenMP 3.0 standard. For more information, see Improved OpenMP Support for C++ in Visual Studio.

Currently, the /openmp:llvm option only works on the x64 architecture. The option isn’t compatible with /clr or /ZW .

Applications compiled by using both /openmp and /clr can only be run in a single application domain process. Multiple application domains aren’t supported. That is, when the module constructor ( .cctor ) is run, it detects if the process is compiled using /openmp , and if the app is loaded into a non-default runtime. For more information, see appdomain , /clr (Common Language Runtime Compilation), and Initialization of Mixed Assemblies.

If you attempt to load an app compiled using both /openmp and /clr into a non-default application domain, a TypeInitializationException exception is thrown outside the debugger, and a OpenMPWithMultipleAppdomainsException exception is thrown in the debugger.

These exceptions can also be raised in the following situations:

If your application is compiled using /clr but not /openmp , and is loaded into a non-default application domain, where the process includes an app compiled using /openmp .

If you pass your /clr app to a utility, such as regasm.exe, which loads its target assemblies into a non-default application domain.

The common language runtime’s code access security doesn’t work in OpenMP regions. If you apply a CLR code access security attribute outside a parallel region, it won’t be in effect in the parallel region.

Microsoft doesn’t recommend that you write /openmp apps that allow partially trusted callers. Don’t use AllowPartiallyTrustedCallersAttribute, or any CLR code access security attributes.

To set this compiler option in the Visual Studio development environment

Open the project’s Property Pages dialog box. For details, see Set C++ compiler and build properties in Visual Studio.

Expand the Configuration Properties > C/C++ > Language property page.

Modify the OpenMP Support property.

To set this compiler option programmatically

Example

The following sample shows some of the effects of thread pool startup versus using the thread pool after it has started. Assuming an x64, single core, dual processor, the thread pool takes about 16 ms to start up. After that, there’s little extra cost for the thread pool.

When you compile using /openmp , the second call to test2 never runs any longer than if you compile using /openmp- , as there’s no thread pool startup. At a million iterations, the /openmp version is faster than the /openmp- version for the second call to test2. At 25 iterations, both /openmp- and /openmp versions register less than the clock granularity.

If you have only one loop in your application and it runs in less than 15 ms (adjusted for the approximate overhead on your machine), /openmp may not be appropriate. If it’s higher, you may want to consider using /openmp .

Источник

Оцените статью