Не увидел эффекта от Open MP на четырехядерном процессоре. В частности, пример из справки про перемножение матриц эффекта не дает. В веб-версии системы - аналогично. Версия 3.0, сборка 1052
Упс… В примере про умножение матриц ошибка - директивы {$omp parallel for }
записаны в обоих вариантах процедур умножения. Если из “непраллельного” варианта убрать, то получается большая разница по времени.
Но в своей программе эффект наблюдаю даже обратный.
Не надо считать собеседника идиотом.
Кода у меня тыщ 6 строк. Умножение матриц - это пример из встроенной справки. Матрицы там 400х400. И если исправить этот пример, все работает ожидаемо. А в реальной программе что с {$omp parallel for}, что без - разницы не видно. При том что при отладке (точка остановки) проверяется, что индексы цикла идут не подряд. И ядра процессора как-то не загружены.
Конечно, ваши 6к строк тут не нужны. Чем возмущаться лучше бы минимальный неработающий пример продемонстрировали. Если ошибка в вашей программе, то скорее всего вы её сами обнаружите, пока будете его генерировать. Даже если это не так, то хотя бы появится вероятность, что вам помогут.
Вот эскиз того куска программы, который вызывает вопросы:
{$omp parallel for}
for var r := ymin to ymax do
HLT( r, T, a);
T и a - разделяемые переменные, они внутри процедуры HLT не меняются. T - массив. В HLT есть цикл while, содержащий десяток действий, в том числе вызовы двух функций. Число итераций цикла for несколько сотен. Цикла while - в среднем примерно столько же.
Обращаю внимание, что работает все правильно, то есть конфликтов с разделяемыми переменными нет. Но и эффекта изменения времени работы нет - ни в сторону уменьшения, ни в сторону увеличения.
Но речь вроде не о том, сколько у тебя кода (про это я тоже ни слова не говорил), а матрицы какого размеры ты перемножаешь. И как ты замеряешь время выполнения. Тут тоже есть нюансы. И эскиза, приведенного постом выше, явно недостаточно.
Грубо говоря, 400х400 у.е. Это копейки. При перемножении матриц из примера было 400х400х400. Лишняя х400, думаю, заметна. Плюс там наверняка еще и самый просто вариант, при котором память в кэш не особо помещалась и вообще использовалась не оптимально, что в свою очередь также влияло (не лучшим образом) на скорость выполнения.
Использование OpenMP не всегда приводит к ускорению. Все зависит от выполняемых в каждом потоке действий (их сложности), работы с памятью и т.п. На синхронизацию потоков тоже определенный ресурс тратится.
P.S.
Этот факт еще демонстрирует и то, что при увеличении кол-ва потоков, к примеру, в 4 раза не будет 4-хкратного увеличения производительности. Совсем.
Давайте Вы не будете “тыкать”. Хорошо?
Матрицы я вообще не перемножаю. Вернее, перемножаю, но не в том месте, о котором речь. Может, в самом деле несколько сотен на несколько сотен - маловато… Но, вроде бы в другой программе на Си в MS VS в похожей (но не идентичной) ситуации ускорение есть.Что касается измерения времени - тут нет проблем. Хорошее ускорение было бы видно на глаз, речь идет о программе, генерирующей движущуюся картинку. А так, как с OpenMP, так и без 59-60 fps.
P.S. Сейчас сделал опыт с умножением матриц. При размере матриц 20х20 ускорение в 2 раза на 4 ядрах. А 20х20х20 = 8000, в то время как 100х100 = 10000. Даже на матрицах 10х10 ускорение процентов 30.
К сожалению, OpenMP реализован в PascalABC.NET не полностью.
Точнее даже сказать, это была студенческая работа по реализации некоторых возможностей OpenMP в .NET. Ничего такого на тот момент не было сделано.
То, что нет ускорения, означает, что ровно такую ситуацию движок распараллелить не может. Он может распараллелить только совсем простые циклы.
С тех пор в .NET появилось множество библиотечных функций, связанных с распараллеливанием.
Я тоже это заметил, но что бы он хорошо работал с OpenMp нельзя в цикл добавлять другие подпрограммы (например у Меня с ProgressBar.Value не работало).
Я тоже это заметил, но что бы он хорошо работал с OpenMp нельзя в цикл добавлять другие подпрограммы (например у Меня с ProgressBar.Value не работало).
{omp parallel for}
for var j:=1 to n do
PBar.Value:= j*100/n; // так не будет
//распаралеливаться
for var i:=1 to n do
<переложение матриц>