Уважаемые коллеги! Предлагаем вам разработку программного обеспечения под ключ.
Опытные программисты сделают для вас мобильное приложение, нейронную сеть, систему искусственного интеллекта, SaaS-сервис, производственную систему, внедрят или разработают ERP/CRM, запустят стартап.
Сферы - промышленность, ритейл, производственные компании, стартапы, финансы и другие направления.
Языки программирования: Java, PHP, Ruby, C++, .NET, Python, Go, Kotlin, Swift, React Native, Flutter и многие другие.
Всегда на связи. Соблюдаем сроки. Предложим адекватную конкурентную цену.
Заходите к нам на сайт и пишите, с удовольствием вам во всем поможем.
OpenMP создавался как средство для программирования параллельных вычислений, выполняемых в многопроцессорных системах с общим пространством памяти (SMP). Его основную часть составляет набор директив, включаемых в тексты программ, написанных на обычных алгоритмических языках. Первая версия стандарта для языков C/C++ появилась в октябре 1998 г., а вторая, и пока последняя - в марте 2002 г., ее полное описание вы найдете на сайте www.openmp.org. В связи с выпуском микропроцессора Pentium 4 HT, поддерживающего технологию Hyper Threading, корпорация Intel разработала реализацию стандарта OpenMP для компиляторов Intel C++. Она позволяет программировать параллельные вычисления, на двух логических процессорах, входящих в состав Pentium 4 HT и последних моделей Pentium 4 с новым ядром Prescott. Список директив, поддерживаемых реализацией Intel, описан в документе "OpenMP* Standard Option". Судя по этому документу при работе с Intel C++ можно использовать стандартный набор директив OpenMP для C/C++ и почти все параметры. Поэтому при подготовке данной публикации я использовал описание, приведенное в стандарте, поскольку оно является более полным. 1. Директивы В преамбуле к описанию стандарта сказано, что для использования директив и всех возможностей OpenMP для C/C++ в командной строке компилятора должен быть указан специальный ключ. В версии для Intel C++ он называется /Qopenmp. Директивы OpenMP для C/C++ имеют следующий формат: #pragma omp <имя директивы> [список параметров] Как известно, в семействе языков C директива #pragma предназначена для управления специфическими возможностями компилятора. Ключевое слово omp используется для того, чтобы исключить случайные совпадения имен директив OpenMP с другими именами. Директивы parallel, for, section и single имеют параметры, которые указываются в той же строке после имени директивы. Если параметры не указаны, то используются их значения принятые по умолчанию. Объектом действия большинства директив является один оператор или блок, перед которым расположена директива в исходном тексте программы. В описании стандарта OpenMP такие операторы или блоки называются ассоциированными с директивой. Параллельный регион. Фрагмент программы, который делится на параллельно выполняемые нити, называется параллельным регионом. В стандарте OpenMP нить определена как простая программная компонента, имеющая частные (локальные) переменные, доступ к общим (внешним) переменным и предназначенная для выполнения одним процессором. В зависимости от установленного способа планирования это может быть конкретный или первый свободный процессор. Параллельно выполняемые нити формируют директивы for и sections. Первая из них создает нити, содержащие копии ассоциированного оператора цикла, каждая из которых выполняет некоторую часть от общего количества итераций. Вторая формирует нити из отдельных блоков, расположенных в исходной программе последовательно друг за другом. Перед каждым преобразуемым в нить блоком указывается вспомогательная директива section. В сфере действия директив for и sections нельзя использовать все остальные директивы OpenMP, что ограничивает возможности управления вычислительным процессом в параллельном регионе. Для снятия этих ограничений описание региона должно начинаться с директивы parallel. Формально сферой ее действия является блок, но он может содержать вложенные блоки и директивы, как формирующие структуру региона, так и управляющие процессом вычислений. Кроме того, директива parallel имеет параметры, которые позволяют по усмотрению программиста выбирать количество нитей, выполняемых в параллельном регионе. Состав директив и их краткая характеристика приведены в следующей таблице:
2. Параметры директив Параметры директив (directive clauses) можно условно разделить на две категории. Одни из них влияют на ход вычислительного процесса и позволяют учесть особенности распараллеливаемой задачи и многопроцессорной системы, в которой она будет выполняться. Например, с их помощью можно разрешить создание параллельного региона только при выполнении заданного условия, назначить количество нитей в регионе или количество итераций, выполняемых в нитях. Другие параметры, их примерно половина, определяют видимость переменных в параллельном регионе и специальные действия, которые должны выполняться над ними в начале и в конце сферы действия директивы. В таких случаях после имени параметра в круглых скобках указывается список переменных, на которые распространяется действие параметра. Он может содержать только те имена, которые описаны в исходном тексте стандартными средствами C/C++ и используются в ассоциированном с директивой операторе или блоке. Работа с переменными. По умолчанию действует простое правило определения видимости переменных в параллельном регионе. Те из них, которые в исходном тексте программы описаны вне распараллеливаемого оператора или блока, объявляются общими, а описанные внутри оператора или блока - частными. Общие (shared) переменные доступны всем нитям, а частные (private) создаются для каждой нити только на время ее выполнения. Пример общей переменной - имя массива, элементы которого обрабатываются в теле цикла, а переменная, управляющая повторами цикла, является частной, иначе будет невозможно распараллеливание цикла. Принятое по умолчанию деление переменных на общие и частные применимо не во всех случаях и тогда приходится явно указывать способ доступа или особенности использования конкретных переменных. Рассмотрим два случая, которые возможны при распараллеливании оператора цикла. Предположим, что результаты вычислений, выполняемых в теле цикла, накапливаются в переменной sum. По умолчанию она объявляется общей и доступна всем нитям. Конечный результат окажется корректным, но в процессе выполнения задания сразу несколько нитей будут обращаться к переменной sum для чтения или записи ее содержимого. Это неизбежно замедлит процесс выполнения задания. Просто объявить переменную sum частной нельзя, поскольку будут потеряны результаты вычислений накопленные в нитях. Специально для такого случая предназначен параметр reduction. Если в его списке указать переменную sum, то в нитях она будет использоваться как частная, а при выходе из каждой нити накопленный результат будет добавлен к общей переменной sum. Другой пример. Предположим, что в теле цикла для хранения промежуточных результатов вычислений используется переменная temp. Если в исходном тексте ее описание расположено вне оператора цикла, то при распараллеливании по умолчанию она будет объявлена общей переменной. В таком случае при выполнении задания вполне вероятны случаи, когда одна из нитей успеет изменить значение temp, прежде чем другая использует сформированное в ней значение. Это неизбежно приведет к ошибкам в результатах вычислений. Поэтому все переменные, используемые для хранения промежуточных результатов, следует объявлять частными, либо описывать их непосредственно в теле оператора цикла. Параметры и их краткое описание приведены в следующей таблице:
Следующие два
параметра отсутствуют в оригинальном документе,
3. Переменные окружения Стандарт OpenMP и его реализация для Intel C++ предусматривают существование четырех переменных окружения (environment variables). Они содержат статически определенные величины, которые могут использоваться при формировании структуры параллельного региона. Имена переменных набираются заглавными латинскими буквами, а аргументы могут набираться как на верхнем, так и на нижнем регистре. Способ установки значений переменных зависит от конкретной реализации компилятора, например, в описании стандарта сказано, что для Unix оболочки C применяется такой способ: setenv OMP_SCHEDULE "dynamic". Изменение значений переменных при выполнении задания невозможно. Переменные и их назначение перечислены в следующей таблице:
4. Функции библиотеки runtime В описании стандарта OpenMP для С/C++ перечислены 17 функций, входящих в состав библиотеки runtime. Их состав и точное количество в реализации Intel C++ мне не известны, поэтому ниже описаны только 4 функции, которые обязательно должны быть доступны. Они позволяют в процессе выполнения задания определить и изменить количество нитей, используемых в параллельном регионе, определить номер конкретной нити и количество доступных процессоров в системе. Для возможности использования библиотечных функций к приложению должен быть подключен заголовочный файл omp.h. Все четыре функции целочисленные. Имена и назначение функций перечислены в следующей таблице:
|
Уважаемые коллеги! Предлагаем вам разработку программного обеспечения под ключ.
Опытные программисты сделают для вас мобильное приложение, нейронную сеть, систему искусственного интеллекта, SaaS-сервис, производственную систему, внедрят или разработают ERP/CRM, запустят стартап.
Сферы - промышленность, ритейл, производственные компании, стартапы, финансы и другие направления.
Языки программирования: Java, PHP, Ruby, C++, .NET, Python, Go, Kotlin, Swift, React Native, Flutter и многие другие.
Всегда на связи. Соблюдаем сроки. Предложим адекватную конкурентную цену.
Заходите к нам на сайт и пишите, с удовольствием вам во всем поможем.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.