Дмитрий Радищев (dibr) wrote,
Дмитрий Радищев
dibr

Categories:

ступенька

Бывает что люди замечают "изменения реальности", примерно как по ссылке ниже. Когда живёшь себе потихоньку, а однажды утром обнаруживаешь, что что-то хорошо тебе известное не просто стало другим, а всегда другим и было, а таким каким ты его помнишь - никогда не было, и все это подтверждают. И это не "эффект Манделы", когда ты что-то где-то вроде слышал, а на поверку оказалось что всё по другому, речь про вполне конкретный свежий личный опыт, без догадок и неоднозначностей.

https://sam-newberry.livejournal.com/1016683.html

А я про другое вспомнил. Про недавние уязвимости процессоров - а именно про Meltdown и Spectre (так их уже с два десятка есть, это самые известные). А основаны они на так называемом "спекулятивном выполнении" в современных процессорах: там, в самом центре ядра процессора, где собственно и происходят вычисления, всё крутится с такой бешеной скоростью, что "думать некогда, считать надо", и совершенно штатной является ситуация, что к моменту начала исполнения команды мы ещё не знаем, надо ли её вообще исполнять - доступны ли все данные вот прям счас, "не подвели ли смежники" (успешно ли выполнилась предыдущая команда, от которой зависит эта), по этой ли ветке условного перехода пойдёт выполнение, и даже имеем ли мы право её вообще исполнять (есть ли у процесса доступ к той памяти, к которой команда хочет доступиться). Поэтому команда, а то и ветка команд, начинает выполняться сразу (и бывает что успевает выполниться на пару операций "вглубь"), а уже в процессе выполнения процессор выясняет, стоило ли вообще это выполнять, или не стоило (в абсолютном большинстве случаев стоило, за счёт этого и происходит ускорение - мы не теряем времени на проверки). Если же не стоило - просто выбрасывает результаты выполнения, а команду заворачивает в специальную очередь на повторное выполнение (или не заворачивает, если оказалось что её выполнять вообще не надо было(*)).
При этом "выбрасывание результата" штука не такая тривиальная - нужно ведь чтобы в случае отмены спекулятивного выполнения не осталось буквально никаких алгоритмически значимых следов этого выполнения, и у программы создавалось впечатление исполнения строго-по-порядку-и-правильно (есть ведь ещё "внеочередное исполнение инструкций", тоже интересная тема, а ещё "неправильно" выполненная инструкция вовсе не обязательно останавливает выполнение следующих за ней). И специально для такого "выбрасывания" в процессоре реализована целая куча механизмов, вплоть до возможности "откатить" даже запись в память (для этого сделан короткий "буфер записи", через который проходят все операции записи, прежде чем реально записаться в память, и пока операция в буфере - её можно просто вычеркнуть, как будто ничего и не было). Но поскольку изначально задача зачистки вообще всех "хвостов" не ставилась, ставилась задача чтобы все эти фокусы были незаметны чисто, так сказать, алгоритмически, а например обращение к памяти так или иначе "задевает" довольно много узлов процессора (кеш, таблицы дескрипторов, что-там-ещё), оставляя косвенные признаки того, что обращение было, эти признаки можно пытаться обнаруживать - то есть команда вроде как бы и не выполнилась, никакого _результата_ после себя не оставила, но _следы_ попыток её выполнения - остались.

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

А теперь рассмотрим ситуацию, в которой человечество живёт и обсчитывается в некоей Матрице. Чисто из соображений эффективности, мир при этом удобно разбить на систему слабосвязанных участков, и каждый такой участок обсчитывать на своём вычислительном узле - тогда не придётся учитывать "влияние всего на всё" (ретроградного Меркурия на успех Великой Октябрьской Социалистической Революции), а обойтись относительно небольшим потоком информации между узлами. Это мы, в принципе, и наблюдаем - люди любят селиться компактными кучками (города, сёла) с относительно слабыми связями (интернет это изменил, но не так чтобы радикально), звёзды-планеты вообще отдельно, и до недавнего времени вообще сводились к "точкам на небесном своде". Но при этом, как за счет ограниченности потока данных, так и временнЫх задержек, точное состояние "внешних" узлов при обсчёте будет частично "угадываться" (кстати, не эту ли проблему должен был решить хак с квантовой механикой?), что неизбежно будет приводить к рассогласованиям между реальностями разных узлов. При синхронизации эти рассогласования будут, разумеется, обнаружены и скомпенсированы - в лёгких случаях простым "приведением в соответствие" (небольшие сбои в реальности мало кто заметит), в более серьёзных - с "коррекцией прошлого" (частичной заменой памяти/предыстории).
Но, поскольку изменяется только так сказать явная, "видимая" часть памяти, а неявная, то есть весь букет ассоциаций и поведенческих нюансов, с этой памятью связанных, не изменяется (поскольку это потребовало бы фактически пересчёта этого участка заново от момента первого изменения, а это не просто затраты времени, но и рассинхронизация участков), как раз и возможны всякие странные ситуации. Начиная с "события как бы не было, но его последствия есть" и до "ложной памяти" вроде той самой "ступеньки" по ссылке.

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

===
(*) в плане спекулятивного выполнения мне вот что больше всего понравилось.
Вот программа-злоумышленник выполняет инструкцию с обращением к чужой памяти. Инструкция начинает выполняться, пока она выполняется процессор обнаруживает что выполнять её нельзя ни в коем случае, и генерирует исключение. Управление передаётся операционной системе, а та, при достаточно параноидальной настройке, тупо прибивает программу. Да и при менее параноидальной испортить жизнь злоумышленнику не так уж сложно, хотя бы кеш инвалидировать - уже большая часть атак отвалится.
А теперь мы кладём эту же инструкцию в одну из веток условного перехода, и подначиваем процессор думать, что эта ветка более вероятна (методы есть). Процессор спекулятивно выполняет инструкцию, обнаруживает обращение к чужой памяти... но мы тем временем выполняем переход по _другой_ ветке, и поскольку оказывается что инструкцию выполняли зря, и надо сделать вид что этого не было - исключение _не_ генерируется, и злоумышленник спокойно переходит к следующему этапу (обычно это опрос кусочка своей памяти на предмет выяснения, что из этого кусочка есть в кеше).
Работает же фантазия у людей!
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 35 comments