OpenMP и Visual Studio

OpenMP поз­во­ля­ет лег­ко со­зда­вать па­ра­л­лель­ные про­грам­мы для си­стем с об­щей па­мя­тью (мно­го­ядер­ных и мно­го­про­цес­сор­ных). В этой ста­тье я рас­ска­жу о том, как вклю­чить OpenMP в са­мой рас­про­стра­нён­ной сре­де про­грам­ми­ро­ва­ния — Visual Studio. Со­глас­но офи­ци­аль­ной вер­сии Mic­ro­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 2010 Express. Од­на­ко, я её по­ка не ис­пы­ты­вал.

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

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

Со вре­ме­ни на­пи­са­ния этой ста­тьи вы­шел но­вый SDK: Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1. К со­жа­ле­нию, я его не ис­пы­ты­вал. Все су­ще­ствую­щие SDK пе­ре­чис­ле­ны на этой стра­ни­це.

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

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

Не­об­хо­ди­мые нам ком­по­нен­ты SDK

Ри­су­нок 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:

#include <iostream>
#include <omp.h>

using namespace std;

int main(int argc, char **argv)
{
    int test( 999 );

    omp_set_num_threads( 2 );
    #pragma omp parallel reduction(+:test)
    {
        #pragma omp critical
        cout << "test = " << test << endl;
    }

    return EXIT_SUCCESS;
}

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

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

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

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

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

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

Вклю­ча­ем OpenMP в свой­ствах про­ек­та

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

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

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

Ри­су­нок 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 вклю­чим его в на­шу про­грам­му сле­дую­щим об­ра­зом, что­бы он не до­га­дал­ся о вклю­чён­ном ре­жи­ме от­лад­ки:

#include <iostream>

#ifdef _DEBUG
#undef _DEBUG
#include <omp.h>
#define _DEBUG
#else
#include <omp.h>
#endif

using namespace std;

int main(int argc, char **argv)
{
    int test( 999 );

    omp_set_num_threads( 2 );
    #pragma omp parallel reduction(+:test)
    {
        #pragma omp critical
        cout << "test = " << test << endl;
    }

    return EXIT_SUCCESS;
}

Ли­стинг 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» мы ви­дим, что про­грам­ма дей­стви­тель­но ра­бо­та­ет, ис­поль­зуя два по­то­ка:

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

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

P.S.

Ес­ли вы не зна­е­те, как со­зда­вать па­ра­л­лель­ные про­грам­мы при по­мо­щи OpenMP, со­ве­тую про­честь спе­цифи­ка­цию, там всё по­дроб­но опи­са­но: http://www.openmp.org/mp-documents/spec30.pdf.

43 отзыва на запись «OpenMP и Visual Studio»

Спа­си­бо, очень по­лез­ная ста­тья.
Огром­ное Вам спа­си­бо! Все «по по­лоч­кам» и очень до­ход­чи­во для но­вич­ка!
От­лад­ка и оп­ти­ми­за­ция мно­го­по­точ­ных OpenMP-про­грамм
http://www.viva64.com/art-3-1-1557922790.html 32 под­вод­ных кам­ня OpenMP при про­грам­ми­ро­ва­нии на Си++
http://www.viva64.com/art-3-1-464379766.html
Боль­шое спа­си­бо за ста­тью! Очень по­мог­ла.
Спа­си­бо бо­ооооль­шое. Ста­тья дей­стви­тель­но очень по­мог­ла.
Спа­си­бо! Ста­тья для ме­ня очень ак­ту­аль­ная
При­кол в том что в в SDK не­ту omp.h имен­но в в этой, фиг зна­ет где
Пар­дон я ис­поль­зую SDK for Windows 7 and Net 3.5sp1, там не­ту его
Так omp.h дол­жен быть в са­мой Visual Studio ещё до уста­нов­ки SDK.
СПАСИБО!!!!
Спа­си­бо боль­шое. По­лез­ная ста­тья для тех, кто толь­ко на­чи­на­ет про­грам­мить!
Спа­си­бо огром­ное за ста­тью
Мне нуж­но па­ра­лель­ное про­гра­ми­ро­ва­ние на Matlab или Fortran. Не мог­ли бы опи­сать как это сде­лать.
За ра­нее огром­ное спа­си­бо
К со­жа­ле­нию, я ма­ло зна­ком с Matlab, и от­ри­ца­тель­но от­но­шусь к Фор­тра­ну.
Боль­шое спа­си­бо, без Вас бы не разо­брал­ся…
А Вы не мог­ли бы под­ска­зать где мож­но ска­чать OpenMP для Windows?
OpenMP — это не ка­кая-то про­грам­ма, ко­то­рую мож­но «ска­чать». Это — ин­тер­фейс (на­бор функ­ций и ди­рек­тив ком­пи­ля­то­ра), ко­то­рый поз­во­ля­ет опи­сать па­ра­л­ле­лизм ва­шей про­грам­мы. OpenMP — эта та «фиш­ка», ко­то­рая под­дер­жи­ва­ет­ся или не под­дер­жи­ва­ет­ся ва­шим ком­пи­ля­то­ром.
Про­чи­тал ста­тью до кон­ца, всё по­нял. Спа­си­бо.
Сей­час по­про­бо­вал со­вер­шить ука­зан­ные дей­ствия по на­строй­ке Visual Studio Express, пи­шет «Про­грам­ма не мо­жет быть вы­пол­не­на»
Спа­си­бо за ста­тью. Про­ве­рил ра­бо­ту опи­сан­ной схе­мы с но­вым SDK (Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1), в Release про­блем нет. Мо­гу под­твер­дить, что до уста­нов­ки SDK хе­де­ра omp.h в include не бы­ло, од­на­ко по­сле уста­нов­ки он по­явил­ся.
very good
Пре­крас­ная ста­тья. Спа­си­бо ав­то­ру.
Боль­шое спа­си­бо за ста­тью! очень по­мог­ла!
Огро­мен­ное спа­си­бо!
Спа­си­бо Боль­шое. Очень хо­ро­шо всё опи­са­но, мне по­мог­ло. Ещё раз спа­си­бо!!!!
А мож­но ли OpenMP «при­кру­тить» к Code::Blocks?
Спа­си­бо, Ан­тон — по­нят­ная и по­лез­ная ста­тья. Очень по­мог­ла мне.
ре­спект те­бе, брат. та­ких как ты ма­ло. во­круг нас пиздешь еба­ный. толь­ко вме­сте все и де­ла­ем. мо­ло­дец.
Об­ра­зец по­ша­го­вой ин­ст­рук­ции, спа­си­бо!
Statia pomogla. Ochen horoshii sait.spasibo!
Огро­мен­ное спа­си­бо! Очень хо­ро­шо всё опи­са­но, мне по­мог­ло.
Мне нуж­но па­ра­лель­ное про­гра­ми­ро­ва­ние на QT. кто зна­ет?
Ан­тон, здрав­ствуй­те. Дей­стви­тель­но по­лез­ная ста­тья, спа­си­бо. Но вы­пол­няя все эти ин­ст­рук­ции на Visual Studio 2005 Standart Edition по­сле ком­пи­ля­ции, ко­гда я за­пус­каю про­грам­му, она мне вы­да­ет ошиб­ку This application has failed to start because the application configuration is incorrect… Хо­тя про­де­ло­вая все это на Visual studio 2010 — все ра­бо­та­ет. Но мне нуж­на ра­бо­таю­щая вер­сия имен­но на 2005. Мо­же­те ли вы мне под­ска­зать в чем про­бле­ма?
«В раз­де­ле Configuration Properties → Linker → Input ука­жи­те, что vcompd.lib при­лин­ко­вы­вать не нуж­но, а vcompd.lib — нуж­но:» Что-то здесь не так — нуж­но ис­пра­вить на­зва­ния биб­лио­тек.
Очень по­лез­ная ста­тья, спа­си­бо!
Не ра­бо­та­ет нифи­га
Хо­ро­шая ста­тья, не пло­хо бы­ло бы при­ве­сти ре­аль­ный при­мер, на­при­мер, умно­же­ние мат­риц па­ра­л­лель­ным про­грам­ми­ро­ва­ни­ем
Дру­жи­щ­ще спа­си­бо!! крат­ко суть — де­лаю про­грам­му на опе­нмп уже тре­тий день, к за­че­ту, де­лаю все пра­виль­но, но не ра­бо­та­ет, кни­га и про­чие ма­те­ри­а­лы предо­став­лен­ные пре­по­дом — под ли­нукс и gcc, дол­гое вре­мя ко­вы­рял а про­чи­тав твою ста­тью на­шел пункт что в ви­жуа­ле на­до от­дель­но вклю­чать опе­нмп а не толь­ко биб­лио­те­ку под­клю­чить))) вклю­чил тут же за­ра­бо­та­ло… и про­сто до­воль­но ин­те­рес­но и по­нят­но все на­пи­са­но… еще раз спа­си­бо, в за­клад­ки чтоб не те­рять до­ба­вил
как для CodeBlocks на­стро­ить?
Спа­си­бо боль­шое!
Для CodeBlocks Project->Build options
Вклад­ка Compiler settings -> вклад­ка Other Options
-fopenmp на вклад­ке Linker settings
до­бав­ля­ем gomp в спи­сок биб­лио­тек Кро­ме все­го, у ме­ня уста­нов­лен под Вин­дой MinGW.
Съе­лись не­ко­то­рые пе­ре­во­ды строк, но, ду­маю, по­нят­но.
До­брый день.
Ска­жи­те что та­кое: Error 3 error C3010: ‘return’ : jump out of OpenMP structured block not allowed d:pcversionstitcher.cpp 468
Сам по­нял. Спа­си­бо.
Там был return внут­ри. Те­перь ду­маю как это из­ме­нить.
There are some attentiongrabbing points in time in this article but I dont know if I see all of them heart to heart. There may be some validity however I will take maintain opinion until I look into it further. Good article , thanks and we would like extra! Added to FeedBurner as properly

Оставить отзыв

Жёлтые поля обязательны к заполнению

   

Можете использовать теги <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang=""> <div class=""> <span class=""> <br>