nlothik (nlothik) wrote,
nlothik
nlothik

Многонитевое

В-общем, по следам предыдущего поста (спасибо ещё раз всем кто высказался), сделал так:

Если от деления количества работы на количество нитей есть остаток, то каждая нить берёт себе отрезок + 1, пока не будет выбран весь остаток.

Таким образом, при делении 96 массовов на 64 нити первые 32 нити получают по два элемента массива, а оставшиеся 32 -- по одному. И, похоже, это наиболее оптимальный алгоритм. Надо только аккуратно программировать ту часть, что обращается к переменным. На языке C# я это реализовал через lock -- очень просто.

Иначе может получиться так, что две нити одновременно попытаются отнять единицу из остатка. Ничем хорошим это не сулит.

На 64-процессорном сервере мне это запустить не получилось -- там не был установлен .NET нужной мне версии, а устанавливать -- это надо согласовывать сначала.

Так что запустил на 32-процессорном, вернее, на 16-процессорном, притворяющимся 32-процессорным через гиперпоточность (hyperthreading).

Результаты ожидаемые. По горизонтали -- количество нитей, по вертикали -- время, потраченное на обработку (в секундах).



Самое большое ускорение, разумеется, было при переходе с одной нити на две. Производительность выросла не в 2 раза, как можно было ожидать, а в 5 с гаком раз.

Вызвано это было, скорее всего, тем, что программа и данные, при разбитии на более мелкие задачи, целиком поместились в кеш.

Трагедия современных процессоров -- большее время своей жизни они не работают, а стоят, ничего не делая, потому что периферийные устройства не обладают достаточной скоростью, чтобы загрузить процессор.

Вот c = a + b -- казалось бы, чего может быть проще? Ан данная команда выполняется 40, если не больше, циклов, из которых на собственно сложение приходится ОДИН! (ну, если речь о целых числах). А остальные 39 -- ждание памяти, 13 (или даже 15) циклов на каждую переменную (если на компьютере стоит память DDR4). Так что работаем один цикл, а остальные -- курим веники.

Но если все эти числа у нас в кеше процессора, который намного быстрее основной памяти -- то наблюдаются вот такие вот артефакты, с 654 секунд время расчётов падает аж до 128.

Далее время выполнения планомерно снижается, достигая в самой нижней точке (16 нитей) -- 43 секунд. Несмотря на то, что логических процессоров в машине типа 32, на деле увеличение количества нитей снижает производительность. И зачем только придумывали эту гиперпоточность, спрашивается? Не вижу бенефитов. На 48 нитях производительность сравнима с процессом с 4 нитями, а 96 нитей считают массивы медленнее двух нитей.

Аномальный горбик с 13 нитями и временем выполнения в 60 секунд -- ради интереса, исследовал, для моих задач, всё же, что лучше -- более равномерное распределение задач между меньшим количеством нитей, или всё же больше нитей? Выяснилось, что всё же больше нитей выгоднее -- хотя сильная перекособоченность в распределении работы дала о себе знать, и большого ускорения работы по сравнению с 8 нитями не произошло.

Всем спасибо.
Tags: программирование
Subscribe

  • Платить преступникам за несовершение преступлений

    Запасаемся попкорном. Мне почему-то кааца, что на преступность это не повлияет от слова “никак”. Да, кстати, а почему мне не платят?…

  • Запрет на выселение

    Я чего-то не понимаю. Администрация Бидон Бидоныча в очередной раз продлила запрет на выселение неплатящих аренду жильцов. Момент раз: попробуйте…

  • Дураки, что ли

    Маск настаивает на том, чтобы заменить руль на новой Тесле S, вот таким вот, блин, причиндалом: Он дурак, что ли? Ну ведь сто раз уже…

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 3 comments