Операция выборки TSC процессора, особенно в многоядерной и многопроцессорной среде
В мире Linux, чтобы получить таймер / часы с точностью до нано секунд, можно использовать:
#include <sys/time.h>
int foo()
{
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
//--snip--
}
Этот ответ предполагает asm
подход к прямому запросу на часы процессора с RDTSC
инструкция.
В многоядерной, многопроцессорной архитектуре, как синхронизируются значения тактов / таймеров между несколькими ядрами / процессорами? Насколько я понимаю, что там в присущем фехтовании делается. Это понимание правильно?
Можете ли вы предложить некоторую документацию, которая объяснила бы это подробно? Мне интересны микроархитектуры Intel Nehalem и Sandy Bridge.
РЕДАКТИРОВАТЬ
Ограничение процесса одним ядром или процессором - не вариант, так как процесс действительно огромен (с точки зрения потребляемых ресурсов) и хотел бы оптимально использовать все ресурсы на машине, которая включает все ядра и процессоры.
редактировать
Спасибо за подтверждение того, что TSC синхронизируется между ядрами и процессорами. Но мой первоначальный вопрос: как выполняется эта синхронизация? это с какой-то фехтованием? Вы знаете какую-либо публичную документацию?
Заключение
Спасибо за все входные данные: Вот заключение для этого обсуждения: TSC синхронизируются при инициализации с использованием RESET, который происходит между ядрами и процессорами в многопроцессорной / многоядерной системе. И после этого каждое Ядро самостоятельно. TSC поддерживаются неизменными с помощью фазово-замкнутого контура, который нормализует изменения частоты и, следовательно, изменения тактовой частоты в данном ядре, и именно так TSC остаются синхронизированными между ядрами и процессорами.
4 ответа
На более новых процессорах (i7 Nehalem+ IIRC) TSC синхронизируется по всем ядрам и работает с постоянной скоростью. Таким образом, для одного процессора или нескольких процессоров в одном корпусе или на материнской плате (!) Вы можете положиться на синхронизированный TSC.
Из системного руководства Intel 16.12.1
Счетчик меток времени в более новых процессорах может поддерживать расширение, называемое инвариантным TSC. Поддержка процессоров для инвариантного TSC обозначается CPUID.80000007H:EDX[8]. Инвариант TSC будет работать с постоянной скоростью во всех ACPI P-, C-. и Т-состояния. Это архитектурное поведение, движущееся вперед.
На старых процессорах нельзя полагаться ни на постоянную скорость, ни на синхронизацию.
Изменить: по крайней мере на нескольких процессорах в одном пакете или материнской плате инвариант TSC синхронизируется. TSC сбрасывается в ноль при /RESET, а затем идет с постоянной скоростью на каждом процессоре, без смещения. Сигнал /RESET гарантированно поступит на каждый процессор одновременно.
Прямо от Intel, вот объяснение того, как последние процессоры поддерживают TSC, который работает с постоянной скоростью, синхронизируется между ядрами и пакетами на многосетевой материнской плате и может даже продолжать работать, когда процессор переходит в состояние C глубокого сна. В частности см. объяснение Випина Кумара Е.К. (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 одновременно, когда вы включаете материнскую плату, все процессорные пакеты получают опорный тактовый сигнал от внешнего кварцевого генератора, а внутренние тактовые импульсы в процессоре находятся в фазе (хотя обычно с большим множителем, таким как 25x) с Схема называется фазовой замкнутой петлей (ФАПЧ). Последние процессоры будут синхронизировать TSC на самой высокой частоте (множителе), который оценивается процессором (так называемый постоянный TSC), независимо от множителя, который может использовать любое отдельное ядро из-за регулирования температуры или управления питанием (так называемый инвариантный TSC). Процессоры Nehalem, такие как X5570, выпущенный в 2008 году (и более новые процессоры Intel), поддерживают "безостановочный TSC", который будет продолжать работать даже при сохранении питания в C-состоянии с глубоким отключением (C6). Смотрите эту ссылку для получения дополнительной информации о различных состояниях отключения питания:
http://www.anandtech.com/show/2199
После дальнейших исследований я наткнулся на патент Intel, поданный 22.12.2009 и опубликованный 23.06.2011 под названием "Управление смещением счетчика меток времени (TSC) для многоядерных ядер и потоков".
http://www.freepatentsonline.com/y2011/0154090.html
Страница Google для этой заявки на патент (со ссылкой на страницу USPTO)
http://www.google.com/patents/US20110154090
Из того, что я понял, есть один TSC в uncore (логика в пакете, окружающем ядра, но не часть какого-либо ядра), который увеличивается на каждой частоте внешней шины на значение в поле регистра, специфичного для машины, указанного Vipin Kumar. по ссылке выше (MSR_PLATFORM_INFO[15:8]). Часы внешней шины работают на частоте 133,33 МГц. Кроме того, каждое ядро имеет свой собственный регистр TSC, синхронизируемый тактовым доменом, который совместно используется всеми ядрами и может отличаться от тактового сигнала для любого одного ядра - поэтому должен быть какой-то буфер, когда ядро TSC читается RDTSC (или RDTSCP) инструкция, работающая в ядре. Например, MSR_PLATFORM_INFO[15:8] может быть установлен на 25 для пакета, каждый тактовый генератор шины увеличивает значение uncore TSC на 25, есть PLL, который умножает тактовый сигнал шины на 25 и предоставляет эти тактовые импульсы каждому из ядер для тактирования их локальный регистр TSC, тем самым поддерживая синхронизацию всех регистров TSC. Таким образом, чтобы сопоставить терминологию с фактическим оборудованием
- Постоянный TSC реализуется с использованием тактовой частоты внешней шины, работающей на частоте 133,33 МГц, которая умножается на постоянный множитель, указанный в MSR_PLATFORM_INFO [15: 8]
- Инвариантный TSC реализуется путем хранения TSC в каждом ядре в отдельной области синхронизации
- Непрерывный TSC реализуется с помощью неосновного TSC, который увеличивается с помощью тиков MSR_PLATFORM_INFO [15: 8] на каждом тактовом сигнале шины, таким образом, многоядерный пакет может перейти в режим глубокого отключения (состояние C6) и может отключить PLL... нет необходимости держать часы на более высоком множителе. Когда ядро восстанавливается из состояния C6, его внутренний TSC инициализируется значением неосновного TSC (того, который не переходил в спящий режим) с корректировкой смещения в случае, если программное обеспечение записало значение в TSC, подробности которые находятся в патенте. Если программное обеспечение выполняет запись в TSC, то TSC для этого ядра будет не в фазе с другими ядрами, но с постоянным смещением (частота тактовых импульсов TSC связана с эталонным тактовым сигналом шины постоянным множителем).
В этом руководстве, глава 17.12, описывается инвариантный TSC, используемый в новейших процессорах. Эта временная метка, доступная в Nehalem, вместе с инструкцией rtscp позволяет считывать метку времени (не зависящую от состояний ожидания и т. Д.) И сигнатуру процессора за одну элементарную операцию.
Говорят, что он подходит для вычисления времени настенных часов, но он явно не ожидает, что значение будет одинаковым для разных процессоров. Заявленная идея заключается в том, что вы можете видеть, выполняются ли последовательные операции чтения на одном и том же тактовом сигнале ЦП или настраиваться на несколько операций чтения ЦП. "Его также можно использовать для корректировки различий между процессорами в значениях TSC в системе NUMA".
Смотрите также точность rdtsc для всех ядер ЦП.
Однако я не уверен, что окончательный вывод о согласованности в принятом ответе следует из утверждения о том, что tsc может использоваться для настенных часов. Если бы он был последовательным, то какой была бы причина для атомного определения источника времени процессора?
Примечание. Информация TSC перенесена из главы 11 в главу 17 этого руководства Intel.
RTDSC не синхронизируется между процессорами. Таким образом, вы не можете положиться на это в многопроцессорных системах. Единственный обходной путь, который я могу придумать для Linux, состоит в том, чтобы фактически ограничить процесс для запуска на одном процессоре путем установки его соответствия. Это можно сделать внешне используя taskset
утилита или "внутренне", используя функции sched_setaffinity или pthread_setaffinity_np.