Однопроцессорные программы, работающие на четырехъядерном процессоре с поддержкой Hyper-Threading

Я исследователь в статистическом распознавании образов, и я часто запускаю симуляции, которые работают в течение многих дней. Я запускаю Ubuntu 12.04 с Linux 3.2.0-24-generic, который, как я понимаю, поддерживает многоядерность и гиперпоточность. С моим Intel Core i7 Sandy Bridge Quadcore с HTT я часто запускаю 4 симуляции (программы, которые занимают много времени) в одно и то же время. Прежде чем задать свой вопрос, вот что я уже (думаю, я) знаю.

  • Моя ОС (Ubuntu 12.04) обнаруживает 8 процессоров из-за гиперпоточности.
  • Планировщик в моей ОС достаточно умный, чтобы никогда не планировать две программы для работы на двух логических (виртуальных) ядрах, принадлежащих к одному и тому же физическому ядру, потому что ОС поддерживает SMP (одновременная многопоточность).
  • Я прочитал страницу Википедии о Hyper-Threading.
  • Я прочитал страницу HowStuffWorks на Sandy Bridge.

ОК, мой вопрос таков. Когда я одновременно запускаю 4 симуляции (программы) на своем компьютере, каждый из них работает на отдельном физическом ядре. Однако из-за гиперпоточности каждое физическое ядро ​​разбивается на два логических ядра. Поэтому верно ли, что каждый из физических ядер использует только половину своей полной мощности для запуска каждого из моих симуляций?

Спасибо вам заблаговременно. Если какая-либо часть моего вопроса не ясна, сообщите мне.

Ответ 1

Этот ответ, вероятно, поздний, но я вижу, что никто не предлагал точное описание того, что происходит под капотом.

Чтобы ответить на ваш вопрос, нет, один поток не будет использовать половину ядра. Один поток может работать внутри ядра за раз, но этот поток может насытить всю вычислительную мощность ядра.

Предположим, что поток 1 и поток 2 принадлежат ядру # 0. Резьба 1 может насытить всю мощность обработки ядра, а поток 2 ждет, пока другой поток завершит выполнение. Это сериализованное исполнение, а не параллельное.

С первого взгляда, похоже, что лишняя нить бесполезна. Я имею в виду, что ядро ​​может обрабатывать 1 поток сразу правильно?

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

  • Ошибка кеша
  • неверное предсказание отрасли

Ошибка кэширования

Когда он получает задание, CPU ищет внутри своего кеша для адресов памяти, с которыми ему нужно работать. Во многих сценариях данные памяти настолько разбросаны, что физически невозможно сохранить все требуемые диапазоны адресов внутри кеша (поскольку кеш имеет ограниченную емкость).

Когда ЦП не находит то, что ему нужно в кеше, он должен получить доступ к ОЗУ. Сама оперативная память работает быстро, но она бледнеет по сравнению с кэшем на процессоре. Задержка с памятью является основной проблемой здесь.

Во время обращения к ОЗУ ядро ​​застопоривается. Это ничего не делает. Это не заметно, потому что все эти компоненты работают на смешной скорости в любом случае, и вы не заметили бы это через какое-то программное обеспечение для загрузки CPU, но оно добавляет аддитивно. Один кеш промахивается за другим, а другой значительно ухудшает общую производительность. Здесь начинается вторая нить. В то время как ядро ​​задерживается в ожидании данных, второй поток перемещается, чтобы поддерживать занятость ядра. Таким образом, вы в основном отрицаете влияние производительности ключевых киосков.

Я говорю, главным образом, потому что второй поток также может заглохнуть ядро, если произойдет еще один промах кэша, но вероятность того, что 2 потока пропустит кеш в строке вместо 1 потока, будет намного ниже.

Неправильное предсказание отрасли

Прогнозирование ветки - это когда у вас есть путь к коду с более чем одним возможным результатом. Наиболее основным кодом ветвления будет оператор if. Современные процессоры имеют алгоритмы прогнозирования ветвлений, встроенные в свой микрокод, которые пытаются предсказать путь выполнения части кода. Эти предсказатели на самом деле довольно сложны, и хотя у меня нет достоверных данных о скорости предсказания, я вспоминаю некоторые статьи некоторое время назад, заявляя, что архитектура Intel Sandy Bridge имеет среднюю успешную скорость прогнозирования ветвления более 90%.

Когда процессор попадает на кусок разветвляющегося кода, он практически выбирает один путь (путь, который, по мнению предсказателя, является правильным) и выполняет его. Между тем, другая часть ядра оценивает выражение ветвления, чтобы увидеть, действительно ли предиктор ветки действительно прав или нет. Это называется спекулятивным исполнением. Это работает аналогично двум различным потокам: один оценивает выражение, а другой выполняет один из возможных путей заранее.

Здесь у нас есть два возможных сценария:

  • Предиктор был прав. Выполнение продолжается обычно из спекулятивной ветки, которая уже выполнялась, когда решался путь кода.
  • Прогноз был неправильным. Весь трубопровод, который обрабатывал неправильную ветку, должен быть сброшен и начать с правильной ветки. ИЛИ, легко доступная нить может войти и просто выполнить, в то время как беспорядок, вызванный неправильным предсказанием, разрешен. Это второе использование гиперпотока. Прогнозирование ветки на среднем ускоряет выполнение значительно, так как оно имеет очень высокий уровень успеха. Но производительность не совсем штраф, если предсказание неверно.

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

Из моего опыта гиперпоточность действительно помогает в 3D-рендеринге (которое я делаю как хобби). Я заметил улучшения на 20-30% в зависимости от размера сцен и материалов/текстур. Огромные сцены используют огромное количество оперативной памяти, что делает пропуски кеша гораздо более вероятными. Hyperthreading помогает в преодолении этих промахов.

Ответ 2

Поскольку вы работаете в ядре Linux, вам повезло, потому что планировщик достаточно умный, чтобы ваши задачи делились между вашими физическими ядрами.

Linux стал гиперссылкой в ​​ядре 2.4.17 (ссылка: http://kerneltrap.org/node/391)

Обратите внимание, что ссылка указана из старого планировщика O (1). Linux теперь использует алгоритм планирования CFS, который был введен в ядре 2.6.23 и должен быть еще лучше.

Но, как уже было предложено, вы можете поэкспериментировать, отключив гиперпоточность в BIOS и посмотрите, работает ли ваша конкретная рабочая нагрузка быстрее или медленнее с включенным или отсутствующим гиперпотоком. Если вы начинаете 8 задач вместо 4, вы, вероятно, обнаружите, что общее время выполнения для 8 задач при гиперпотоке быстрее, чем два отдельных прогона с 4 задачами, но опять же лучше всего поэкспериментировать. Удачи!

Ответ 3

Нет, это не совсем так. Гиперпотоковое ядро ​​- это не два ядра. Некоторые вещи могут работать параллельно, но не так сильно, как на двух отдельных ядрах.

Ответ 4

Если вам действительно нужны только 4 выделенных ядра, вы должны быть в состоянии отключить гиперпоточность на странице BIOS. Кроме того, и в этой части я менее понятен, я считаю, что процессор достаточно умен, чтобы больше работать над одним потоком, если его второе логическое ядро ​​не работает.