Pull to refresh

Comments 64

Интересно, а как с этим у джавы?
И у других языков?
Да, очень интересно было бы посмотреть на подобное исследование по другим языкам. Скажем, Java и Gо — как другие представители популярных языков, где рядовые разработчики часто не задумываются, как оно живет «под капотом».
где рядовые разработчики часто не задумываются, как оно живет «под капотом»

Блаблабла, сейчас столько фреймворков, что почти всем пофигу как оно живет под капотом.

до тех пор, пока из-под капота дым не пойдет в виде замедления работы.

Дым и замедление..? У вас туго с логикой!

А вы таки думаете машина едет быстрее, когда у неё загорается двигаетль?
«Если вы покупаете новейшее железо, то получите процессор с архитектурой Skylake.»
Прошу прощения но с телефона (из приложения) не понятно это перевод или нет?
Сейчас 8 поколение — CoffeLake, а Skylake это 6.
Думается сейчас ситуация уже должна измениться, или нет?
UFO just landed and posted this here

Микроархитектура у Intel не менялась со времени выхода первого Skylake для ПК: Skylake 6xxx — Kaby Lake 7xxx (14nm+) — Cofee Lake 8xxx (14nm++, 6 ядер в настольном сегменте)
Серверные процессоры: Skylake-X и Skylake-SP (заменили кольцевую шину на меш). Только лишь на конец года намечен преемник — Cascade Lake.


https://en.wikichip.org/wiki/intel/cores/skylake_sp

На самом деле даже архитектура не имеет значения — это изменение Intel сделал по каким-то своим соображениям специально, а значит в следующих архитекутрах (скорее всего) будет повторять.
Предположу, что это сделано для того, чтобы иметь большую возможность распоряжаться ресурсами во время wait-а.
Если как сказано выше «спиннинг начинается с 50 вызовов паузы» — так почему бы грубо говоря вместо 50 не сделать 1 вызов? Зачем возвращаться?
Наверное, решение правильное, если вовремя поддержать это производителями софта.
И на мой взляд проблема всё-таки в .net. Почему 50, а не 42? Они делают какие-то допущения о длительности паузы, вместо того, чтобы проверить, сколько реально прошло (чтением tsc, например). Вполне возможно, что длительность паузы в будущих процессорах вообще станет динамической, в зависимости от состояния конвеера на других логических ядрах.
А как узнать, что прошло N квантов времени? Для этого нужно прерваться и сравнить. Будете слишком часто прерываться — производительность упадет. Будете слишком много вычислять во время спинлока — производительность упадет.
Плюс, предположу, что сам по себе получение текущего времени — обращение к ядру. Так зачем тогда спинлок?
Вообще, эта задержка должна легко вычисляться при старте программы. Видимо, не ожидали.
Инструкция процессора такая есть — rdtsc, в большинстве ОС доступна в user space. Ничего прерывать или обращаться к ядру не надо.
спасибо, не писал на ассемблере(и не интересовался новыми инструкциями) со времен 486.

Но все равно, 50 раз уснуть — это намного проще, чем уснуть, прочитать, сравнить… и не задействует ценные блоки процессора. А нужное количество тактов можно и при старте посчитать.
Плюс, интересно, что это значит: «Точные замеры могут быть невозможны при однократном исполнении измеряемого фрагмента инструкций из-за влияния кэшей процессора при обращении к памяти. Традиционно решается многократным измерением фрагмента программы или повторением измеряемого фрагмента в цикле.» Если оно может слишком рано выйти из спинлока — думаю, это не очень страшно. А если слишком поздно (тем более — если неограниченно поздно) — могут быть проблемы.
С rdtsc тоже всё не просто. 1. Это счётчик циклов в процессоре с плавающей частотой. Вы получите такты а не циклы. 2. Это счётчик конкретного ядра. Если ОС перебросит вас на другое ядро, то вы получите совершенно другой счётчик, он может быть как больше так и меньше. 3. Не помню его битности но лично сталкивался с его переполнением на долго работающих машинах, да и вообще с уровня драйвера в него писать может кто угодно что угодно, во всяком случае на CORE2 архитектуре, когда я этим занимался, мы случайно набажили в драйвере и вместо считывания писали туда нули на каждом переключении контекста, что удивительно ничего не ломалось.
ну, переполнение — не страшно в данном контексте. А вот прочитать данные из другого ядра — это может все сломать и вместо нескольких сотен тактов процессора прождете пол-дня.

А расскажите пожалуйста, где сейчас востребована эта магия? Можно ли по удаленке устроиться? А то иногда хочется чуть большего, чем в спринге аннотации развешивать.
Студенческий проект по разработке профилировщика. Performance countres, хук swapContext в винде xp. И собирали метрики о кешмиссах и прочих тормозных ситуация в проце. Хукать надо потому что эти счётчики считают метрики просто по ядру и ему пофиг что там задачи переключаются.
да, в школьные и студенческие годы чего только не писал. Жаль, тогда знаний не хватало. Зато свободного времени и желания изменить мир было хоть отбавляй.
1. Такт и цикл это синонимы. Что вы имеете в виду? Если вы про то, что процессор может уменьшать или увеличивать частоту, то это не приводит к тому, что иногда время измеряется быстрее, а иногда медленней — возвращаемое число тактов имеет константный интервал. Т.е. rdtsc игнорирует состояния энергосбережения процессора.
2. Нет, на современных процессорах счётчики синхронны между ядрами. Поэтому rdtsc предлагают иногда в качестве замены ACPI и HPET, т.к. накладные расходы минимальны.
3. Его разрядность 64 бита. Не знаю, что у вас за машины, но 2^64 / 3 giga / 60 / 60 / 24 / 365 даёт результат в 194980805785024010823 лет для его переполнения.
Как это вы его изменяли, если его невозможно изменить и есть только инструкция считывания? Его может сбросить только перезагрузка ПК.
Дело было в 2007 году примерно, тогда точно на CORE 2 разные на разных ядрах были. Про переполнение опять же дело было на 32х битных ОС. Может только половинку его читали. Деталей точно не припомню, но у интела есть специальные регистры для снятия метрик производительности, количество фейлов бранч предиктора, кешмиссов и тп. И эти штуки из драйвера можно настроить. Мы делали профилировщик и на swapContext снимали метрики всякие. И тогда при ошибки получили обнуление TSC.
И да такты и циклы попутал, имелось ввиду конечно такты а не время.

1, 2. Насколько я помню, RDTSC уже давно является таймером, а не счётчиком циклов, причём синхронизированным между ядрами. Точнее, это зависит от режима работы процессора.


The time stamp counter in newer processors may support an enhancement, referred to as invariant TSC. Processor’s support for invariant TSC is indicated by CPUID.80000007H:EDX[8]. The invariant TSC will run at a constant rate in all ACPI P-, C-. and T-states. This is the architectural behavior moving forward. On processors with invariant TSC support, the OS may use the TSC for wall clock timer services (instead of ACPI or HPET timers). TSC reads are much more efficient and do not incur the overhead associated with a ring transition or access to a platform resource.

 3. Да пускай переполняется, нас же разница интересует, а не абсолютное значение.

Хм интересно, а как теперь именно такты померять? Для некоторых вещей в тактах как раз ценнее инфа чем в абсолютном времени.

Главное не оказаться в ситуации, когда rdtsc доступна, но виртуализована, т.е. один вызов rdtsc превратится в несколько сот тактов из-за обращения к гипервизору.

Вычисление паузы — проходили уже, когда программы на паскале с модулем crt (любые с цветным выводом в текстовом режиме) в конце 90-х начали вываливаться при запуске с делением на ноль. Скорость вычисляли. И тоже при этом "не ожидали". Нет в мире совершенства.

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

Планка может быть и не 50. Это значение явно было выбрано из каких-то формальных оценок (скорее всего, энергопотребления), не учитывающих скайлейки. Ну, бывает, поставят 5-10 и будет всё почти как раньше.
На серверный рынок Skylake попал с значительным опозданием. У крупных производителей модели начали появляеться в прошлом году только. Intel Xeon Scalable Gold/Platinum основан на Skylake микроархитектуре. Более новых процессоров пока нет.
Меня другое интригует — я себе стац в конце 2015-го собирал на самых-самых первых Skylake, какие только появились на Amazone. А тут речь ведут про:
на последних процессорах, которые выпускались с середины 2017 года,

И как это понимать то? Автор допустил ошибку или смена (микро-изменение) логики вышла позже, чем я железо себе сменил?
Тут речь о серверных процессорах, там обновление архитектуры со значительной задержкой происходит, когда домашние хомячки закончат бета-тест за свой счёт.
это изменение Intel сделал по каким-то своим соображениям специально

А потом уберут и всем будет хорошо. )
Сделай плохо и затем верни как было )
Ну ни фига себе. На амд такого нет?
И ведь проблема как я понял будет везде где есть эта инструкция.
Больше ядер хороших и быстрых.
На амд такого нет?

As I said before – AMD has a different latency, so it’s an issue with a software in the first place.
Bulldozer – 50
Zen – 10
Jaguar – 50
Pretty big difference from pre Skylake architectures

Я правильно понимаю, что проблема только с кодом, который много и часто ждёт освобождения Critical Section?
Если да — можно выдохнуть: такой код всё равно оставлять нельзя (надо уменьшать периоды локов или переходить на lock-free структуры данных). Ну и MS, опять же, заткнул со своей стороны.

MS звткнул — другие не заткнули, есть ещё унаследованный код, есть AMD с другими временами, есть более старые процессоры с другими временами.
Тоже согласен что к многопоточному программированию лучше так не подходить, один раз подождал блокировку и получил огромную пачку данных для работы, а не каждый раз ждать небольшую порцию.

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

К сожалению, не всякая вычислительная задача укладывается в подобную парадигму. В некоторых задачах требуется обмен информацией между потоками в малых объёмах с низкой задержкой и высокой частотой.

кстати данная статья как раз доказывает что C# это не про производительность и что бы торговые роботы не сорили деньгами их нужно писать на C/C++/Asm/Go

а с чего вы взяли что под капотом примитивов синхронизации в c/c++/go не используются те же самые спинлоки на тех же самых инструкциях паузы?
UFO just landed and posted this here
авторы торговых роботов за каждую микросекунду воюют, а вы предлагаете подождать пачку…

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

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

Если я правильно понимаю, то это как раз тот случай, когда gpu в разы быстрее делают работу cpu за в разы меньший прайс? Может, тогда им это и предоставить?

Вообще GPU это процессор для графики, на него лучше грузить задачи по отрисовке. Можно сказать что тут нужен баланс загрузки ресурсов.

любые хорошо распараллеливающиеся вычисления с плавающей точкой имеет смысл вычислять на GPU. Включая ту самую физику коллизий (PhysX, например), машинное обучение, майнинг и много чего еще

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

Сорян, не туда отвелил, ответ выше, про роботов ((=

удивительная история, спасибо за расследование. как будто уже сталкивался с таким. а как дела обстоят под виртуализацией? по идее тоже должно воспроизводится.
: ) Тоже заметил!

сделал замер в mono (linux) на AMD Ryzen, проблем нет:


rinat@linuxmint-desktop ~/SkylakeXPause/SkylakeXPause/bin/Release/net45 $ mono SkylakeXPause.exe -check
Did call pause 1 000 000 in 0,8401 ms, Processors: 8
No SkylakeX problem detected
Если бы я мог, то попросил бы Microsoft портировать инфраструктуру ETW на Linux, потому что текущие профайлеры в Linux по-прежнему отстойные. Там недавно добавили интересные возможности ядра, но инструментов анализа вроде WPA до сих пор нет.

Бесспорно, WPA — неплохой профайлер для Windows, но не единственный, а из статьи создается впечатление, что без него прямо никак. Автор оригинального текста сильно не в курсе про профайлеры под Linux.
UFO just landed and posted this here
На Windows он бы выгдядел как спин-локи в топах объектов ожидания, и соответственно, стеки вызовов функций синхронизации. Но в WPA выглядит красивее, т.к. VTune не инструментирует .Net API и не покажет, например, Sender/Worker.
У ETW/WPA только один недостаток — нет микроархитектурных данных. Иногда нужно видеть зарежки при доступе к памяти, проблемы с предсказанием ветвлений.
Как исправить
D:\SkylakeXPause\SkylakeXPause\bin\Release\net45>SkylakeXPause.exe -check
Did call pause 1 000 000 in 62,6168 ms, Processors: 4
SkylakeX CPU with unpatched .NET Framework detected.

последние патчи и фреймворк стоят
винда 10 домашняя
Спасибо. Тоже заинтересовался данным вопросом.
С ценовой политикой Intel и «жвачкой» в процессоре за 2,5k$ для декстопа Core i9 решил перейти на AMD Threadripper
Sign up to leave a comment.

Articles