Конечно, параллельные вычисления в основном нужны для науки, вычислений с большими массивами данных, но это дело реально даёт существенное приращение в скорости вычислений, проверено опытом.
OpenMP во FreePascal
Модератор: Модераторы
OpenMP во FreePascal
Между прочим, коварный конкурент FreePascal - PascalABC поддержку OpenMP имеет, а у FreePascal с параллельностью как-то всё печально.
Конечно, параллельные вычисления в основном нужны для науки, вычислений с большими массивами данных, но это дело реально даёт существенное приращение в скорости вычислений, проверено опытом.
Конечно, параллельные вычисления в основном нужны для науки, вычислений с большими массивами данных, но это дело реально даёт существенное приращение в скорости вычислений, проверено опытом.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Re: OpenMP во FreePascal
Имхо, не только для науки. Полно еще других, более прикладных областей применения.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Re: OpenMP во FreePascal
Да, обработка изображений, например.Лекс Айрин писал(а):Полно еще других, более прикладных областей применения.
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: OpenMP во FreePascal
Не надо тащить в язык корявую реализацию для сишников. Есть же более грамотные решения в C# и Go.
Re: OpenMP во FreePascal
serbod
А Вы не могли бы кратко описать достоинства и недостатки того и дугого?
А Вы не могли бы кратко описать достоинства и недостатки того и дугого?
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: OpenMP во FreePascal
Многопоточность в Go выглядит примерно так:
в результате получится примерно так:
test1
done
test2
...
ok
А для синхранизации и получения результата есть так называемые каналы. Допустим, что readln() может принимать то, что отправлено в паралельном writeln().
Получится такое:
test1
test2
..
ok
done
Добавлено спустя 10 минут 14 секунд:
Что касается недостатков. Си (как и Паскаль) суров и не умеет самостоятельно определять, какие переменные и функции будут использоваться из разных потоков и каким образом будут использоваться. Для этого нужны:
- модификаторы для запрета изменения или создания копии при изменении (у Паскаля такое по умолчанию для параметров функций)
- модификаторы для атомарного доступа к переменной, то есть автоматического помещения переменной в "кабинку", в которую зайти может только один поток, и пока он не выйдет, другие будут ждать.
Код: Выделить всё
procedure Test();
var i: Integer;
begin
for i := 1 to 100 do writeln('test' + IntToStr(i));
writeln('ok');
end;
go Test();
writeln('done');в результате получится примерно так:
test1
done
test2
...
ok
А для синхранизации и получения результата есть так называемые каналы. Допустим, что readln() может принимать то, что отправлено в паралельном writeln().
Код: Выделить всё
go Test();
while readln() <> 'ok' do sleep();
writeln('done');
Получится такое:
test1
test2
..
ok
done
Добавлено спустя 10 минут 14 секунд:
Что касается недостатков. Си (как и Паскаль) суров и не умеет самостоятельно определять, какие переменные и функции будут использоваться из разных потоков и каким образом будут использоваться. Для этого нужны:
- модификаторы для запрета изменения или создания копии при изменении (у Паскаля такое по умолчанию для параметров функций)
- модификаторы для атомарного доступа к переменной, то есть автоматического помещения переменной в "кабинку", в которую зайти может только один поток, и пока он не выйдет, другие будут ждать.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Re: OpenMP во FreePascal
мда...какая до фигня получается((( а почему нельзя дождаться пока все потоки остановятся?
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: OpenMP во FreePascal
Лекс Айрин писал(а):а почему нельзя дождаться пока все потоки остановятся?
Потому что остановка, завершение и успешное завершение потока это разные вещи. В примере показано успешное завершение.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Re: OpenMP во FreePascal
serbod, но в этом случае, фактически, теряется смысл в "параллельных" вычислениях. Обвязка съест всю выгоду.
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: OpenMP во FreePascal
Лекс Айрин, обвязка это неизбежное зло, которое незначительно для абсолютного большинства случаев. Вы же не заморачиваетесь с внутренней механикой работы строк, объектов, интерфейсов и динамической памяти? Зато резко исчезают трудновыявляемые проблемы во время работы программы.
Для каких-то случаев понадобится оптимизация, но это делается либо на более низком уровне (ассемблер, железо), либо на более высоком (дизайн, архитектура). А на уровне исходного кода достаточно просто понимать, что публичную переменную в потоке использовать "дороже", чем приватную или константу.
Для каких-то случаев понадобится оптимизация, но это делается либо на более низком уровне (ассемблер, железо), либо на более высоком (дизайн, архитектура). А на уровне исходного кода достаточно просто понимать, что публичную переменную в потоке использовать "дороже", чем приватную или константу.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Re: OpenMP во FreePascal
serbod,и добавляется куча новых проблем. Ведь вычисления не ведутся просто для забития процессорного времени. Предполагается, что вся матрица значений используется сразу же после того как закончатся все вычисления. Одно дело если потоков 4-6, а если их, к примеру, 20К +? Причем, это не сферическая задача в вакууме, а обычная обработка изображений по типу шейдера, игра "жизнь".
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: OpenMP во FreePascal
Лекс Айрин, если железо позволяет 20К потоков и компилятор умеет делать эффективный код под это железо, то в чем могут быть проблемы, кроме кривых рук программиста?
С технической стороны, я не знаю, как работают шейдеры в видеоускорителях. Предполагаю, что там используется какой-то свой специфичный компилятор, код для которого можно сгенерить из основного компилятора. Как ассемблерную вставку, например.
С технической стороны, я не знаю, как работают шейдеры в видеоускорителях. Предполагаю, что там используется какой-то свой специфичный компилятор, код для которого можно сгенерить из основного компилятора. Как ассемблерную вставку, например.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Re: OpenMP во FreePascal
serbod писал(а):С технической стороны, я не знаю, как работают шейдеры в видеоускорителях. Предполагаю, что там используется какой-то свой специфичный компилятор, код для которого можно сгенерить из основного компилятора.
шейдер, это минипрограмма выполняющаяся на многопоточном процессоре. Фактически же это матрица преобразований. Причем, каждое ядро имеет доступ к соседям, так как использует в своих целях его данные. Конечно, их не 20К+ ... но порядка 4-5К в крайних версиях. И каждый кадр должен обрабатываться полностью за одну итерацию.
Да, там используется специфический компилятор, но, фактически, вся обработка идет за счет накладывания нескольких текстур ( текстура, карта глубин, карта освещенности и пр.. ) и вся работа по распараллеливанию ложится на видеокарту.
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Re: OpenMP во FreePascal
Eсли имеется в виду параллелизм данных (data parallelism), то есть одновременная обработка разных частей одного массива данных, то в Go оно делается путем фактического ограничения количества одновременно выполняемых задач до разумных пределов (оптимальных для железа). Можно в цикле запустить миллион потоков, но одновременно будет работать только 8 (по числу ядер), но по мере завершения отработавших потоков будут запускаться другие, пока все не отработают. Примерно так:
В OpenMP в принципе то же самое, но через жопу и с уродливым синтаксисом поверх цикла for.
Код: Выделить всё
procedure ProcessItem(var arr: array; i: Integer; var n: Integer); threaded;
begin
// обработка arr[i]
Dec(n); // поскольку процедура отмечена как threaded, то операции над внешними переменными атомарные,
// то есть вместо Dec(n) будет InterlockedIncrement(n, -1);
end;
var
n: Integer;
begin
n := Length(arr)-1;
for i := 0 to n do
begin
go ProcessArrItem(arr, i, n);
end;
while n > 0 do sleep(); // ждем завершения всех задач
end;
В OpenMP в принципе то же самое, но через жопу и с уродливым синтаксисом поверх цикла for.
Re: OpenMP во FreePascal
Походу Айрин не понял.
" дождаться пока все потоки остановятся", на практике означает что компилятор сам вставит код ожидания завершения потоков, такой-же while и он никакого ущерба производительности не нанесет, тобишь разница только в том кто это делает программист или компилятор.
Разница между OpenMP и go (горутины) существенная и заключается в том что это не системные потоки а задачи, менеджмент потоков лежит на среде исполнения, она смотрит что прогу запустили на 8 ядерном проце значит делаем 8 потоков воркеров, а горутин может быть хоть тыща, они выстраиваются в очередь на исполнение к этим 8 потокам. OpenMP делает столько задач сколько доступно потоков, в go, программист, сам разделяет цикл на куски, OpenMP делает это сама, с одной стороны это хорошо с другой это не подконтрольная магия.
В итоге в go нету магии, весь исполняемый код обозрим, нету зависимости от количества ядер.
" дождаться пока все потоки остановятся", на практике означает что компилятор сам вставит код ожидания завершения потоков, такой-же while и он никакого ущерба производительности не нанесет, тобишь разница только в том кто это делает программист или компилятор.
Разница между OpenMP и go (горутины) существенная и заключается в том что это не системные потоки а задачи, менеджмент потоков лежит на среде исполнения, она смотрит что прогу запустили на 8 ядерном проце значит делаем 8 потоков воркеров, а горутин может быть хоть тыща, они выстраиваются в очередь на исполнение к этим 8 потокам. OpenMP делает столько задач сколько доступно потоков, в go, программист, сам разделяет цикл на куски, OpenMP делает это сама, с одной стороны это хорошо с другой это не подконтрольная магия.
В итоге в go нету магии, весь исполняемый код обозрим, нету зависимости от количества ядер.
