last day (15 days later) » 

13:39
8
A: Ключевое слово volatile в C

HolyBlackCatvolatile заставляет компилятор не оптимизировать запись/чтение в переменную (не заменять ее на регистр а всегда писать в оперативную память, читать и писать ровно когда сказали, ...). Если вы программируете какую-то железку, где запись по специальным адресам в памяти вызывает какие-то специальные...

а чем поможет атомик, если проц в конвеере команды [инструкции] переставляет как хочет? особенно недо-проц, под архитектурым названием арм
@InterceptorTSK Я не железячник, допускаю что чего-то не знаю. И что, как на ARMе живут с такими перестановками? Наивно кажется, что перестановки на уровне конвеера не должны влиять на поведение программы.
"И что, как на ARMе жить с такими перестановками?" строго однопоточно) справедливости ради интел тоже слегка меняет инструкции, но на это можно влиять, именно потому на интеле можно играть в многопоток, а на арме - нет, всё нужно тотально берьерами обвешивать, недопроц жеж
чюдеса случаются - и это так) берёте 12 ядер недо-арма, а в многопоток вменяемо поиграть не получится, всё завязнет в тотальном оверхеде - это ли не чюдо чюдесное чюдесатое?
avp
avp
Еще volatile запрещает компилятору переставлять в коде операции с ним (именно в этом смысле volatile используется с ассемблерными вставками)
@InterceptorTSK, imho странные наезды на arm (может конкретный пример что именно у вас не получилось приведете?) (кстати, про atomic и барьеры. Atomic (в зависимости от архитектуры заставляет компилятор вставлять в код барьеры))
@InterceptorTSK Так я ж написал, что volatile не для многопоточки; для многопоточки - атомики. Поделитесь, что у вас за опыт был с многопоточкой и армами?
13:39
@avp "Еще volatile запрещает компилятору переставлять в коде операции с ним (именно в этом смысле volatile используется с ассемблерными вставками)" - и не только в ассемблере, в дот-нете такой же принцип, всё то [почти всё] что перед volatile - не меняется как угодно, но! в интеле сам проц не позволяет [почти не имеет такой возможности] изменять последовательность инструкций, а значит лишних ограничивающих телодвижений компилятор под интел не нагородит, а вот на арм - нагородит по полной
@HolyBlackCat суть в обратном, как в многопотоке не использовать ни атомики, ни volatile, и при этом, если подходить к коду аккуратно - интел позволяет [почти позволяет] без этого жить, а вот арм этого не позволит, всё утыкивается массово разнообразными "синхронизаторами" - в этом суть
@InterceptorTSK как в многопотоке не использовать ни атомики. Ну, понятно. Сперва пишем UB-код, а потом удивляемся, почему он не работает.
ну что понятно, когда ничего не понятно?) допустим есть 100 инструкций, и они исполняются как попало, потому что "умненький" компилятор нагородит как хочет, ему же видите ли "виднее", и это пол-беды, потому что есть обработка инструкций процессором, и уже там всё нагороженное тоже перемусолится как захочет, но только не под интел - и это всего лишь значит, что компилятор напихает "синхронизаторов" на 100 инструкций - для интела сильно меньше, чем если оно будет компилироваться под арм; и это работает - везде, не важно ассемблер это или плюсики или что-то ещё, это первичное свойство процессоров
avp
avp
@InterceptorTSK, вы абсолютно уверены, что правильно понимаете, что именно будет в результате исполнения переставляемых инструкций в суперскалярном и спекулятивном arm-e? Ну, т.е. тонкостей в руководстве программиста для этой шайтан-машины хватает и насколько они учтены компайлеростроителями это вопрос, но обычно многопоточный код работает как ожидалось
@avp частично; и к сожалению арм не вывозит; многопоточный код - всегда работает как и ожидается, другое дело эээ, я уже не знаю как сказать) тут другое дело; интел всегда работает без проблем, потому что [почти] полностью предсказуем; а что бы заработал арм - всё нужно увешать абсолютно всё предсказуемыми берьерами, иначе оно не работает; но как только сие происходит - мгновенно падает линейная производительность [от кол-ва ядер], у интела падения почти нет [~2-5%]
avp
avp
@InterceptorTSK, пример кода с замерами производительности на обеих платформах можете привести?
13:39
да например обычный код, карячится поток с массивом, массив обслуживает временной интервал [пусть 1сек], массив оптимизирован, и пусть 1млн тиков, т.е. индексы массива - по сути временные метки [тики]; элементы массива - сообщения; и куча параллельных потоков раздербанивают этот массив мисаг как сабаки - обрабатывают и складывают в отдельные хипы; понятное дело [предельно очевидно] оно wait-free/lock-free, но чем больше потоков на арме - тем линейная производительность падает, у интела - не падает
avp
avp
@InterceptorTSK, еще раз -- числа в студию (пока все это у вас пустые слова)
@InterceptorTSK Мне гугл подсказывает, что в ARMv8 завезли acquire-store/release-load инструкции, может это их вам не хватало? А может лишние барьеры какие-то поставили? Тема-то интересная, но без кода и без бенчмарков особо не поговоришь.
о боже, я вроде бы пишу очевидное, а тут про v8 инструкции какие то; до которых мне как до фанаря; простейший код - именно простейший - центральный поток, который разгребают вспомогательные потоки; и всё всегда без [любых, каких либо] блокировок, потому что я не использую на уровне исходников [кода] блокирующиеся алгоритмы, я такое вообще никогда не пользую уже как лет десять оно мне не нужно; т.е. в алгоритмах и соответственно в коде - блокировок - нет; но кто тогда расставляет блокировки в уже скомпилированном коде?
как вы в моём коде [исходниках] собираетесь куда то смотреть? на что смотреть? на отсутствующие блокировки? так я вам разу говорю - их в коде [исходниках] - нет ; но они появляются в скомпилированном коде - это же очевидно; так вот для интела компилятор нагораживает их сильно меньше, чем для арма; потому что процессоры так устроены, и соответственно и компиляторы так устроены; тогда на что вы собираетесь смотреть то? я понять не могу
14:06
@InterceptorTSK "а тут про v8 инструкции какие то" - Обясню ход мыслей. Не уверен на 100% что прав, но тем не менее:
* На х86 нет `std::memory_order_relaxed` (он тихо заменяется на acquire/release).
* На x86 обычные не-атомарные операции на уровне инструкций эквивалентны acquire/release атомикам (разница только в оптимизации компилятора может быть) - https://gcc.godbolt.org/z/j7s8TErcM
* На арме вроде как барьер медленнее чем acquire/release (https://stackoverflow.com/a/73028656/2752075)
Поэтому все выглядит логично:
14:56
хмммм... а вот это уже интересно, благодарю! я попробую покопаться в исходниках, только их ещё нужно найти, я экспериментировал лет пять как назад, и попробую посмотреть на то что вы говорите, но это будет только летом, ещё раз благодарю! кто-то написал что тема "интересная", так я больше скажу - тема не то что бы интересная, а вообще то "краеугольная", т.е. определяющая если не всё, то почти всё

last day (15 days later) »