Харт Джонсон М.
Шрифт:
Для изучения поведения различных вариантов реализации можно воспользоваться программой timep из главы 6 (программа 6.2). Тесты, которые проводились на системах, не загруженных никакими другими задачами, и состояли в выполнении 250 000 единичных рабочих заданий с использованием 1,2,4, 8, 16, 32, 64 и 128 потоков, показали следующие результаты:
• При небольшом количестве потоков (4 и менее) для выполнения каждого из вариантов реализации NS (отсутствие синхронизации), IN (функции взаимоблокировки) и CS (объекты CRITICAL_SECTION) требуется примерно одно и то же время. Вариант CS может оказаться несколько более медленным (10-20 процентов), демонстрируя типичное замедление работы программ, использующих синхронизацию. Вместе с тем, для выполнения варианта MX (мьютексы) требуется в два-три раза больше времени.
• Производительность варианта CS на однопроцессорных системах при использовании 5 и более потоков не всегда изменяется пропорционально количеству потоков. Картина может меняться при переходе от одной NT5-системы к другой, однако, как свидетельствуют данные, для каждой конкретной системы результаты согласуются между собой. В случае некоторых систем истекшее время удваивается при переходе к следующему члену ряда 1, 2, 4 и так далее, соответствующему количеству используемых потоков, но в одном случае (Windows 2000, процессор Pentium с частотой 1 ГГц, портативный компьютер) оно составляло (в секундах) 0.5, 1.0, 2.0, 4.0, 14.9, 16.0, 32.1 и 363.4, а в другом (Windows 2000, процессор Pentium 500 МГц, на стольный компьютер) — 1.2, 2.3, 4.7, 9.3, 42.7, 101.3, 207.8 и 1212.5 секунд. Как правило, резкое изменение поведения происходит тогда, когда количество потоков начинает превышать 4 или 8, но производительность остается приемлемой, пока количество потоков не превышает 128.
• В случае однопроцессорных систем вариант MX уступает варианту CS, причем отношение показателей производительности варьирует в пределах от 2:1 до 10:1 в зависимости от типа системы.
• В случае SMP-систем производительность может резко ухудшаться в десятки и сотни раз. Интуитивно кажется, что с увеличением количества процессоров производительность может только повышаться, но в силу механизмов внутренней реализации процессоры конкурируют между собой за право владения блокировками и обращения к памяти, и это объясняет, почему результаты для вариантов MX и CS оказываются практически одинаковыми. В случае объектов CS некоторого улучшения производительности удавалось добиться за счет тонкой настройки спин-счетчиков, о чем говорится в одном из следующих разделов.
• Для ограничения количества готовых к выполнению рабочих потоков без изменения базовой программной модели можно использовать семафоры. Эта методика рассматривается далее в этой главе.
Предупреждение
В массиве task_count намеренно использованы 32-битовые целые числа, чтобы увеличить верхний предел значений счетчика заданий и избежать создания предпосылок для возникновения "разрыва слов" ("word tearing") и "конфликтов строки кэша" ("cache line conflict") в SMP-системах. Два независимых процессора, на которых выполняются смежные рабочие потоки, могут одновременно изменять значения счетчиков смежных заданий путем внесения соответствующих изменений в свои кэши (32-битовые в системах на основе Intel x86). Вместе с тем, реально записываться в память будет только один кэш, что может сделать результаты недействительными. Чтобы избежать возможных рисков, следует позаботиться об отделении рабочих ячеек каждым из потоков друг от друга и их выравнивании в соответствии с размерами кэшей. В данном примере счетчик заданий может быть сгруппирован с аргументом потока, так что использованию 32-битовых счетчиков ничто не препятствует. Эта тема исследуется в упражнении 9.6.