+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 92.51 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

Параллельное программирование для многоядерных систем с помощью OpenMP

21.12.2009 15:47

История

Самым значимым событием 2005 года стало появление многоядерных процессоров. К тому времени классические одноядерные системы исчерпали свой потенциал, поскольку не давали нужной производительности за счет повышения частот, мало того разработчики архитектур столкнулись с проблемой нестабильности и повышенного тепловыделения. Все это волей-неволей способствовало появлению революционных многоядерных процессоров. Идея этих процессоров предельно проста: в одном процессоре интегрировано более одного ядра. Такой подход способствует появлению более производительных процессоров без повышения частот.

OpenMP

Тем не менее, на сегодняшний день не так уж и много приложений (особенно игр), которые полноценно используют многопроцессорные системы. Если Ваше приложение не использует несколько ядер, то соответственно и прироста быстродействия не будет. Именно здесь появляется на сцене OpenMP, технология, с помощью которой можно легко и быстро создавать мультипоточные приложения на C++ и соответственно существенно повысить производительности. Данная технология была разработана в 1997 году и изначально базировалась на языке Fortran. Сегодня она включена в язык C++ и доступна в Visual Studio 2005 (версия 2.0), а также на платформе XBOX 360.
Прежде чем приступать к коду, нужно активизировать реализованные в компиляторе средства OpenMP. Для этого в свойствах проекта C/C++ -> Language -> OpenMP ставим Yes(/openmp). Встретив параметр /openmp компилятор определяет символ _OPENMP, с помощью которого мы сможем определить используется ли данная технология в нашем приложении или нет. Так же, во избежание ошибок, в проект следует подключить хедер omp.h, который содержит нужные нам функции из vcomp.dll (или vcompd.dll в отладочной версии, которая содержит дополнительные сообщения об ошибках), манифесты и т.п.

"Helloworld"

OpenMP достаточно прост в использовании, он состоит из набора прагм и функций из omp.h. Прагмы - это указатели компилятору разбивать код на блоки, которые будут выполняться параллельно. Если openmp выключен, компилятор проигнорирует прагмы, а код останется вполне работоспособным. Все это дает возможность писать универсальный, переносимый код для реализации программ на различных архитектурах и системах. Спецификация OpenMP поддерживается такими поставщиками как Sun, Intel и IBM.
Все директивы начинаются с #pragma omp. Самая важная и распространенная директива - parallel. Она создает параллельный регион для следующего за ней блока. В качестве примера рассмотрим классический "Hello world":
Код:
int main()
{
 #pragma omp parallel
{
 printf("Hello world\n");
}
return 0;
}
При выполнении на двуядерной системе мы получим результат:

Код:
Hello world
Hello world

Рассмотрим более сложный пример, в котором используем конструкцию #pragma omp for, которая сообщает, что при выполнении цикла for в параллельном регионе итерации цикла должны быть распределены между потоками группы:
Код:
#pragma omp parallel
{
#pragma omp for
 for(int i < 0; i < num_Particles; i++) {
        Action(vec[i]);
}
}
Отметим очень важное замечание: если убрать из конструкции #pragma omp for, то каждый поток полностью выполнит цикл, таким образом будет выполнено много ненужной работы. В OpenMP также имеется возможность более краткой записи прагм #pragma omp parallel и #pragma omp for:
 
Код:
#pragma omp parallel for for(int i < 0; i < num_Particles; i++) {Action(vec[i]);
}

Барьеры и nowait

Барьеры являются одним из видов синхронизации. При обнаружении барьера поток останавливается и ждет пока все остальные потоки не окажутся на этом же барьере. Например, при выполнении цикла выше мы столкнулись с неявной барьерной синхронизацией, сами не заметив того. В конце цикла стоит барьер, который приостанавливает выполнение освободившихся потоков до тех пор, пока не освободятся другие потоки, обрабатывающие итерации этого же цикла. В некоторых случаях возникает потребность отключать синхронизацию, для этого существует оператор nowait, приведем пример, где это может быть выгодно:
Код:
#pragma omp parallel
{
#pragma omp for nowait
            for(int i = 0; i < 5000; i++) {
                        // …
            }
#pragma omp for
            for(int j = 0; j < 1000; j++) {
                        // …
            }
#pragma omp barrier
             some_func();
}В этом примере потоки, которые освободились после обработки первого цикла переходят к обработке второго цикла без ожидания остальных потоков. В некоторых случаях это может повысить производительность, поскольку уменьшается время простоя потоков. Возможна и обратная ситуация, когда нам нужно организовать барьер. В примере выше функция some_func() не выполнится до тех пор, пока все потоки не выполнят предыдущие задачи (это нужно, например, при обновлении буфера кадров перед выводом его содержимого на экран).

Ограничение на циклы

В OpenMP существует ряд ограничений на циклы, которые нужно распараллелить:
1.Переменная цикла должна иметь тип integer. Беззнаковые целые числа, такие как DWORD, работать не будут.
2.Цикл должен являться базовым блоком и не может использовать goto и break (за исключением оператора exit, который завершает все приложение).
3.Инкрементная часть цикла for должно являться либо целочисленным сложением, либо целочисленным вычитанием и должно практически совпадать со значением инварианта цикла.
4.Если используется операция сравнения < или <=, переменная цикла должна увеличиваться при каждой итерации, а при использовании операции > или >= переменная цикла должна уменьшаться.

Критические разделы

С помощью критических разделов можно предотвратить одновременный доступ к одному сегменту кода из нескольких потоков. Один поток получает доступ только тогда, когда другие не обрабатывают данный код. Конструкция имеет следующий вид:
Код:
#pragma omp critical
{
     …
}Такие критические разделы называются неименованными. Существуют также именованные, которые способствуют повышению производительности приложения, поскольку блокировка будет производиться только теми потоками, которым это действительно необходимо. Выглядит следующим образом:

Код:
#pragma omp critical(some_value)
{
      …
}

Конструкция Sections

OpenMP применим не только для циклов, но и для функций. Конструкция sections используется когда необходимо выполнять блоки кода в отдельных потоках. Рассмотрим простейший пример (сортировка):
Код:
#pragma omp parallel sections
{
            #pragma omp section
            sort(array, …);
            #pragma omp section
            sort(array, …);
}
В данном примере первая директива #pragma создает параллельный регион секций, а последующие секции определяются директивой #pragma omp section. Каждой секции в параллельном регионе ставится в соответствие один поток из группы потоков, и все секции выполняются одновременно. Заметим, что каждая из функций sort выполняется полностью независимо друг от друга, это очень важно, поскольку приводит к тривиальным ошибкам, которые очень тяжело отловить. Рассмотрим пример ошибочного кода:
Код:
int n, m, q;
#pragma omp parallel sections
{
            #pragma omp section
            n = partition(array, lo, hi);
            #pragma omp section
            m = partition(array, lo, n-1); // n возможно не определен!!
            #pragma omp section
            q = partition(array, n+1, hi);  // n возможно не определен!!
}При компиляции приложения без параметра /openmp будет сгенерирована корректная последовательная версия. Одно из преимуществ OpenMP в том, что эта технология совместима с компиляторами, не поддерживающими OpenMP.
Выводы
OpenMP быстрая, простая и легкая технология с помощью которой можно использовать потенциал многоядерных систем. Всего за несколько минут обычный код можно переделать в оптимизированный, при этом остается совместимость с компиляторами, которые не поддерживают данную технологию. Возможное применение в игровых движках: particle system, collision detection, fractals, поиск путей и т. д. К сожалению, в данной статье мы коротко рассмотрели лишь малую часть возможностей данной технологии, но более подробную спецификацию вы можете найти на сайте http://www.openmp.org.

Ссылки по теме

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям.

Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе.

В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года