Pull to refresh

Comments 68

А если это не базы данных, а рендеринг или другие вычисления?
Мне кажется у вас почти вся статистика о базе данных, где не столько CPU, сколько траффик. Трафик связанных как со storage так и памятью. Кроме того траффик, связанный со storage/network вообще может косвенно нагружать CPU (kernel space ибо драйвера).

Можете уточнить как именно вы меряли?

Я связан с базами, а рендерингом чуть менее чем никак) и на базе тоже может быть CPU если на стороне сервера много бизнес логики

и на базе тоже может быть CPU если на стороне сервера много бизнес логики

Так хотелось бы понять, если это будет вычисления бизнес логики, то тоже будут именно такие 50% CPU?

Если ОС выполняет много процессов параллельно, то понятно что system usage для переключения будет занимать определенный процент, который явно больше, чем если у нас несколько процессов.
Если ОС выполняет множество операциый связанных с IO, то там большой процент завязан на работу с устройствами. В Линукс это может считаться как CPU LOAD, в Windows не подскажу, но это тоже часть CPU LOAD которую будут возлагать на драйвера, а не IDLE
Поэтому и хотелось больше технических деталей о том как проводилось тестирование, типы данных, типа тестов...

В современном мире вообще performance тестирование, если начинаешь копать, и обнарживаешь количество подуровней различной виртуализации и хардварной оптимизации, которую нужно учитывать, то можно застрелиться....

Это был тест на живую) на prod server. Данный сервер cpu-bound а основном, много логики на функциях и они жрут cpu

В Линукс это может считаться как CPU LOAD, в Windows не подскажу, но это тоже часть CPU LOAD которую будут возлагать на драйвера, а не IDLE

В Windows загрузку CPU берут со счетчиков ядра для Performance Monitor, а там есть отдельные счетчики не просто для kernel time, но и для частей ядра - interrupt time (обработка прерываний) и DPC time (это процедуры отложенного вызова, асинхронщина ядра, по большей части они тоже для ввода/вывода т.к. он в Windows целиком асинхронный). И иногда это разделение полезно: например большой interrupt time% - это явный признак неисправного устройства, которое генерит прерывания как не в себя.

И, вообще-то даже Диспетчер задач несложно заставить отображать время ядра кроме общей загрузки процессора.

В современном мире вообще performance тестирование, если начинаешь копать, и обнарживаешь количество подуровней различной виртуализации и хардварной оптимизации, которую нужно учитывать, то можно застрелиться....

Я пришел к выводу что в современном мире имеют смысл только две метрики скорости работы. Скорость работы конкретной чистой функции или алгоритма без IO. И скорость работы всей системы целиком при типичной нагрузкой. Сумма времен ответов сервера на типичной нагрузке или средний fps игры для стандартного маршрута в ней.

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

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

Если важно время ожидания конкретного запроса - конечно надо смотреть на всяческие персентили.

А если это не базы данных, а рендеринг или другие вычисления?

Рендер by design рассчитан на 100% загрузку cpu/gpu. Разумеется все зависит от движка и эффектов и на практике далеко не всегда работает с полной загрузкой. Если ограничить движок 1 ядром - кадр будет считаться быстрее за счёт boost, но лучше медленно считать 8 кадров разом чем быстро 1.

Во-первых, 100% загрузка CPU и GPU невозможна. Во-вторых, параллельно несколько кадров никто не считает.

Во-первых, 100% загрузка CPU и GPU невозможна

А какая возможна? 99.9?...

Во-вторых, параллельно несколько кадров никто не считает.

Запрещено законом? Неэффективно? Не знаю, у меня multiframe rendering включён.

А какая возможна? 99.9?...

Если у вас CPU загружен на 100%, то GPU простаивает и наоборот

Запрещено законом? Неэффективно?

Да, синхронизация нарушится

Про всю эту тему был давно отличное видео

для VR очень даже надо рендерить два кадра одновременно.

VR, КМК, это немного другая история потому что между двумя кадрами разница только в позиции камеры. Но как там работает рендер я если честно не знаю.

Возможно вы говорили про игры а я про "рендер или другие вычисления"?

Если у вас CPU загружен на 100%, то GPU простаивает и наоборот

Если речь про рендер - в качестве простого примера опровергающего ваши слова могу привести

  1. кодирование последовательности jpeg2000 - хорошо параллелится, успешно считается и на gpu и на cpu, загружает и то и то на 100%

  2. upscale видео с применением нейронки

  3. любая задача на чистый gpu рендер станет чуть быстрее с подключением cpu и даст 100% утилизацию

Но есть нюансы

самая частая причина не подключать cpu - заметная на глаз разница между кадрами рассчитанными на gpu и cpu;

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

При большом разрыве производительности (например 6 карт и слабый проц) тоже считают на чистом gpu.

Возможно вы говорили про игры а я про "рендер или другие вычисления"?

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

Согласен, в играх все работает не совсем так. Может быть это профдеформация, но я не предположил что в обсуждении статьи про сервера уровня "256 - 1 - 2Tb RAM и 40-48 cpu" может зайти речь про игровой рендер. Даже если бы вы упомянули например Unreal Engine - я бы не догадался что речь про игры.

Когда непонятно, можно спросить

UFO just landed and posted this here

Мне кажется, что на базах данных вообще самое узкое место - доступ в память. В СХД вообще процессор не главная характеристика. Жаву с ёё библиотеками тянет и ладно.

Однажды напоровшись на схожую картину отключили гипертрединг на уровне приложения (благо плюсы позволяют), и вешали нагрузку только на физические ядра - иначе p99 начинал скакать как не в себя при нагрузке выше 70% cpu. Выбрали стабильность. Не представляю как нужно разложить обработку данных чтобы гипертрединг делал что-то полезное, когда он действительно становится нужен.

Вообще 50% это как-то маловато (но возможно и справедливо). Из того что видел - около 85% на практике это потолок, дальше непонятные спайки и перегрев

На мощных задач он только мешает. И если уж стали жить с HT, то надо учитывать что с 60% начинается деградация сервиса. И это всё уже описано, все эти рекомендации по отключению всех этих оптимизаций на тяжёлых серверах.

отключили гипертрединг на уровне приложения (благо плюсы позволяют)

Это как? Может, просто задействовали число потоков, равное числу физических ядер?

Отчасти: через cpu_affinity перестали прибивать потоки к гипертредным ядрам. Ну и да, по факту это ограничило количество cpu-bound потоков количеством ядер (были еще не-cpu-bound, которых по сотне на ядро лежало)

Нюанс в том, что при включенном гипертрединге некоторые ресурсы CPU (скажем, reorder buffer) статически делятся между логическими ядрами, так что один поток на ядре получает меньше, чем при выключенном HT.

Мы пробовали отключать ht через конфигурацию ядра - это не оказывало существенного влияния на производительность на наших задачах (оценка была методом "ну латенси и загрузка cpu вроде такие же". Перезагружать после этого тоже пробовали :D ). Так что в итоге оставили включенным для большей гибкости.

пробовали отключать ht через конфигурацию ядра

Вообще то оно в BIOS включается/выключается. Ядро линукса может скрыть дополнительные логические ядра процессора, но на разделение ресурсов это не влияет.

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

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

Пустите майнер во второй поток, чтобы постоянно проц прогревал)

Зеоны умеют бустить отдельные ядра. А нагружать майнером все ядра - плохая идея.

Да и не все зеоны умеют бустить проц целиком. У многих старых зеонов до максимальной частоты может добраться только одно ядро. Как на новых - не знаю.

Я однажды у себя в ПК так отказ вентилятора на процессоре увидел - он и до того работал неслышно, а тут резко заклинил, что тоже неслышно. Мое внимание привлекло, что что-то компьютер на тех же задачах стал тормозить и жрать много процессора. Причина - тот самый пропуск тактов из-за перегрева.

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

Насколько я знаю, лимиты питания срабатывают и без перегрева

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

Ну вас ещё много открытий впереди, осталось как минимум почитать статью Б. Грега, где он объяснит, что то, что многие привычно видят как нагрузку на процессор, на самом деле является его простоем.

Ну я писал тоже писал про ожидания памяти. Вот интересно, под виндой можно увидеть те же характеристики как автор пишет про Linux?

Насколько мне кажется, под Виндой в среднем можно увидеть больше, так как винда собирает чуть больше метрик по дефолту, чем Линукс. Но и тратит на это больше cpu. Условно запустить и остановить 1000 мелких процессов - на Линукс займет меньше времени, чем на Windows.

В Линуксе без спец средств посчитать что-то на уровне что именно делал процессор в течение секунды - нереально. Слайсы выделяемые на процесс 10-15 мс, максимум что можно попробовать посчитать. Но точно ли процесс свой слайс загрузил по полной или частично - уже вообще несчитаемо. Надо ядро перекомпилировать с какими-то отладочными вещами, которые естественно сами по себе будут нагружать.

Вот только хотел про это написать, опередили :-)
Делал презентацию нащим менеджерам на прошлой неделе, они не понимают что такое throttling cpu. В современных кубернетесах можно хорошо так загубить производительность если не понимать как проц слайсится.

Делал презентацию нащим менеджерам на прошлой неделе, они не понимают что такое throttling cpu.

А зачем им это понимать? Или менеджер - это CTO?

У нас нет СТО, у нас board of architects, только они уже меньше тех вопросами занимаются чем принято считать. С менеджерами "которым не нужно понимать" технические детали инженер у нас даже не разговаривает.
Вообще-то это тема важная, потому что одни могут соптимизировать расходы на cloud инфраструктуру, а другие сделать более оптимальныйи красивый дизайн и развеску нагрузок.
Хотя это всё тема другой большой дискуссии...

А действительно, что такое "throttling cpu"?

Это не тот тепловой throttling что на ноутбуках :-)
Вот тут например люди постарались и разложили по полочкам: https://www.datadoghq.com/blog/kubernetes-cpu-requests-limits/
Хотя я больше был под впечатлением от одного доклада с недавней конференции, там как раз про типичные ошибки в выставлении лимитов было, и я по возвращении презентовал идеи коллегам.

Сходил, почитал. Словосочетание "throttling cpu" не увидел.

Жаль что параметры memory cache misses можно измерить только специальным оборудованием с платы

Есть специальное приложение от известного производителя процессоров. В линуксе есть perf

Если у вас на машине стрелочка показывает, что у вас осталась половина бака, то у вас точно осталась половина бака? На самом деле больше,

Мой опыт показывает, что на самом деле меньше. По крайней мере, на старых машинах очень часто заправляешь машину, очень долго ездишь на первой четверти бака, а то и вообще "не тратя бензин", а потом, когда остаётся половина, бензин начинает расходоваться очень быстро.

…, а потом, когда она на нуле, можно проехать ещё полсотни километров )

Кстати, прыгая тут по ссылкам только что нашёл очень интересное эссе про метод анализа подобных систем, где производительность деградирует при высокой утилизации - https://www.brendangregg.com/usemethod.html

Из серии "они забыли больше, чем мы когда-либо знали".

Есть ещё один кейс когда 50% не 50%.
Столкнулся недавно с подобным на Azure Managed SQL, так там ещё прикольнее вышло. Есть такая B-серия у них, в описании написано:

Семейство виртуальных машин серии «B» - это один из экземпляров виртуальных машин общего назначения в Azure. В то время как традиционные виртуальные машины Azure обеспечивают фиксированную производительность ЦП, виртуальные машины серии B - единственный тип ВМ, использующий кредиты для предоставления производительности ЦП. В виртуальных машинах серии B используется модель кредитов ЦП для отслеживания количества потребляемого ЦП - виртуальная машина накапливает кредиты ЦП, когда рабочая нагрузка работает ниже базового порога производительности ЦП, и использует кредиты при работе выше базового порога производительности ЦП, пока все кредиты не будут израсходованы. Когда все кредиты ЦП израсходованы, виртуальная машина серии B возвращается к базовой производительности ЦП до тех пор, пока не накопит кредиты для повторной загрузки ЦП.

А так же уточняется что для БД небольшого размера (прям как у меня) это отличный вариант, но как водится детали не менее важны.

Скрытый текст

Оказалось что "порог производительности ЦП" это не 100% от моего купленого vCPU а 20% от его возможностей, из которых к слову около 17% кушают встроенные сервисы подсчёта этих кредитов. И когда нагрузка в среднем была мои 2% + 17% сервисы азура, то всё было более менее не плохо, а как только моей нагрузки стало 4% ядра то кредиты закончились за 2 дня и теперь задачи по крону которые выполнялись за 1 минуту каждые 5 минут стали выполняться 12 минут (запуск всё ещё каждые 5 минут). Вообщем на будущее читайте внимательно про условия тротлинга (к слову для Азура это не применимо, я специально искал где написано про эти условия и я этого не нашёл для своего арендованого сервера)

Нет, спасибо, мне троттлига по диску хватает)

В AWS и Azure почти все типы инстансов считают vCPU как поток в HT, а не ядро PCPU.

я уверен, что базы данных - самые ужасные программы с точки зрения cache misses

Ну, нет. Всякая вычислительная математика и физика, от прочностных расчётов в солидоле до не знаю там процессов теплопереноса в двигателях и атомных реакторах (hydroflow, logos, etc). Там в конечном счёте задачи сводятся к решению гигантских СЛАУ (систем линейных уравнений), где каждая дополнительная точка "разрешения" это дополнительная переменная в СЛАУ. Собственно, рейтинги суперкомпьютеров не зря меряют тестом LINPACK, который как раз эти СЛАУ и решает.

Каждая точка зависит только от нескольких своих соседей. Хорошо реализованный алгоритм читает каждую точку из памяти один раз за проход и потом один раз за проход записывает. Т.е. кэш на этом этапе как бы вообще в холостую работает. Но это полбеды.

Дальше, огромная матрица СЛАУ режется на прямоугольные куски, каждый из которых отдаётся своему процессору. Пока процессоров относительно немного, скорость вычислений упирается в их производительность. Проблема в том, что процессоры, обрабатывающие соседние куски матрицы, должны синхронно обмениваться свежими результатами на границах кусков. И хотя на первый взгляд объём "границ" линеен против квадратичного объёма содержимого "кусков", но на самом деле он также линеен относительно количества процессоров. Поэтому, начиная с некоторого количества CPU общая производительность упирается уже в межпроцессорные передачи и те самые кэши L2/L3 и их инвалидацию.

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

Из всех прямоугольников заданной площади минимальным периметром обладает квадрат.

И да, если уж резать на полосы, тогда эффективнее на горизонтальные. Тогда границы хотя бы будут лежать в ОЗУ одним непрерывным куском, который читать-писать намного быстрее, чем по одному слову памяти (16 байт) вертикальных границ.

Собственно, рейтинги суперкомпьютеров не зря меряют тестом LINPACK

LINPACK как раз таки достаточно эффективен в плане количества вычислений на один доступ к памяти и флопсы, которые он показывает, достаточно близки к теоретическому максимуму (что видно в данных Top500). Но реальный код да, очень часто memory bound (и LINPACK - не такая уж адекватная оценка, но лучшего не придумали).

Хорошо реализованный алгоритм читает каждую точку из памяти один раз за проход и потом один раз за проход записывает.

С точки зрения математического описания алгоритма входные точки зачитываются несколько раз для расчёта разных выходных. Чтобы минимизировать чтение из DRAM и приблизиться к идеалу "зачитать один раз", как раз таки и нужны кеши (и написанный с их учётом алгоритм).

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

Есть ещё более медленный обмен между нодами в кластере. LINPACK'у и это не так страшно, но в реальной жизни часто затраты на обмен между узлами сравнимы с вычисленияим на узле.

Жаль что параметры memory cache misses можно измерить только специальным оборудованием с платы

про кэшмиссы и даже всякие миспрефетчи запросто расскажет процессор, если его попросить. например, дефолтный линуксовый perf (c -e cache-misses,cache-references), или какой-нибудь vtune все покажут и расскажут.

если хочется прям совсем глубоко- то можно накостылять свое поверх intel processor trace. очень удобная штука для отладки многопоточщины.

Это Вы ещё про cgroups, CPU shares и контейнеры не знаете

и, кстати, с учетом скорости современных NVMe - не быстрее ли прочитать такую страницу с диска а не с соседнего NUMA? Честно, не знаю

Нет, конечно же. Задержки обращения к памяти соседей ноды numa сотни наносекунд, лучшие задержки накопителей — десятки микросекунд. Разница на два порядка.

И да, где гарантии того, что накопитель не окажется на другой ноде?

Поэтому, на hyperthreaded серверах "вторые" 50% cpu - это чистый обман

А вот и нет. Как раз нагрузка с большим числом ожиданий, о которой вы пишете выше, идеальна для SMT. Пока одно виртуальное ядро ждёт данных от памяти, второе на том же железе что-то исполняет.
У IBM в процессорах давно есть не только SMT2 (то, что Intel называет hyperthreading), но и SMT4 и даже SMT8.
Слухи о том, что и в x86 появится SMT4, ходят давно, но пока не складывается. Возможно, дело в том, что и так упёрлись в потребление/тепловыделение, повышать утилизацию жрущих блоков процессора бессмысленно. А может быть для эффективного использования надо наращивать регистры/кэши, что оказалось накладно и/или технически сложно.

Тут какбы большой вопрос откуда дровишки, и не связано ли увеличение времени с тем, что узкое место образуется где-то например по дороге к памяти. В этом случае HT наоборот как мана небесная. Кстати, линейная зависимость времени от загрузки без перегиба в районе 50% свидетельствует именно об этом. Если бы это была положительная обратная связь внутри камня, функция, была бы более быстрорастущая, чем линейная.

Беда автора, что у него не откалибрована сложность материала. Пишет, мол, простите за очевидные вещи, а потом начинает тарабарить. Я могу из общих соображений догадаться, что такое PAGELATCH, но я не знаю, что такое NUMA и как-то смутно представляю себе BUFFER POOL. При этом я долго работал с MS SQL и как раз поэтому не очень хорошо представляю себе, что там сейчас творится на низком уровне.

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

Тогда о какой очевидности речь?

PAGELATCH, BUFFER POOL и прочие умные слова сюда притащены для того чтобы завалить читателя терминологией и отвлечь его от главной проблемы текста - в нём нет доказательства что дело сублинейного роста именно в тех причинах, о которых нам вещает автор.

Хохму с дракой за спинлоки я помню ещё в районе 2000 года. Сервер БД для хостинга поставили на MySQL на Linux, и увидели, что если в локи входят несколько одновременно клиентов, то их процессы начинают только и делать, что крутиться в ожидании освобождения, и в результате зависимость квадратичная от количества вошедших. Лечить это в коде мы тогда не могли, и мистическим образом улучшение настало от перевода на FreeBSD, где треды были сделаны на libc_r, старой и кривоватой, которая реально один системный процесс с переключением в юзерленде - и это работало лучше! Исправление наступило года через два с новыми версиями всего.

Реально такие нелинейные росты это основная проблема любой загрузки чего-то.

и, кстати, с учетом скорости современных NVMe - не быстрее ли прочитать такую страницу с диска а не с соседнего NUMA? Честно, не знаю

NVMe диск - это небольшой компьютер, только CPU, RAM у него хуже, проще, дешевле чем у соседа по сокету. В десятки раз. Пропускная способность 4x PCI-e в десятки раз меньше интерконнекта. Мощнее не особо нужно, потому что flash медленнее DDR раз в 100.

А вот для менеджеров, например, которые планируют ресурсы, это может быть открытием.

манагеры не поймут то что тут написано.. не таким языком.

Sign up to leave a comment.

Articles