Валентин Юльевич Арьков - Организация параллельных потоков. Часть 2 стр 6.

Шрифт
Фон

4.1. Вычислительная среда

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

 число процессоров в компьютере;

 число потоков в группе;

 номер текущего потока в группе.

4.1.1. Число процессоров

Начнём с числа процессоров.

Напомним, что слово «процессор» в нашем случае  это указание на «виртуальный процессор». Другими словами, это любой вычислительный элемент, который может выполнять один поток. Физическая реализация сейчас не важна.

Число «процессоров» можно узнать с помощью библиотечной функции

int omp_get_num_procs (void).

Функция возвращает количество доступных процессоров. Доступных именно нашей программе, а точнее ПРОЦЕССУ. В предыдущей работе мы уже немного познакомились с привязкой процесса к конкретным ядрам.

Создадим новую программу и познакомимся с описанной функцией (рис. 4.1).


Рис. 4.1. Число доступных процессоров


Запускаем программу и видим сообщение (рис. 4.2).

Убеждаемся, что заявленное число процессоров соответствует действительности.


Рис. 4.2. Число процессоров


Задание. Создайте и запустите программу (рис. 4.1). Проверьте, как изменится сообщение программы, если установить число процессоров через параметр окружения NUMBER_OF_PROCESSORS и запустить программу в командной строке.

4.1.2. Число потоков

Рассмотрим, как узнать число потоков в текущей параллельной области программы.

Для организации параллельной работы нужно знать, на сколько частей делить задачу. И вообще, надо следить за событиями. Даже если всё как бы само собой делается, за результаты отвечает почему-то не компьютер, а программист.

Итак, вот библиотечная функция, которая сообщает нам количество параллельных потоков в группе:

int omp_get_num_threads (void).

Расшифровывается название так:

Number of Threads  «число потоков».

Аргументов у функции нет, но скобки при вызове придётся использовать.


Вторая полезная библиотечная функция сообщает номер текущего потока в группе:

int omp_get_thread_num (void).

Название расшифровывается так:

Thread Number  «номер потока».

Номера потоков начинаются с нуля. Это будет главный поток.

Соответственно, максимальный номер потока равен числу потоков минус один.


Названия этих двух функций очень похожи, здесь просто другой порядок слов.

Судите сами:

num_threads / thread_num.

Придётся немного освежить английский. Здесь действует так называемое «правило ряда» (цепочка определений). Если идут несколько существительных подряд, то главное слово будет в конце.

Вторая трудность с пониманием названий  слово NUMBER. Оно может означать «количество» или «порядковый номер». Это одно и то же слово, но два разных значения. И переводятся разные значения разными словами. Вообще-то у этого слова ещё штук двадцать других значений, но дальше углубляться мы уже не будем.

КОНЕЦ ОЗНАКОМИТЕЛЬНОГО ОТРЫВКА

Вторая трудность с пониманием названий  слово NUMBER. Оно может означать «количество» или «порядковый номер». Это одно и то же слово, но два разных значения. И переводятся разные значения разными словами. Вообще-то у этого слова ещё штук двадцать других значений, но дальше углубляться мы уже не будем.

Составим программу и посмотрим, как работают эти две функции (рис. 4.3).

Для организации вывода в виде таблицы используем символ табуляции:

\t.

Табуляция смещает начало вывода на 8 позиций.

Таким образом, первое число выводится начиная с 1-й позиции, второе число  с 9-й и т. д.

Табуляция нам ещё пригодится для анализа эффективности и точности.


Рис. 4.3. Номер потока и количество потоков


Запускаем программу и видим сообщения в произвольном порядке (рис. 4.4). Кто первый успел  тот и напечатал. Если запускать программу несколько раз, получим разные результаты.


Рис. 4.4. Список номеров потоков


Задание. Составьте программу (рис. 4.3). Запустите программу несколько раз и обратите внимание на порядок вывода номеров потоков.

4.2. Параллельный цикл

В этом разделе мы организуем параллельное исполнение цикла FOR и исследуем поведение программы. Результаты могут оказаться не совсем очевидными. Это особенности параллельного программирования. Вот с этими особенностями нам и предстоит познакомиться.

4.2.1. Ситуация гонки

При выполнении параллельной программы может возникать так называемая «ситуация гонки». Это соревнование параллельных потоков за доступ к данным. Английское название:

Data Race.

Мы её уже рассматривали в предыдущей работе. Параллельные потоки обращаются к общей переменной и «затирают» чужие результаты, записывая свои. В результате появляется ошибка в расчётах. Причём ошибка будет случайной, непредсказуемой, и при каждом запуске ошибка будет разной.

Начнём с решения задачи распараллеливания цикла «в лоб».

Рассмотрим программу вычисления суммы большого количества единиц в цикле (рис. 4.5).

Перед оператором цикла вставляем следующую строчку:

#pragma omp parallel for (строка 6).

Эта директива организует параллельное выполнение разных итераций цикла несколькими потоками.

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке

Скачать книгу

Если нет возможности читать онлайн, скачайте книгу файлом для электронной книжки и читайте офлайн.

fb2.zip txt txt.zip rtf.zip a4.pdf a6.pdf mobi.prc epub ios.epub fb3