Является ли test-and-set (или другая атомарная операция RMW) привилегированной инструкцией в любой архитектуре?

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

Я думал, что они не являются привилегированными и могут вызываться в пользовательском пространстве. Но http://faculty.salina.k-state.edu/tim/ossg/IPC_sync/ts.html, кажется, предполагает обратное. Но тогда futex(7) при определенных условиях может добиться блокировки без системного call, что означает, что он должен выполнить инструкцию (например, test-and-set) без привилегий.

Противоречие? Если да, то что правильно?


person flow2k    schedule 02.09.2018    source источник
comment
Я думаю, вам нужно указать архитектуру процессора. Насколько я знаю, у Intel нет инструкции Test_and_Set (TS). У процессоров Intel есть атомарность, им просто не хватает этой конкретной инструкции. Может быть, это поле в машинном регистре/управляющем регистре, и чтение/запись защищены? Пинг @PeterCordes.   -  person jww    schedule 02.09.2018
comment
Правильно, я считаю, что x86 имеет инструкцию сравнения-перестановки cmpxchg. Как я могу пропинговать его?   -  person flow2k    schedule 02.09.2018
comment
Вы можете привлечь мое внимание, размещая вопросы в теге [assembly] :P   -  person Peter Cordes    schedule 02.09.2018
comment
@jww: x86 имеет lock bts с 386 года. bts = Bit test and set.   -  person Peter Cordes    schedule 02.09.2018
comment
Спасибо @Питер. Автор специально указывает, что инструкция ts. Вы знаете об арке, которая исходит из? Или они используют гипотетический набор инструкций?   -  person jww    schedule 02.09.2018
comment
@jww: я не думаю, что они говорят о конкретной архитектуре; они говорят о примитивной операции (en.wikipedia.org/wiki/Test-and -set), независимо от того, как это реализовано в ассемблере. В С++ 11 только он должен быть свободным от блокировок: C++: как можно реализовать структуры данных без блокировок в С++, если std::atomic_flag — единственный безблокировочный атомарный тип?. (Я не знаю инструкции ts ни на одном ISA. Большинство из них являются LL/SC и не имеют атомарных RMW с одной инструкцией.) Ее часто называют TAS, точно так же, как cmpxchg обычно называется CAS.   -  person Peter Cordes    schedule 02.09.2018
comment
Я задавался вопросом, говорили ли они о гипотетической ISA, но несколько выше / более ранних страниц не дают никаких признаков этого. Это чистый C. Но, конечно же, у вас может быть гипотетическая дрянная ISA с привилегированной инструкцией TS (и без других атомарных примитивов), которая делает невозможным написание хорошего многопоточного кода пользовательского пространства без блокировки и затрудняет эффективную многопоточность.   -  person Peter Cordes    schedule 02.09.2018


Ответы (1)


Эта страница неверна. Кажется, утверждается, что атомарные операции без блокировки являются привилегированными на ISA в целом, но это не так. Я никогда не слышал о том, чтобы для атомарной проверки и установки или любой другой операции без блокировки требовался режим ядра.

Если бы это было так, потребовалось бы C++11 атомарное чтение-модификация без блокировки. операции записи для компиляции в системные вызовы, но они не выполняются на x86, ARM, AArch64, MIPS, PowerPC или любом другом обычном процессоре. (попробуйте на https://godbolt.org/).

Это также сделало бы невозможной «облегченную» блокировку (которая пытается получить блокировку без системного вызова). (http://preshing.com/20111124/always-use-a-lightweight-mutex/)

Обычные ISA позволяют пользовательскому пространству выполнять атомарные операции RMW с памятью, разделяемой между потоками или даже между отдельными процессами. Мне неизвестен механизм отключения атомарного RMW для пользовательского пространства на x86. Даже если на любой ISA такое есть, то это не нормальный режим работы.

Доступ только для чтения или только для записи обычно является атомарным в выровненных местах на всех ISA до определенной ширины (Почему целочисленное присваивание естественно выровненной переменной является атомарным в x86?), но атомарный RMW нуждается в аппаратной поддержке.


В x86 TAS — это lock bts, что является непривилегированным. (Документация по префиксу lock). x86 имеет широкий набор других атомарных операций, таких как lock add [mem], reg/immediate, lock cmpxchg [mem], reg и даже lock xadd [mem], reg, которые реализуют fetch_add, когда требуется возвращаемое значение. (Может ли num++ быть атомарным для 'int num'?)

Большинство RISC имеют LL/SC, включая ARM, MIPS и PowerPC, а также все более старые, более не распространенные RISC ISA.


futex(2) — это системный вызов. Если вы вызываете его, все, что он делает, находится в режиме ядра.

Это резервный механизм, используемый облегченной блокировкой в ​​случае возникновения конкуренции, который обеспечивает сон/пробуждение с помощью ОС. Таким образом, не futex сама по себе делает что-либо в пользовательском пространстве, а реализации блокировок, построенные вокруг futex, могут избежать выполнения системных вызовов в случае неконкуренции или низкой конкуренции.

(например, покрутите несколько раз в пользовательском пространстве, если блокировка станет доступной.)

Это то, что описывает справочная страница futex(7). Но мне кажется немного странным называть это «операцией фьютекса», если вы на самом деле не выполняете системный вызов. Я предполагаю, что это работает с памятью, на которую код ядра может смотреть от имени других ожидающих потоков, поэтому необходимая семантика для изменения ячеек памяти в коде пользовательского пространства зависит от futex.

person Peter Cordes    schedule 02.09.2018
comment
Спасибо @Peter за этот подробный ответ! Если futex(7) не вызывает futex(2) (т. е. нет конкуренции), он должен использовать TAS или другую атомарную инструкцию для реализации блокировки, верно? Я не проверял код для futex(7)... Я упомянул об этом в вопросе, поскольку futex(7) является библиотечной функцией, она работает в пользовательском пространстве, и поэтому любой выполняемый TAS должен быть в пользовательском пространстве. - person flow2k; 02.09.2018
comment
@flow2k: Да, атомарный RMW в пользовательском пространстве. Но futex(7) документирует общую концепцию построения блокировки или другой операции вокруг futex(2). Нет никакой библиотечной функции с именем futex(), кроме оболочки системного вызова; если бы он был, он бы назывался futex(3). В любом случае, да, весь смысл этого ответа в том, что futex(2) - это то, как вы спите, если обнаружите, что блокировка уже используется в такой реализации, как эта спин-блокировка x86 asm (которая работает в пользовательском пространстве): Блокировка манипулирования памятью с помощью встроенного ассемблера - person Peter Cordes; 02.09.2018
comment
Я никогда не видел процессора, в котором операции проверки битов и установки были бы привилегированными инструкциями. Неудивительно, что студенты компьютерных наук так запутались. - person user3344003; 02.09.2018