Используя собственно данную технологию натолкнулся на его особенность или собственную глупость, что и хотел выяснить. Были ли у кого проблемы с ней?
У меня скорость сильно падает по отношению с нераспараллеленой версией кода пи запуске 8 процессов на 4-ядерной архитектуре.
Цикл самый обычный:
#ifdef _OPENMP
procsCount = omp_get_num_procs();
#pragma omp parallel for num_threads(procsCount), schedule(dynamic)
#endif// _OPENMPfor ( int y = 0; y < dstHeight; y++ )
{
setResizePixel(Img, y, dstWidth, scaley, scalex, Dst);
}
Хотя все было корректно... Пришлось все что было локализовано в распараллеливаемом цикле перевести в процедуру setResizePixel тогда проблемы не стало. Чья глюкоза?
Здравствуйте, sof.bix, Вы писали:
SB>Используя собственно данную технологию натолкнулся на его особенность или собственную глупость, что и хотел выяснить. Были ли у кого проблемы с ней? SB>У меня скорость сильно падает по отношению с нераспараллеленой версией кода пи запуске 8 процессов на 4-ядерной архитектуре.
SB>Цикл самый обычный: SB>
SB>#ifdef _OPENMP
SB>procsCount = omp_get_num_procs();
SB>#pragma omp parallel for num_threads(procsCount), schedule(dynamic)
SB>#endif// _OPENMP
SB>for ( int y = 0; y < dstHeight; y++ )
SB>{
SB> setResizePixel(Img, y, dstWidth, scaley, scalex, Dst);
SB>}
SB>
SB>В чем может быть дело?
Что в функции setResizePixel()?
И как объявлены все используемые переменные?
SB>Да еще возникала проблема №26 из отсюдова
SB>Хотя все было корректно... Пришлось все что было локализовано в распараллеливаемом цикле перевести в процедуру setResizePixel тогда проблемы не стало. Чья глюкоза?
Не понятно, как может возникнуть проблема №26, если всё корректно. Она может возникнуть только если программа написана *НЕ* корректно.
Здравствуйте, sof.bix, Вы писали:
SB>Здравствуйте, remark, Вы писали:
R>>Что в функции setResizePixel()? R>>И как объявлены все используемые переменные?
SB> #pragma omp parallel for num_threads(procsCount), schedule(dynamic)
Попробуй указать schedule(dynamic, 50). chunk_size=1 это слишком мало здесь.
И может быть вообще другие типы schedule попробовать и другие размеры chunk_size.
Здравствуйте, sof.bix, Вы писали:
SB>Здравствуйте, remark, Вы писали:
R>>Что в функции setResizePixel()? R>>И как объявлены все используемые переменные?
SB> Dst.setRawColor(x,Dst.getHeight() — y — 1, color);
Здравствуйте, remark, Вы писали:
R>Попробуй указать schedule(dynamic, 50). chunk_size=1 это слишком мало здесь. R>И может быть вообще другие типы schedule попробовать и другие размеры chunk_size.
schedule(dynamic, 50) — что это дает?
chunk_size=1 — что это такое?
Здравствуйте, sof.bix, Вы писали:
SB>Здравствуйте, remark, Вы писали:
R>>Попробуй указать schedule(dynamic, 50). chunk_size=1 это слишком мало здесь. R>>И может быть вообще другие типы schedule попробовать и другие размеры chunk_size.
SB>schedule(dynamic, 50) — что это дает? SB>chunk_size=1 — что это такое?
Здравствуйте, sof.bix, Вы писали:
SB>Здравствуйте, remark, Вы писали:
R>>Попробуй указать schedule(dynamic, 50). chunk_size=1 это слишком мало здесь. R>>И может быть вообще другие типы schedule попробовать и другие размеры chunk_size.
SB>schedule(dynamic, 50) — что это дает? SB>chunk_size=1 — что это такое?
Нет. Потери в некоторых случаях даже выросли.
А что вы думаете о взаимодействии двух шедулеров (осевого и опенМП)?
Есть подозрение что при любом типе планировки потери неизбежны.
На днях попробовал просто запускать 4 процесса по 3 нити на 4-х ядрах. Потери ~3%
Здравствуйте, sof.bix, Вы писали:
SB>Здравствуйте, remark, Вы писали:
R>>Помогло?
SB>Нет. Потери в некоторых случаях даже выросли. SB>А что вы думаете о взаимодействии двух шедулеров (осевого и опенМП)? SB>Есть подозрение что при любом типе планировки потери неизбежны. SB>На днях попробовал просто запускать 4 процесса по 3 нити на 4-х ядрах. Потери ~3%
Я не очень понял, потери относительно чего? На ~3% стало медленнее отночительно чего?
Небольшой оверхед шедулер OpenMP, естественно, вносит. Например, если размер одной задачи, выделяемой потоку, равен 10'000 тактов, то оверхед может составлять как-раз ~3%.
Если размер задачи 10 тактов, то оверхед может составлять ~3000%.
Вот тут я тоже не очень понял:
"У меня скорость сильно падает по отношению с нераспараллеленой версией кода пи запуске 8 процессов на 4-ядерной архитектуре."
А при запуске 2 процессов? Ускоряется?
А при запуске 4 процессов? Ускоряется?
Т.е. именно при запуске 8 замедление?
Здравствуйте, sof.bix, Вы писали:
SB>Используя собственно данную технологию натолкнулся на его особенность или собственную глупость, что и хотел выяснить. Были ли у кого проблемы с ней? SB>У меня скорость сильно падает по отношению с нераспараллеленой версией кода пи запуске 8 процессов на 4-ядерной архитектуре.
Здравствуйте, remark, Вы писали:
R>Кстати, вот тут рядом ветка тоже про OpenMP, где есть подозрение, что производительность просто упирается в пропускную способность памяти: R>http://www.rsdn.ru/forum/message/3127856.1.aspx
Читал, думал... Наверное это не мой случай.
В моем как раз много математических операций на уже подготовленных данных.
Хотя постоянное перемещение по картинке (чтение массива данных) конечно вносит свою лепту.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, sof.bix, Вы писали:
SB>>Здравствуйте, remark, Вы писали:
R>>>Помогло?
SB>>Нет. Потери в некоторых случаях даже выросли. SB>>А что вы думаете о взаимодействии двух шедулеров (осевого и опенМП)? SB>>Есть подозрение что при любом типе планировки потери неизбежны. SB>>На днях попробовал просто запускать 4 процесса по 3 нити на 4-х ядрах. Потери ~3%
R>Я не очень понял, потери относительно чего? На ~3% стало медленнее отночительно чего? R>Небольшой оверхед шедулер OpenMP, естественно, вносит. Например, если размер одной задачи, выделяемой потоку, равен 10'000 тактов, то оверхед может составлять как-раз ~3%. R>Если размер задачи 10 тактов, то оверхед может составлять ~3000%. R>Вот тут я тоже не очень понял: R>"У меня скорость сильно падает по отношению с нераспараллеленой версией кода пи запуске 8 процессов на 4-ядерной архитектуре."
В общем сравнивалось время выполнения двух версий программы. В ней есть параллельно идущие и нераспараллеленые куски кода, выполняющиеся по одиночке примерно за 200сек. Одна была с отключеной поддержкой OpenMP, другая включеной (число потоков=числу ядер фиксированно). Запуск разных версий шел естественно последовательно, но в разных, параллельно идущих, количествах копий . 4-8. Скорость падала при количестве процессов, сравнимым с количеством ядер.
Вспомним что процессор 4-х ядерный R>А при запуске 2 процессов? Ускоряется?
(должно быть ускоряется, но не тестировалось) R>А при запуске 4 процессов? Ускоряется?
замедляется ~10% R>Т.е. именно при запуске 8 замедление?
еще медленней 10-20%
А один процесс — естественно быстрее раза в три
R>
Коллективная мысль наводит что дело в Виндовом шедулере, т.е. под саляркой меньшие потери будут!?
Здравствуйте, sof.bix, Вы писали:
SB>В общем сравнивалось время выполнения двух версий программы. В ней есть параллельно идущие и нераспараллеленые куски кода, выполняющиеся по одиночке примерно за 200сек. Одна была с отключеной поддержкой OpenMP, другая включеной (число потоков=числу ядер фиксированно). Запуск разных версий шел естественно последовательно, но в разных, параллельно идущих, количествах копий . 4-8. Скорость падала при количестве процессов, сравнимым с количеством ядер.
SB>Вспомним что процессор 4-х ядерный R>>А при запуске 2 процессов? Ускоряется? SB>(должно быть ускоряется, но не тестировалось) R>>А при запуске 4 процессов? Ускоряется? SB>замедляется ~10% R>>Т.е. именно при запуске 8 замедление? SB>еще медленней 10-20%
SB>А один процесс — естественно быстрее раза в три
Не понял, как X может быть больше Y на 10-20%, Y больше X на 200%
SB>Коллективная мысль наводит что дело в Виндовом шедулере, т.е. под саляркой меньшие потери будут!?
Лично я так не думаю. На хорошо написанную OpenMP программу шедулер ОС не должен влиять.
Основные 3 момента, которые обычно не дают программе масштабироваться:
1. Grain-size.
2. False-sharing.
3. Locality.
Здравствуйте, remark, Вы писали:
R>Не понял, как X может быть больше Y на 10-20%, Y больше X на 200%
Наверное вы не поняли потому что никогда не занимались абсурдными тестами.
Если вам ближе математика, то я постараюсь объяснить математическими терминами.
Y — кол. тактов без параллелизма. X — с параллелизмом и без (часть кода параллелиться)
Деление на 4 — означает выполнение на 4-х ядрах. Умножение на 4 означает работа в 4-х процессах.
Уровнения:
X / 4 < Y на 200% (здесь как ни крути Y будет исполняться на одном ядре а X на всех четырех)
4 * X / 4 > 4 * Y / 4 на 10-20% (здесь все выполняется на 4-х ядрах)
SB>>Коллективная мысль наводит что дело в Виндовом шедулере, т.е. под саляркой меньшие потери будут!?
R>Лично я так не думаю. На хорошо написанную OpenMP программу шедулер ОС не должен влиять.
Компилируется на MSVC 2005 R>Основные 3 момента, которые обычно не дают программе масштабироваться: R>1. Grain-size. R>2. False-sharing. R>3. Locality.
Здравствуйте, sof.bix, Вы писали:
SB>Здравствуйте, remark, Вы писали:
R>>Не понял, как X может быть больше Y на 10-20%, Y больше X на 200%
SB>Наверное вы не поняли потому что никогда не занимались абсурдными тестами. SB>Если вам ближе математика, то я постараюсь объяснить математическими терминами. SB>Y — кол. тактов без параллелизма. X — с параллелизмом и без (часть кода параллелиться) SB>Деление на 4 — означает выполнение на 4-х ядрах. Умножение на 4 означает работа в 4-х процессах. SB>Уровнения: SB>X / 4 < Y на 200% (здесь как ни крути Y будет исполняться на одном ядре а X на всех четырех) SB>4 * X / 4 > 4 * Y / 4 на 10-20% (здесь все выполняется на 4-х ядрах)
Ровном счетом ничего не понятно.
Приведи просто 2 цифры: время выполнения нераспараллелиной версии и время выполнения [частично] распараллелиной.
Здравствуйте, sof.bix, Вы писали:
SB>В общем сравнивалось время выполнения двух версий программы. В ней есть параллельно идущие и нераспараллеленые куски кода, выполняющиеся по одиночке примерно за 200сек. Одна была с отключеной поддержкой OpenMP, другая включеной (число потоков=числу ядер фиксированно). Запуск разных версий шел естественно последовательно, но в разных, параллельно идущих, количествах копий . 4-8. Скорость падала при количестве процессов, сравнимым с количеством ядер.
Ну а что Вы хотите? У Вас при включенном OpenMP каждый из 4-8 процессов запускает минимум 4 потока, всего имеете от 16 до 32 потока, одновременно конкурирующих за процессорное время 4-х ядер. Oversubscription, однако; как следствие — увеличение накладных расходов на переключение контекстов, а если вычисления ещё и с памятью что-то делают — значительно больше промахов по кэшу. Если OpenMP отключить — 4-8 потоков на 4 ядра, соответственно и проблем нет.
SB>Коллективная мысль наводит что дело в Виндовом шедулере, т.е. под саляркой меньшие потери будут!?
Здравствуйте, sof.bix, Вы писали:
SB>Используя собственно данную технологию натолкнулся на его особенность или собственную глупость, что и хотел выяснить. Были ли у кого проблемы с ней? SB>У меня скорость сильно падает по отношению с нераспараллеленой версией кода при запуске 8 процессов на 4-ядерном процессоре.
у интела есть VTune и Thread Profiler, которые помогут выяснить точную причину. про Thread Profiler не скажу, а у VTune есть триальная версия. эти инструменты — необходимейшая вещь для оптимизации. есть еще третий инструмент — компилятор. наверняка он поддерживает open mp лучше майкрософтовского.
про возможные причины уже сказано — промахи по кешу, гранулярность данных, затраты на синхронизацию.
кстати,
SB> Пришлось все, что было локализовано в распараллеливаемом цикле, перевести в процедуру
я думаю, будет правильно заставить работать кусок кода по месту, не вынося его в отдельную функцию. использование open mp не такая простая вещь, как кажется. интел на эту тему переодически семинары проводит.
Здравствуйте, degor, Вы писали:
SB>> Пришлось все, что было локализовано в распараллеливаемом цикле, перевести в процедуру
D>я думаю, будет правильно заставить работать кусок кода по месту, не вынося его в отдельную функцию. использование open mp не такая простая вещь, как кажется. интел на эту тему переодически семинары проводит.
То есть искать проблему, не обращая на противоречия с компилятором?