Атомарные встроенные функции в lcc

Ответить
Аватара пользователя
OCTAGRAM
Сообщения: 4
Зарегистрирован: 04 ноя 2020, 05:20
Контактная информация:

Атомарные встроенные функции в lcc

Сообщение OCTAGRAM »

Обнаружил, что встроенные функции вроде __atomic_compare_exchange_16 работают как встроенные в том смысле, что доступны без объявления. Но для них нужно подключать библиотеку libatomic.so, и реально исполнение идёт туда.

Ожидалось, что они встраиваются в выходной код на уровне инструкций, а получается целый косвенный (межбиблиотечный) вызов.
https://Objective.PE/
Общая платформа исполнения приложений

Аватара пользователя
mike
Сообщения: 58
Зарегистрирован: 24 апр 2017, 13:58
Контактная информация:

Re: Атомарные встроенные функции в lcc

Сообщение mike »

Прошу модераторов перенести тему в раздел про lcc; в идеале поставив здесь какую-либо отсылку туда.

Ответ компиляторщиков:

---
В lcc работает симметрично с gcc


Описание gcc:
https://gcc.gnu.org/onlinedocs/gcc-7.5. ... c-Builtins
...
If there is no pattern or mechanism to provide a lock-free instruction sequence,
a call is made to an external routine with the same parameters to be resolved
at run time
...
Другими словами, встроенный код будет строиться только в том случае,
если есть аппаратная поддержка для операции такого типа и такого формата.
Если такой поддержки нет, то будет строиться вызов функции, который
реализует НЕ lock-free вариант построения (т.е. с использованием mutex'ов
или семафоров)


Например, на intel'овском gcc:

Код: Выделить всё

$ cat t.c
__int128_t x, y, z;
int main (void)
{
  __atomic_compare_exchange_n (&x, &y, z, 0, 0, 0);
}

Код: Выделить всё

$ gcc-7.3 t.c
/tmp/cczAmbWl.o: In function `main':
t.c:(.text+0x2f): undefined reference to `__atomic_compare_exchange_16'
collect2: error: ld returned 1 exit status

$ gcc-7.3 t.c -latomic
<ok>
Конкретно в случае Эльбруса аппаратная поддержка 16-байтных атомарных
обращений появилась начиная с системы команд elbrus-v5 (т.е. начиная
с процессора Эльбрус-8СВ). Поэтому для более ранних систем команд
для 16-байтных атомарных операций будет строитья вызов функции,
а для более поздних - встроенный код

Код: Выделить всё

$ cat t.c
__int128_t x, y, z;
int main (void)
{
  __atomic_compare_exchange_n (&x, &y, z, 0, 0, 0);
}

$ lcc -march=elbrus-v3 t.c
/tmp/lcc_RHGnwb.o: in function `main':
t.c:(.text+0x40): undefined reference to `__atomic_compare_exchange_16'

$ lcc -march=elbrus-v5 t.c
<ok>
Я плохо разбираюсь в intel'овской системе команд. Возможно, что если
сконфигурировать gcc под какие-то более поздние модели процессоров
или подать опцию -march с каим-нибудь современным процессором, то там
тоже построится встроенный код для данного примера. Если в современных
версиях intel'овских процессоров есть аппаратная поддержка 16-байтных
атомарных операций
---
Михаил Шигорин | ОС Альт для Эльбрус | вики для всех нас: altlinux.org/эльбрус

Аватара пользователя
mike
Сообщения: 58
Зарегистрирован: 24 апр 2017, 13:58
Контактная информация:

Re: Атомарные встроенные функции в lcc

Сообщение mike »

PS:

---
Всё, что было написано выше, касалось процессора Эльбрус. В случае
процессора МЦСТ-R на сегодняшний день аппаратной поддержки 16-байтных
операций нет ни в одной модели процессора (так же, как и на SPARC'ах).
Поэтому для 16-байтных операций там всегда будет строиться вызов функции
---
Михаил Шигорин | ОС Альт для Эльбрус | вики для всех нас: altlinux.org/эльбрус

Аватара пользователя
OCTAGRAM
Сообщения: 4
Зарегистрирован: 04 ноя 2020, 05:20
Контактная информация:

Re: Атомарные встроенные функции в lcc

Сообщение OCTAGRAM »

mike писал(а):
04 дек 2020, 11:24
Я плохо разбираюсь в intel'овской системе команд. Возможно, что если
сконфигурировать gcc под какие-то более поздние модели процессоров
или подать опцию -march с каким-нибудь современным процессором, то там
тоже построится встроенный код для данного примера. Если в современных
версиях intel'овских процессоров есть аппаратная поддержка 16-байтных
атомарных операций
---
На Intel дело не в процессоре, а во всей системе. Такую операцию, как атомарную замену, может требоваться проводить через L3 кеш, чипсет, и всё прочее на материнской плате, так что cmpxchg16b стал реально доступен не очень давно.
mike писал(а):
04 дек 2020, 11:24
Конкретно в случае Эльбруса аппаратная поддержка 16-байтных атомарных
обращений появилась начиная с системы команд elbrus-v5 (т.е. начиная
с процессора Эльбрус-8СВ). Поэтому для более ранних систем команд
для 16-байтных атомарных операций будет строитья вызов функции,
а для более поздних - встроенный код

Код: Выделить всё

$ cat t.c
__int128_t x, y, z;
int main (void)
{
  __atomic_compare_exchange_n (&x, &y, z, 0, 0, 0);
}

$ lcc -march=elbrus-v3 t.c
/tmp/lcc_RHGnwb.o: in function `main':
t.c:(.text+0x40): undefined reference to `__atomic_compare_exchange_16'

$ lcc -march=elbrus-v5 t.c
<ok>
Вот это неожиданная причина. Во-первых, оказывается, есть неочевидный ключ, потенциально заметно влияющий на производительность всего, что связано с подсчётом ссылок.

Во-вторых, я принимал как данность, что любой вменяемый процессор умеет атомарно работать с указателями, а хороший процессор сразу с двумя. В так называемом защищённом режиме указатель 16 байт, и аппаратная защита тем более подразумевает такую вменяемость, так что я даже немного растерян на тему, а как это могло надёжно работать раньше без атомарной замены? То есть, если ломануться потоками как-нибудь хитро писать в память, они рано или поздно смогут создать указатель-франкенштейн с неположенными индексами или правами доступа.
https://Objective.PE/
Общая платформа исполнения приложений

Аватара пользователя
mike
Сообщения: 58
Зарегистрирован: 24 апр 2017, 13:58
Контактная информация:

Re: Атомарные встроенные функции в lcc

Сообщение mike »

---
Сами аппаратные операции чтения-записи защищённого дескриптора
являются атомарными. Т.е. никакие многопоточные программы не могут разломать
дескриптор или создать на его основе что-нибудь непотребное

Но, к сожалению, на ранних версиях процессоров аппаратного cmpxchg
для формата 16 байт сделано не было. Поэтому cmpxchg работал только
в НЕ-lock-free варианте. Т.е. предыдущий пример вполне себе можно
было скомпилировать и на более ранних версиях процессоров, но используя
дополнительную опцию -latomic

Проблему нехватки cmpxchg и прочих операций формата 16 поняли уже
давно. Но процесс разработки процессора - вещь очень длительная.
То, что условно выпущено в 2020 году, начало разарабатываться
лет 5 назад, а то и ранее, сходу даже сказать не могу. Поэтому
то упущение, которое поняли много лет назад, в готовом железе
появилось только "сегодня"
---
Михаил Шигорин | ОС Альт для Эльбрус | вики для всех нас: altlinux.org/эльбрус

Ответить

Вернуться в «Вопросы производительности»