Работа с ЦП TSC, особенно в многоядерной многопроцессорной среде

В мире Linux, чтобы получить таймерные таймеры/часы-часы nano секунд, вы можете использовать:

#include <sys/time.h>

int foo()
{
   timespec ts;

   clock_gettime(CLOCK_REALTIME, &ts); 
   //--snip--      
}

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

В многоядерной многопроцессорной архитектуре, как синхронизируется эта синхронизация часов/таймера по нескольким ядрам/процессорам? Мое понимание заключается в том, что там, где делается неотъемлемое фехтование. Правильно ли это понимание?

Можете ли вы предложить некоторую документацию, которая подробно объяснила бы это? Меня интересуют микроархитектуры Intel Nehalem и Sandy Bridge.

ИЗМЕНИТЬ

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

Изменить

Спасибо за подтверждение того, что TSC синхронизирован по ядрам и процессорам. Но мой первоначальный вопрос: как эта синхронизация выполняется? это с каким-то фехтованием? знаете ли вы о какой-либо публичной документации?

Заключение

Спасибо за все входы: Здесь вывод для этого обсуждения: TSC синхронизируются при инициализации с использованием RESET, который происходит по ядрам и процессорам в многопроцессорной/многоядерной системе. И после этого каждое Ядро само по себе. TSC сохраняются в неизменном виде с помощью цикла Phase Locked Loop, который нормализует вариации частоты и, следовательно, изменения часов в пределах заданного Core, и именно так TSC остается в синхронизации по ядрам и процессорам.

Ответ 1

В новых процессорах (i7 Nehalem + IIRC) TSC синхронизируется по всем ядрам и работает с постоянной скоростью. Поэтому для одного процессора или нескольких процессоров на одном пакете или на материнской плате (!) Вы можете полагаться на синхронизированный TSC.

Из системного руководства Intel 16.12.1

Счетчик метки времени в новых процессорах может поддерживать повышение, называемый инвариантным TSC. Поддержка процессоров для инвариантного TSC указанный CPUID.80000007H: EDX [8]. Инвариантный TSC будет работать при постоянная скорость во всех ACPI P-, C-. и T-состояния. Это архитектурное поведение продвигается вперед.

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

Изменить: по крайней мере, на нескольких процессорах в одном пакете или на материнской плате синхронизируется инвариантный TSC. TSC reset равен нулю при a/RESET, а затем тикает вперед с постоянной скоростью на каждом процессоре без дрейфа. Сигнал /RESET гарантированно будет поступать на каждый процессор одновременно.

Ответ 2

Прямо от Intel, здесь объясняется, как последние процессоры поддерживают TSC, который тикает с постоянной скоростью, является синхронным между ядрами и пакетами на многоплатформенной материнской плате и может даже продолжать тикать, когда процессор переходит в глубокий сон C-состояние, в частности, см. Объяснение от Vipin Kumar EK (Intel):

http://software.intel.com/en-us/articles/best-timing-function-for-measuring-ipp-api-timing/

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

http://software.intel.com/en-us/articles/intel-gpa-tip-cannot-sychronize-cpu-timestamps/

Все сокеты/пакеты на материнской плате получают два внешних общих сигнала:

  • RESET
  • Ссылка CLOCK

Все сокеты см. в разделе RESET одновременно с подключением материнской платы, все пакеты процессоров получают опорный тактовый сигнал от внешнего кварцевого генератора, а внутренние часы в процессоре сохраняются в фазе (хотя обычно с большим множителем, например, 25x) с цепью, называемой фазовой блокировкой (PLL). Последние процессоры будут синхронизировать TSC на самой высокой частоте (множителе), которую процессор оценивает (так называемый постоянный TSC), независимо от множителя, который может использовать любое отдельное ядро ​​из-за регулирования температуры или регулирования мощности (так называемый инвариантный TSC). Процессоры Nehalem, такие как X5570, выпущенные в 2008 году (и более новые процессоры Intel), поддерживают "Non-stop TSC", который будет продолжать тикать даже при сохранении мощности в режиме сильного C-состояния (C6). См. Эту ссылку для получения дополнительной информации о различных состояниях питания:

http://www.anandtech.com/show/2199

После дальнейших исследований я столкнулся с патентом Intel, зарегистрированным 12/22/2009 года и опубликованным 27.06.2011, озаглавленным "Контрольные отметки счетчика времени (TSC) для Mulitple Cores And Threads"

http://www.freepatentsonline.com/y2011/0154090.html

Страница Google для этой патентной заявки (со ссылкой на страницу USPTO)

http://www.google.com/patents/US20110154090

Из того, что я собираю, есть один TSC в uncore (логика в пакете, окружающем ядра, но не часть какого-либо ядра), который увеличивается на каждый внешний такт шины на значение в указанном конкретном регистре машин по Випину Кумару по ссылке выше (MSR_PLATFORM_INFO [15: 8]). Часы внешней шины работают на частоте 133.33 МГц. Кроме того, каждое ядро ​​имеет собственный регистр TSC, синхронизированный тактовой областью, которая разделяется всеми ядрами и может отличаться от часов для любого одного ядра. Следовательно, должен быть какой-то буфер, когда основной TSC считывается RDTSC (или RDTSCP), работающий в ядре. Например, MSR_PLATFORM_INFO [15: 8] может быть установлен на 25 в пакете, каждый из которых синхронизирует TSC с тем, чтобы не увеличивать TSC на 25, есть PLL, который умножает часы шины на 25 и передает эти часы каждому из сердечников в такт их локальный регистр TSC, тем самым синхронизируя все регистры TSC. Итак, чтобы сопоставить терминологию с фактическим оборудованием

  • Постоянный TSC реализуется с использованием времени внешней шины, работающего на частоте 133,33 МГц, которое умножается на постоянный множитель, указанный в MSR_PLATFORM_INFO [15: 8]
  • Инвариантный TSC реализуется путем сохранения TSC в каждом ядре в отдельной тактовой области
  • Non-stop TSC реализуется с помощью TSC без декодирования, которое увеличивается на каждые часы шины MSR_PLATFORM_INFO [15: 8]: таким образом многоядерный пакет может перейти в глубокое энергоснабжение (состояние C6) и может отключиться PLL... нет необходимости держать часы в более высоком мультипликаторе. Когда ядро ​​возобновляется из состояния C6, его внутренний TSC будет инициализирован значением uncore TSC (тот, который не заснул) с коррекцией смещения, если программное обеспечение записало значение для TSC, подробности которые находятся в патенте. Если программное обеспечение не писать в TSC то ТСК для этого сердечника будет вне фазы с другими ядрами, но при постоянном смещении (частота TSC часов все привязана к опорной частоте шины от постоянного множителя).

Ответ 3

RTDSC не синхронизируется между процессорами. Таким образом, вы не можете полагаться на него в многопроцессорных системах. Единственным обходным решением, которое я могу придумать для Linux, было бы фактически ограничить процесс запуском на одном CPU с помощью настроек его близости. Это можно сделать извне, используя утилиту taskset или "внутренне", используя sched_setaffinity или pthread_setaffinity_np.

Ответ 4

В этом руководстве, глава 17.12, описывается инвариантный TSC, используемый в новейших процессорах. Доступный с Nehalem этот штамп времени вместе с инструкцией rtscp позволяет считывать временную метку (не зависящую от состояний ожидания и т.д.) И сигнатуру процессора в одной атомной операции.

Говорят, что он подходит для расчета времени настенных часов, но, очевидно, он не ожидает, что значение будет одинаковым для процессоров. Заявленная идея заключается в том, что вы можете видеть, соответствуют ли последовательные чтения тем же самым часам процессора или настраиваются для чтения нескольких CPU. "Он также может использоваться для настройки различий между процессорами в значениях TSC в системе NUMA".

См. также точность rdtsc в ядрах процессора

Однако я не уверен, что окончательное согласование в принятом ответе следует из утверждения о том, что tsc можно использовать для настенных часов. Если бы это было согласовано, то какая была причина для атомарного определения источника ЦП времени.

N.B. Информация TSC перешла от главы 11 к главе 17 в руководстве Intel.