Вечера на Воре близ Москвы
Июл 20
Июл 20
Июн 23
Июн 16
13 июня я поставил ещё одну галочку в списке вещей, которые надо когда-то сделать.
На день рожденья моя любимая Саша подарила мне прыжок с 4 км, конечно же в тандеме но с задержкой раскрытия в 50 секунд.
Июн 9
Друзья!
Прошло немало времени с нашей последней встречи. Воды, и не только, утекло немало…
Кто-то разбогател, кто-то поумнел, а кто-то раздобрел…
Но практически у каждого, (мы уверены!) произошли какие-то изменения, и наверняка к лучшему!
Пришло время на людей посмотреть, и себя показать, похвастаться достижениями, посочувствовать неудачникам….
И время это – 18 июня.
Это особенная дата. Другой такой больше не будет. В этот торжественный день нам исполняется 66 лет.
Число 6 – число зверя. 66 – сатанинское вдвойне. Если не отогнать злых духов в этот день, может испортиться карма и неудачи будут преследовать нас всю жизнь…
Мы приглашаем Вас всех оказать нам небольшую услугу – отогнать злых духов.
Для этого нужно всего-лишь приехать в означенное место и принять участие в ритуале очищения (другое название – обмывание)
Помните, от Вас зависит наше будущее!
Игорь и Максим
Празднование будет в районе города Дубна, описание в конце сообщения.
Проживание в палатках.
На машине можно подъехать без затруднений, легковая машина проезжает.
ЗЫ. Культпрограмма стандартная.
Приезжаем, сразу приступаем к первому этапу очищения (уборка мусора с места ритуала).
далее – водные процедуры, всевозможные игры, футбол, волейбол, бадминтон, слеклайн, ну и тд.
Обмывание в течение всего времени.
ЗЗЫ: Подарки дарят только те, кто не приезжает.
Место проведения:
На вьезде в Дубну пост ДПС, поворачиваем на нем направо и едем по главной дороге, проезжаем :
===== Описание удалено =====
Если последняя стоянка занята, то останавливаемся на предыдущей незанятой. И т.д. по рекурсии.
Обязательно возьмите защиту от комаров!
Май 18
Ездили в Грецию на Крит с 28 апреля по 9 мая. Отель Europa Beach, всё включено, отель понравился. Погода была разная, от пасмурных дней с сильным холодным ветром до жары с солнцем. Море достаточно тёплое чтобы купаться, в бассейнах в отеле тоже хорошо. Самое начало сезона, людей вначале было совсем мало, что плюс. Из минусов – аквапарк Критский ещё не работал.
Янв 24
В продолжение выпуска 2.
Чтож, попробуем ускорить нашу функцию ещё больше.
Первое, что бросается в глаза при анализе работы функции из выпуска 2 void f3(double * pdArr) так это неполная загрузка ядер в следствии не очень хорошей балансировки циклов. На этот случай у OpenMP так же есть инструменты. Для балансировки циклов используется директива schedule(type[,size]), подробнее можно почитать тут.
Не вдаваясь в подробности скажу, что наилучший результат дал вариант #pragma omp parallel for schedule(dynamic, 8192). На всякий случай, в качестве параметра, я использую величину, являющейся степенью двойки, на такое число компилятору всяко проще делить (если это ему поможет, а мне уж точно не навредит). Так какой же результат получается с такой директивой? 1.72 секунды, что 2.5 раза быстрее чем однопоточная версия функции. Использование других дериктив и других чисел в размере блока так же может давать прирост в ускорении но не такой значительный. Уменьшение размера блока увеличивает накладные расходы на обслуживание, увеличение – ухудшает балансировку. Т.е. размер блока надо подбирать индивидуально в зависимости от объёма работы, совершаемой в самом теле цикла. И на последок картина, как выглядит выполнение оптимизированной программы в Intel Thread Profiler:

На картинке представлено (как и в прошлый раз) небольшой участок выполнения программы (примерно 4 запуска параллельного цикла). Видно, что балансировка циклов стала почти идеальной (все потоки заканчивают работу практически одновременно). И даже в случае задержки запуска некоторых потоков (как в третьем цикле на картинке) все они завершают работу в один момент. Мы достигли 2.5 кратного ускорения цикла при распараллеливании его на 8 ядер. Результат достаточно посредственный, но это всё же ускорение по сравнению с однопоточной версией. В следующем выпуске исследуем причины такого не самого яркого результата.
В продолжение выпуска 1.
Так вот наблюдательный опытный разработчик конечно же догадался что причиной замедления параллельной версии стала строка #pragma omp critical. Не поставить её было нельзя, т.к. запись происходит в общую, для разных потоков, память. Будет очень показательно взглянуть на картинку, которую нам показывает Intel Thread Profiler в случае цикла с critical:

Верхняя гистограмма показывает что бОльшую часть времени наша функция задействовала всего 2 ядра на машине. По нижней части картинки видно что каждый поток работает лишь небольшую часть времени, потом натыкается на critical секцию и останавливается, передавая управление другому потоку (жёлтые линии). И такая постоянная передача управления стоит совсем не дёшево (от того и замедление в 50 раз).
Но стандарт OpenMP позволяет в данном случае использовать более «мягкую» директиву #pragma omp atomic, но при этом никто не гарантирует что компилятор не заменит её на тот же critical. Давайте проверим компилятор от Майкрософт. Проведём эксперимент с немного изменённой функций:
компилируем, запускаем и получаем ~2.6 секунд (в некоторых запусках бывает заметно больше). Much better! Ускорение в 1.7 раза (на 8 ядрах) относительно однопотоковой версии. И давайте взглянем на картину, которую нам даёт тот же Intel Thread Profiler:

Видим, что теперь функция использует почти всегда все 8 ядер системы, хотя балансировка циклов оставляет желать лучшего, и отдельные потоки заканчивают работу намного раньше других, что приводит к неполной загрузке системы. Жёлтые линии на данной картинке – это запуски цикла, который у меня в тесте запускается 100 раз подряд для получения более точного результата измерения (на картинке представлен только небольшой кусок процесса выполнения программы).
О дальнейших возможностях улучшения работы параллельной версии программы в следующем выпуске.