Читать интересную книгу Описание языка PascalABC.NET - W Cat

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 33 34 35 36 37 38 39 40 41 ... 101

Изменяет расширение файла с именем name на newext

function FileExists(name: string): boolean;

Возвращает True, если файл с именем name существует

function DiskFree(diskname: string): int64;

Возвращает свободное место в байтах на диске с именем diskname

function DiskSize(diskname: string): int64;

Возвращает размер в байтах на диске с именем diskname

function DiskFree(disk: integer): int64;

Возвращает свободное место в байтах на диске disk. disk=0 - текущий диск, disk=1 - диск A: , disk=2 - диск B: и т.д.

function DiskSize(disk: integer): int64;

Возвращает размер в байтах на диске disk. disk=0 - текущий диск, disk=1 - диск A: , disk=2 - диск B: и т.д.

OpenMP

OpenMP: обзор

OpenMP – открытый стандарт для распараллеливания программ на многопроцессорных системах с общей памятью (например, на многоядерных процессорах). OpenMP реализует параллельные вычисления с помощью многопоточности: главный поток создает набор подчиненных потоков, и задача распределяется между ними.

OpenMP представляет собой набор директив компилятора, которые управляют процессом автоматического выделения потоков и данными, требуемыми для работы этих потоков.

В системе PascalABC.NET реализованы следующие элементы OpenMP:

* Конструкции для создания и распределения работы между потоками (директивы parallel for и parallel sections)

* Конструкции для синхронизации потоков (директива critical)

Директивы имеют следующий вид:

{$omp directive-name [опция[[,] опция]...]}

Здесь $omp означает то, что это директива OpenMP, directive-name – имя директивы, например parallel, после чего могут быть опции. Директива относится к тому оператору, перед которым она находится.

Примеры использования OpenMP находятся в папке Samples/OMPSamples

Ниже приводится описание директив.

Директива parallel for

Редукция в директиве parallel for

Параллельные секции и директива parallel sections

Синхронизация и директива critical

Директива parallel for

Директива parallel for обеспечивает распараллеливание следующего за ней цикла.

{$omp parallel for}

for var i: integer:=1 to 10 do

тело цикла

Здесь будет создано несколько потоков и разные итерации цикла будут распределены по этим потокам. Количество потоков, как правило, совпадает с количеством ядер процессора, но в некоторых случаях могут быть отличия, например, если поток ожидает ввод данных от пользователя, могут создаваться дополнительные потоки, чтобы по возможности задействовать все доступные ядра.

Все переменные, описанные вне параллельного цикла, будут разделяемыми, то есть, если в теле цикла есть обращение к таким переменным, все потоки будут обращаться к одной и той же ячейке памяти. Все переменные, объявленные внутри цикла, будут частными, то есть у каждого потока будет своя копия этой переменной.

Опция private позволяет переменные, описанные вне цикла, сделать частными. Опция записывается так:

{$omp parallel for private(список переменных)}

Список переменных – одна или несколько переменных через запятую.

var a,b: integer;

{$omp parallel for private(a, b)}

for var i: integer:=1 to 10 do

a := ...

В этом случае переменные a и b будут частными, и присваивание этим переменным в одном потоке не будет влиять на другие потоки.

Ограничение: счетчики распараллеливаемого цикла и вложенных циклов должны быть объявлены в заголовке цикла.

Не все циклы можно распараллеливать. Если на разных итерациях происходит обращение к одной и той же переменной и при этом ее значение меняется – распараллеливание такого цикла приведет к ошибкам, при разных запусках могут получаться разные результаты в зависимости от того, в каком порядке происходили обращения к этой переменной.

{$omp parallel for}

for var i:=1 to 2 do

a[i] := a[i+1];

Здесь на первой итерации происходит чтение второго элемента массива, а на второй итерации – запись этого же элемента. Если первая итерация выполнится раньше второй – в первый элемент массива запишется значение из второго, а если позже – то из третьего элемента массива.

var a:integer;

{$omp parallel for}

for var i:=1 to 10 do

begin

a := i;

... := a; //к этому моменту a может быть изменено другим потоком

end;

Значение переменной a после этого цикла может быть любым в диапазоне от 1 до 10.

Наиболее эффективно распараллеливаются циклы, каждая итерация которых выполняется достаточно долго. Если тело цикла состоит из небольшого количества простых операторов, затраты на создание потоков и распределение нагрузки между ними могут превысить выигрыш от параллельного выполнения цикла.

Пример параллельного перемножения матриц

Перемножение матриц - классический пример иллюстрации параллельности. Вычисление различных элементов матрицы происходит независимо, поэтому не надо предусматривать никаких средств синхронизации.

uses Arrays;

procedure ParallelMult(a,b,c: array [,] of real; n: integer);

begin

{$omp parallel for }

for var i:=0 to n-1 do

for var j:=0 to n-1 do

begin

c[i,j]:=0;

for var l:=0 to n-1 do

c[i,j]:=c[i,j]+a[i,l]*b[l,j];

end;

end;

procedure Mult(a,b,c: array [,] of real; n: integer);

begin

{$omp parallel for }

for var i:=0 to n-1 do

for var j:=0 to n-1 do

begin

c[i,j]:=0;

for var l:=0 to n-1 do

c[i,j]:=c[i,j]+a[i,l]*b[l,j];

end;

end;

const n = 400;

begin

var a := Arrays.CreateRandomRealMatrix(n,n);

var b := Arrays.CreateRandomRealMatrix(n,n);

var c := new real[n,n];

ParallelMult(a,b,c,n);

writeln('Параллельное перемножение матриц: ',Milliseconds,' миллисекунд');

var d := Milliseconds;

Mult(a,b,c,n);

writeln('Непараллельное перемножение матриц: ',Milliseconds-d,' миллисекунд');

end.

Редукция в директиве parallel for

Часто в цикле накапливается значение некоторой переменной, перед циклом эта переменная инициализируется, а на каждой итерации к ней добавляется некоторое значение или умножается на некоторое значение. Эта переменная должна быть объявлена вне цикла, а значит, будет общей. В таком случае возможны ошибки при параллельном выполнении:

var a: integer:=0;

{$omp parallel for}

for var i:integer:=1 to 100 do

a := a+1;

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

Опция reduction позволяет обеспечить правильное накопление результата:

{$omp parallel for reduction(действие : список переменных)}

При этом все переменные из списка будут объявлены частными, таким образом, разные потоки будут работать со своими экземплярами переменных. Эти экземпляры будут инициализированы в зависимости от действия, а в конце цикла новое значение переменной будет получено из значения этой переменной до цикла и всех частных копий применением действия из опции.

var a: integer := 1;

{$omp parallel for reduction(+:a)}

for var i: integer:=1 to 2 do

a := a+1;

Здесь начальное значение переменной a – единица, для действия + локальные копии будут инициализированы нулями, будет выполнено две итерации и у каждого потока локальная копия переменной a примет значение 1. После завершения цикла к начальному значению (1) будут прибавлены обе локальные копии, и результирующее значение переменной a будет равно 3, так же как и при последовательном выполнении.

В таблице приведены допустимые операторы редукции и значения, которыми инициализируются локальные копии переменной редукции:

Оператор раздела reduction

Инициализированное значение

+

0

*

1

-

0

and (побитовый)

~0 (каждый бит установлен)

or (побитовый)

0

xor (побитовый)

0

and (логический)

true

or (логический)

false

Параллельные секции и директива parallel sections

Директива parallel sections обеспечивает параллельное выполнение нескольких операторов, простых или составных.

{$omp parallel sections}

1 ... 33 34 35 36 37 38 39 40 41 ... 101
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Описание языка PascalABC.NET - W Cat.
Книги, аналогичгные Описание языка PascalABC.NET - W Cat

Оставить комментарий