Обновить
32K+
555
Sergei Kushnirenko@dalerank

Люблю (ш)кодить, алгоритмы и старые авто.

220
Рейтинг
611
Подписчики
Отправить сообщение

Нужно, очень.

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

Когда у вас на E-core частота скачет от 100Мгц до 2Ггц вас мало что спасет, поэтому туда только таски, которым пофиг на задержки

Процессор при branch prediction спекулятивно читает данные ещё до разрешения условия, но результат спекулятивного load при page fault не коммитится в retired состояние и исключение откладывается до момента, когда ветка "станет настоящей", что не противоречит обычному исполнению, неважно прочитали вы нулл из обычной ветки или спекулятивной.
Но есть другой нюанс, что компилятор может использовать CMOVcc только если "доказал" что оба оберанда валидны

Ну обычно мы тут в игрушки играем :) И новомодные E-коры ведут себя крайне коварно начиная тротлить в самый неподходящий момент, если вы про это. Поэтому основные потоки все забинжены на P-ядра, а на E-отдается всякая мелочь, вроде подгрузки текстур, распаковки банков и т.д. На консолях можно выставлять желаемую частоту ядра, если очень хочется, но я таких изысков пока не встречал. Задается максимум для двух первых ядер, а остальные под ОС живут.

Компилятор может превратить это в CMOV

cmp keys[i], target
cmov result, values[i]

Но это не гарантия и может сделать так

cmp keys[i], target
jne skip
mov result, values[i]

сделав обычное ветвление, это тоже зависит от включенных оптимизаций, целевой архитектуры, вероятности ветки по собранной эвристике и стоимости операций в этом месте. А еще это зависит от данных, и если VALUES[i] требует загрузки из памяти, то предпочитаетс JNE именно потому что CMOV в этом случае всё равно должен загрузить значение до выполнения, и латенси памяти попадает в хотпас независимо от условия. То есть CMOV с load-зависимостью иногда будет хуже, чем ветвление и компилятор это знает.
CMOV условно перемещает значение из источника в регистр, но источник должен быть УЖЕ готов до выполнения, сам CMOV не может условно отменить уже начатую загрузку из памяти, а только условно записывает результат.

Мы не властны над легаси

тоже верно

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

Я могу сказать про игры, но думаю это будет справедиво для большинства софта. Свременные игры занимают 16+гб оперативки, но это это не значит, что процессор реально работает со всем этим объёмом, потому что юольшая часть памяти будет просто загруженные ресурсы (текстуры, модели, звуки, анимации и разные буферы). Из них 90% используются редко или вообще обрабатываются видяхой, а не процом.
Потом в каждый конкретный кадр процессор обычно крутится вокруг очень маленького набора данных вроде позиций объектов, состояний AI, параметров физики и тд. И такой рабочий набор занимает очень немного, по моим замерам на текущем проекте горячий рабочий сет занимает всего 5Мб на каждый гигабайт выделенных данных в общем, т.е. на 8Гб всей игры мы имеем 40Мб рабочего сета, который мы перевариваем каждый кадр.

Поэтому даже относительно маленький кеш процессора в 32кб и несколько мегабайт L2/L3 позволяет это дело прокачать. Потом весь этот горячий сет мы пытаемся положить максимально линейно, тут уже пофик на красивые абстрации и паттерны работы - поэтому у нас появляются компоненты ECS, хот секции физический тел и тп. Учитывая что проце загружает память сразу линиями, вместе с нужным элементом сразу подтягиваются его соседи. В итоге мы приходим к том, что следующие обращения уже попадают в кеш, поэтому, несмотря на гигабайты оперативки, в реальности мы почти всё время работаем с маленьким набором данных, и кеш отлично справляется с тем, чтобы держать этот коробку и мешок под рукой. А вот если этого не получается, тогда начинаются проблемы, но это уже совсем другая история.

Надеюсь я ответил на вопрос

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

Нет, барьеры не выталкивают данные в L2, как вы выразились. smp_wmb() просто инструкция упорядочивания, которая гарантирует что все записи до барьера станут видны другим ядрам раньше записей после барьера. Это понятие только об относительном порядке видимости, и физические если вы откроете годболт там будет чтото вроде mfence или lock xchg, и все отложенные записи из store-буфера коммитятся в L1D конкретного ядра, а вот полетят ли они дальше в L2 вопрос. Ядро просто пометит свою копию как Invalid. Более того, L1D ядра1 может вообше отдать линию напрямую ядру2 через HITM, минуя L2, и изменения там появятся только когда ядро3 придет за этими данными, но там тоже есть особенности работы на старых Intel/Amd до 15года

Это не было темой статьи. Я вам больше скажу, обычный (широковещательный) snooping MESI нормально работает только на 2-4 ядрах. Если интересно больше технических деталей то можно вот это почитать (https://habr.com/ru/articles/689310/), на 6–8 накладные расходы уже соизмеримы и превышают время работы с переменной в L2. Но все зависит от паттерна работы, если вся работа в пределах одного ядра то проблем не будет, проблема начинается там, где есть write-sharing, когда несколько ядер пишут в одни и те же или соседние кэш-линии. Но даже на двух ядрах можно подложить себе граблей с false sharing, если два потока пишут в разные переменные, которые случайно лежат в одной кэш-линии. И тогда с точки зрения MESI они делят одну линию, и каждая запись одного ядра инвалидирует кэш другого, хотя логически данные вообще независимы. Это классическая грабля при написании многопотока, еслиatomic counter1 и stomic counter2 лежат рядом в структуре, то они почти гарантированно окажутся в одной кешлинии и будут постоянно пинговать друг друга между ядрами, но увидите и почините вы это очень не скоро, если увидите вообще.

есть такое, у знакомых на билдферме стоит пара Samsung PM9AX c 16гб кеша, но скажу что кардинально они картину не меняют, снижение времени сборки билда не стоит этих денег. Сам диск стоит как самолет и потом оказалось что дешевле было докупить 128Гб оперативки и развернуть в ней временный диск.

Хеоны у меня были в руках очень давно, но в числомолотилках, да еще под ICC скомпиленых они уделывали AMD и обычные гражданские версии не то, что на проценты - в разы в некоторых случаях, на GCC результаты были сильно скромнее. Но, это было в 2008.

Ну дядя Борман был известным приколистом в этом плане, на его багах я застал -Og, когда внутри функции делалась подфункция если некоторые части были одинаковые. И я бы никогда не знал про эту дичь если бы не странные краши, которые она порождала. Или -Ov, который пытался выносить переменные и инваринты из циклов. Или "фантастический" -Ob режим, который умел склеивать функции под капотом, что тоже добавляло отладки в ночи.

Благодарю, поправил на сигнал, так будет корректнее.

Могут, но это уже не ко мне вопросы :)

Ну вы же прочитали эту статью, она размещена в сети, написана с помощью пк и вызвала некоторый отклик у вас, раз вы решили написать комментарий. Вероятно с помощью смартфона. Разве ваш комментарий не реален? Музыка и игры тоже не имеют физических воплощений, но это не мешает им вызывать эмоции.

1
23 ...

Информация

В рейтинге
27-й
Откуда
Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Десктоп разработчик, Разработчик игр
Старший
От 300 000 ₽
Git
C++
Многопоточность
Прикладная математика
ООП