Книга: Описание языка PascalABC.NET
Редукция в директиве parallel for
Редукция в директиве parallel for
Часто в цикле накапливается значение некоторой переменной, перед циклом эта переменная инициализируется, а на каждой итерации к ней добавляется некоторое значение или умножается на некоторое значение. Эта переменная должна быть объявлена вне цикла, а значит, будет общей. В таком случае возможны ошибки при параллельном выполнении:
var a: integer:=0;
{$omp parallel for}
forvar 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)}
forvar 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 |
- Forced writes - палка о двух концах
- Forced Writes
- Chapter 15. Graphical User Interfaces for Iptables
- What NAT is used for and basic terms and expressions
- Information request
- SCTP Generic header format
- System tools used for debugging
- FORWARD chain
- How to use this License for your documents
- 1. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- Оператор цикла foreach
- Глава 4 Виртуальные машины Parallels Workstation