Гиперпоточность работает?

Я запускаю на своем ПК некоторые довольно ресурсоемкие программы и замечаю, что загрузка ЦП выглядит довольно странно. Мой компьютер представляет собой четырехъядерный процессор i7-870, который предположительно имеет восемь виртуальных ядер.
Я использую библиотеку Task Parallel в .NET 4, поэтому ожидаю, что все ядра будут эффективно использоваться, но я получаю информацию, подобную этой, от Монитор процесса:

Использование ЦП

Ядра 6 и 8 почти не затрагиваются, и, если не считать короткого всплеска, 4 тоже.
Это то, чего мне следует ожидать?


person DefenestrationDay    schedule 10.06.2011    source источник
comment
компьютеры обычно работают по назначению, поэтому вам следует выяснить, что именно в вашем алгоритме не масштабируется. Вы не сказали, какой у вас алгоритм. Даже если вы проигнорируете виртуальные процессоры, использование вашего процессора будет очень низким.   -  person David Heffernan    schedule 10.06.2011
comment
(a) да (b) профиль (c) YMMV - гиперпоточность не является многоядерной и поэтому сильно зависит от типа загрузки инструкций, насыщения кеша и т. д.   -  person sehe    schedule 10.06.2011
comment
@ Дэвид - под «бедным» ты имеешь в виду «низкий»? Даже при среднем использовании 60% я бы (наивно, может быть?) ожидал, что ОС будет немного лучше распределять это между виртуальными ядрами.   -  person DefenestrationDay    schedule 10.06.2011
comment
@Cap: Affinity поддерживает выполнение потоков на одном ядре. Если вы не используете все ядра, это хорошо.   -  person Rick Sladkey    schedule 10.06.2011
comment
ОС предпочтет запускать потоки на процессоре, который последним запускал поток, для повышения производительности кэша. Поскольку ваше использование настолько низкое, это означает, что некоторые процессоры игнорируются.   -  person David Heffernan    schedule 10.06.2011
comment
Я думаю, что вы страдаете от раздора по замку. Это звучит правдоподобно?   -  person David Heffernan    schedule 10.06.2011
comment
@David: Правдоподобно - конечно: я посмотрю на это. Я ожидал 100% для этого процесса, на самом деле. Меня просто удивила (не)балансировка нагрузки..   -  person DefenestrationDay    schedule 10.06.2011
comment
@CapsicumDreams: ничего не получится, если разделить его между всеми ядрами. Часто более эффективно запускать одно ядро ​​на 100%, чем два ядра на 50% каждое (зависит от точного поведения кэша вашего кода).   -  person jalf    schedule 10.06.2011
comment
@Cap: Еще один параметр, который нужно измерить, — это ваша загрузка GC. Даже при фоновом сборщике мусора .NET4, если нагрузка на сборщик мусора слишком высока, потоки будут блокироваться, и вы никогда не сможете полностью использовать ядро.   -  person Rick Sladkey    schedule 10.06.2011


Ответы (3)


По большей части, да, я думаю, что это выглядит разумно. Имейте в виду, что гиперпоточность на самом деле просто имитирует два ядра. Каждому физическому ядру предоставляется два интерфейса, поэтому оно может читать два потока инструкций параллельно. Но они по-прежнему используют одни и те же исполнительные блоки. Таким образом, когда одно ядро ​​HT занято, исполнительные блоки берутся, поэтому его «двойное» ядро ​​сможет выполнять очень мало работы.

Кажется, это то, что вы видите на первых двух ядрах (второе, в частности, делает это очень очевидным).

Кроме того, вы почти никогда не сможете добиться идеальной загрузки процессора. Иногда ядро ​​просто зависает в ожидании памяти. Иногда это выполнение дорогостоящей неконвейерной инструкции, эффективно блокирующей исполнительные блоки на этом физическом ядре, возможно, на десятки или даже сотни циклов.

А иногда зависимости между инструкциями могут просто означать, что у вас нет нет ничего для выполнения одним или несколькими ядрами.

Кроме того, вы видите 8 графиков, а у вас всего 4 ядра, так что да, конечно, гиперпоточность работает. ;)

person jalf    schedule 10.06.2011
comment
когда он ожидает памяти, которая считается временем процессора, поэтому вы все равно можете получить 100% использование, даже если ваше использование памяти ужасно - person David Heffernan; 10.06.2011
comment
на самом деле для многих алгоритмов легко получить 100% использование - person David Heffernan; 10.06.2011
comment
Справедливо. Но даже если это просто межпоточные зависимости, это все равно объясняет, почему OP не видит 100% -ного использования всех ядер :) - person jalf; 10.06.2011
comment
должна быть блокировка, чтобы увидеть это. Конкуренция за память и зависание ухудшают время выполнения, но проявляются как полная загрузка ЦП. - person David Heffernan; 10.06.2011
comment
@David: но поскольку мы не знаем, по какому алгоритму работает OP и как он выполняется ..... Я собираюсь пойти дальше и заявить, что его алгоритм или конкретная его реализация, очевидно, не Масштабируйте, чтобы идеально использовать 8 ядер. ;) - person jalf; 10.06.2011
comment
это я прокомментировал некоторое время назад ;) - person David Heffernan; 10.06.2011

Вкратце

  1. да работает (конечно)
  2. профиль это
  3. YMMV - гиперпоточность не является многоядерной и, как таковая, сильно зависит от типа загрузки инструкций, насыщенности кеша и т. д. Ничего не зная о вашем коде (кроме того, что на самом деле это С#), вы можете искать наборы «небольших объектов», которые может быть преобразован в прямые System.Array из структур (общий List<> также будет использовать массив внутри и оптимизировать для типов элементов структуры)

$0.02

person sehe    schedule 10.06.2011
comment
это будет сложнее, чем ваш пункт 3. Все, что красное в диспетчере задач, - это время ядра. Эксплуатация ужасная. Оптимизация, основанная на структуре или массивах, не решит фундаментальную проблему, которая очень похожа на конфликт блокировок. - person David Heffernan; 10.06.2011
comment
Не уверен насчет более сложного (может быть проще), но даже при насыщении вы должны более равномерно распределять нагрузку. Время ЦП будет потрачено впустую (ничего не делая), но все равно будет показывать высокую загрузку. - person TomTom; 10.06.2011
comment
Самое забавное, что кажется, что некоторые ядра полностью игнорируются. Даже с 2-3 потоками время от времени они будут перемещаться между ядрами. - person TomTom; 10.06.2011
comment
@tom это совсем не странно, это именно то, что вы ожидаете - person David Heffernan; 10.06.2011

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

person Ankur    schedule 10.06.2011