Аннотация:
Перечислю собственно вопросы, побудившие меня провести ряд экспериментов, и, в конечном итоге, написать эту заметку.
— Каковы издержки на явное переключение контекста? Как они зависят от количества потоков в программе?
— Как влияет на производительность многопоточной программы наличие в системе дополнительного процессора?
— Как зависит производительность многопоточной программы от конкретной операционной системы?
— Какие существуют ограничения на количество потоков в программе?
Ошибки тестирования
От:
Аноним
Дата:
15.11.02 16:32
Оценка:
1. Реально вызов Sleep(0) только увеличивает прожорливость — он вынуждает программу чаще находиться в режиме ядра. Небходимо использовать Sleep(1).
2. Необходимо вести счет не на милисекунды, а на часы. Потому,что один квант времени + переключение контекста занимает довольно много времени.
3. Нет информации о приоритетах при тестировании. Погрешность этих результатов очень велика.
Тема, безусловно, интересная. Но хотелось бы видеть примеры использования данной технологии. В каких задачах она дает ощутимый выйгрыш? В чем заключается выйгрыш?
Я понимаю, что узнать об этом можно, прочитав статьи. Но краткое резюме не помешало бы.
А вот о чем написано в самой статье я совершенно ничего не понял. Увы. Таблицы какие-то с какими-то числами, что-то насчет скорости, многопоточности, одно и двухпроцессорности. Может стоило бы графики какие-нибудь нарисовать? Единственная полезная вещь, извлеченная мной из этой статьи — это особенности распределения памяти под потоки приложения — вот за это спасибо, буду иметь в виду! А так...
1. Вызов Sleep(0) был поставлен сознательно для ужесточения условий тестирования. Как я указал в заметке, тесты предназначены для оценки общих издержек на переключение между потоками. Пусть уж лучше эти издержки будут немного завышены, чем занижены :)
2. Я бы не взялся измерять квант времени и время переключения контекста в часах. Так же я не уверен, что увеличение объема вычислений, ведущее к возрастания времени выполнения тестов до нескольких часов, радикально изменит соотношение результатов.
3. Ваше замечание про погрешность результатов поражает своей меткостью. Особенно с учетом того, что об этом написано в самой заметке. Если у Вас есть возможность провести измерения в идеальных условиях — милости просим, я с огромным интересом ознакомлюсь с результатами, благо исходные тексты тестов приложены к заметке. Что касается приоритетов — все тесты запускались в одинаковых условиях на более-менее чистых системах, что позволяет с определенной долей уверенности говорить о том, что соотношение результатов, полученных на разных системах, достаточно близко к реальному.
А в остальном Ваш коммантарий очень интересен.
Числа это миллисекунды, затраченные тестовой прогой на выполнение фиксированного объема вычислений при разных количествах потоков. Ключевой момент — _все_ цифры это один и тот же объем вычислений в разных условиях. Как объяснить еще проще — увы, не знаю :)
Здравствуйте, rh2000, Вы писали:
R>1. Вызов Sleep(0) был поставлен сознательно для ужесточения условий тестирования. Как я указал в заметке, тесты предназначены для оценки общих издержек на переключение между потоками. Пусть уж лучше эти издержки будут немного завышены, чем занижены
Кстати, а вызов Sleep(0) точно вызвает переключение контекста, нет ли там проверки if( Period == 0 ) return? Помнится, я написал ради эксперимента цикл.
for(;;)
Sleep( 0 );
И запустил. Других активных потоков не было. Загрузка процессора была 100%. Замена на Sleep(1) сразу уронила загрузку до 2-3%.
Или это происходит потому, что планировщик берёт на себя управление, смотрит, нет ли других кандидатов, их нету и сразу запускает поток ещё раз? А, типа, в случае Sleep(1) он считает обязанным хоть сколько-то потормозить?
--
wbr, Peter Taran
Re: Заметка о производительности многопоточных Win32-програм
РХ>Авторы: РХ> Роман Хациев
РХ>Аннотация: РХ>Перечислю собственно вопросы, побудившие меня провести ряд экспериментов, и, в конечном итоге, написать эту заметку.
РХ>- Каковы издержки на явное переключение контекста? Как они зависят от количества потоков в программе? РХ>- Как влияет на производительность многопоточной программы наличие в системе дополнительного процессора? РХ>- Как зависит производительность многопоточной программы от конкретной операционной системы? РХ>- Какие существуют ограничения на количество потоков в программе?
У меня возникли некоторые возражения по поводу корректности теста.
По сути на 2 процессорной машине при кол-во потоков более 2 и достаточном объеме ОЗУ затраты на переключение должны рости крайне медленно и их рост обусловлен только возрастанием очередей структур, используемых планировщиком. По сравнению с временным квантом, отведенным на работу потока, просмотр и переупорядочивание очередей планировщиком занимает процессорное время менее 1%. Принудительно же переключая контексты мы тем самым многократно увеличиваем именно эти затраты, само переключение занимает одинаковое время. Какая разница между 16 или 128 потоками?
В результате мы получаем цифры падения производительности чуть не в 2 раза, хотя на самом деле падения производительности реально не происходит.
С другой стороны, при большом количестве потоков их стеки просто не умещаются в ОЗУ (если специально не уменьшать размер стека в линковщике), в результате чего система начинает тратить дополнительное время на вытеснение памяти. Однако про размер памяти и его влияние на тест мы не услышали ни слова.
Таким образом, IMHO приведенные цифры имеют смысл только для рассмотрение тестового примера (исходного кода которого мы кстати не видели!) и не могут быть руководством при проектировании многопоточных приложений
Да пребудет с тобою сила
Re: Заметка о производительности многопоточных Win32-програм
РХ>Авторы: РХ> Роман Хациев
РХ>Аннотация: РХ>Перечислю собственно вопросы, побудившие меня провести ряд экспериментов, и, в конечном итоге, написать эту заметку.
РХ>- Каковы издержки на явное переключение контекста? Как они зависят от количества потоков в программе? РХ>- Как влияет на производительность многопоточной программы наличие в системе дополнительного процессора? РХ>- Как зависит производительность многопоточной программы от конкретной операционной системы? РХ>- Какие существуют ограничения на количество потоков в программе?
точные Ответы на поставленные вопросы не знаю. Но в Windows (в 2000 точно) есть "Фиберы"
которые позволяют существенно увеличить производительность многопоточных приложений т.к.
за переключениею контекстов отвечает сам пользователь (т.е. создатель приложения)
Re[2]: Заметка о производительности многопоточных Win32-прог
Y>точные Ответы на поставленные вопросы не знаю. Но в Windows (в 2000 точно) есть "Фиберы" Y>которые позволяют существенно увеличить производительность многопоточных приложений т.к. Y>за переключениею контекстов отвечает сам пользователь (т.е. создатель приложения)
Только вот смысл фиберов, когда все равно ts-mashine будет в разы эффективнее (потому, что контекст включает в себя только необходимую информацию), а по реализации ненамного сложнее. В общем, в dev\null это хозяйство. Имхо мертворожденный интерфейс.
Здравствуйте, tarkil, Вы писали:
T>Или это происходит потому, что планировщик берёт на себя управление, смотрит, нет ли других кандидатов, их нету и сразу запускает поток ещё раз? А, типа, в случае Sleep(1) он считает обязанным хоть сколько-то потормозить?
Насколько я помню Sleep(1) "тормозит" ровно 10 мс, т.е. равносилен Sleep(10)...
Голь на выдумку хитра, однако...
Re: Заметка о производительности многопоточных Win32-програм
Здравствуйте, tarkil, Вы писали:
T>Здравствуйте, rh2000, Вы писали:
R>>1. Вызов Sleep(0) был поставлен сознательно для ужесточения условий тестирования. Как я указал в заметке, тесты предназначены для оценки общих издержек на переключение между потоками. Пусть уж лучше эти издержки будут немного завышены, чем занижены
T>Кстати, а вызов Sleep(0) точно вызвает переключение контекста, нет ли там проверки if( Period == 0 ) return? Помнится, я написал ради эксперимента цикл.
T>
T>for(;;)
T> Sleep( 0 );
T>
T>И запустил. Других активных потоков не было. Загрузка процессора была 100%. Замена на Sleep(1) сразу уронила загрузку до 2-3%.
T>Или это происходит потому, что планировщик берёт на себя управление, смотрит, нет ли других кандидатов, их нету и сразу запускает поток ещё раз? А, типа, в случае Sleep(1) он считает обязанным хоть сколько-то потормозить?
Если почитать Рихтера, то он утверждает, что Sleep(0) отдает остаток кванта операционной системе, а Sleep с параметром, отличным от 0 приведет к "засыпанию" минимум на указанный промежуток времени. Как минимум это будет один квант, а как максимум зависит от наличия и количества более приоритетных потоков в системе.