Ada_Ru форум

Обсуждение языка Ада

Атомарные примитивы

Оставить новое сообщение

Сообщения

Иван Левашев
Атомарные примитивы
2009-10-05 11:26:37

Начну с того, что, как я выяснил, pragma Atomic () не

работает.

 

Если X — Atomic и X := X + 1, то я ожидаю в ассемблерном

листинге увидеть что–нибудь вроде lock incl (%ecx), однако,

вместо этого я вижу нечто вроде (могу листинги выложить,

сейчас пишу по памяти):

 

movl -4(%ebp), %eax

addl $1, %eax

mov %eax, -4(%ebp)

 

http://adaic.org/standards/05rm/html/RM-9-10.html

 

Здесь сказано:

 

A pragma Atomic or Atomic_Components may also be

used to ensure that certain reads and updates are

sequential.

 

Но как можно обеспечить sequential на суперскалярной

архитектуре, не используя барьеров в памяти?

 

Или "may" подразумевает "not necessarily"?

 

Если я всё правильно понимаю, ассемблерные вставки пока

что единственный способ реализовать атомарные примитивы.

 

Да даже, если бы pragma Atomic работала, как на Аде

выразить атомарный CAS? Без if не обойтись, а на if

неделимость чтения–записи уже не должна распространяться.

В стандартной библиотеке CAS пока нет.

 

Кстати, в simple components используется именно

pragma Atomic (), ассемблерных вставок я там не нашёл.

Странно.

 

Зато вот здесь:

 

http://www.gidenstam.org/Ada/Non-Blocking/

 

явно указано на использование ассемблерных вставок. В

Ассемблер я верю. Если нет Ассемблера, жди подвоха, и

подвохи в самом деле не заставляют себя ждать. Надо

бы скачать NBAda.

 

В gcc intrinsics я тоже верю, но их в GNAT пока нет.

 

У меня сейчас есть небольшие наработки. Для jedi winapilib

понадобилась дополнительная библиотека, которую я не

захотел делать частью виндовых привязок. Она более общего

назначения. В эту библиотеку (я назвал её Turbo) должны

в том числе входить строки, сделанные по образу и подобию

Делфийских. Я хочу, чтобы Виндовыми привязками было

пользоваться так же удобно, как в Delphi. Win32Ada и

GNAT-COM в Аде просто кошмар по сравнению с WinAPI и COM в

Delphi. Таким кошмаром редкого разработчика можно

заманить. Нужно очень глубоко забуриться в Ад,

чтобы понять, что потенциально Ада намного мощнее, чем

Delphi и co., однако до этого потенциального превосходства

путь пролегает через написание дополнительного кода.

В частности, атомарные примитивы и строки со счётчиками

ссылок должны быть частью стандартной библиотеки, а

сама библиотека — было бы неплохо под Modified GPL.

Что касается конвертера, я переписал его на существенно

более мощном и быстром Icon, но упирается всё пока что

в адский код. Для Delphi-style строк понадобились счётчики

ссылок, а подсчёт ссылок — это атомарный примитив.

Строки без счётчика ссылок — это несерьёзно. protected в

роли счётчика ссылок — это тоже несерьёзно. Только для

fallback implementation.

 

Для x86 всё реализуется довольно прозрачно.

lock incl, lock xchgl, lock xaddl, lock cmpxchgl.

Для других архитектур источник вдохновения можно

черпать в gatomic.c (glib), mono_membar.h (mono),

gcc/config/i386/sync.md (gcc) и прочих. В таких

библиотеках плохо то, что предоставляются только те

атомарные инструкции, которые есть на целевой платформе.

Если какой–то операции, такой, как XADD, нет на целевой

платформе, её можно реализовать через CAS. В принципе,

через CAS можно реализовать любой другой тривиальный

примитив.

 

Мне вот, разве что, непонятно, можно ли в качестве

неполного барьера использовать lfence и sfence? На

x86_64 я видел, что они применяются для неполных

барьеров, а на x86 — ? На процессорах с SSE2 эти

инструкции есть в 32разрядном режиме, но их не

используют так же, как на x86_64. Скажем, в том же

mono_membar полный барьер на x86 реализован как

прибавление нуля к (%esp) в сочетании с Clobber => "memory".

А все неполные барьеры в mono реализованы через

этот полный барьер. Зато всё в том же mono_membar.h

для x86_64 есть и lfence, и sfence, и mfence.

Новое сообщение:
Страницы: 1

Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти