Ada_Ru форум

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

Re: [ada_ru] Атомарные примитивы

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

Сообщения

kazakov1961
Re: [ada_ru] Атомарные примитивы
2009-10-05 14:00:16

On Thu, 5 Nov 2009 11:26:37 +0000 (UTC), you wrote:

 

Начну с того, что, как я выяснил, 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 на суперскалярной

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

 

Легко, если соответствующая инструкция атомарна. Например, GNAT будет ругаться на Atomic для Unsigned_64, но не на Unsigned_32, на 32 разрядной машине. Если инструкция mov на одно слово атомарна, но на два слова - mov и mov - нет.

 

"update" означает "изменение". Запись в X есть "update", чтение,

увеличение, и запись это не "update", но три раздельные операции.

Поэтому Atomic, говоря русским языком, просто означает следующее: пусть n задач Ti пишут в X значения Xi. Тогда любая задача читающая X не прочтет из него ничего, кроме одного из значений Xi, не сказано какого.

 

Я развлекался задачкой реализации X := X + 1 используя только pragma Atomic. Ничего путного не придумал, но подозреваю, что работающее решение будет медленнее чем protected procedure. Такова моя девичья догадка...

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

 

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

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

 

Нет. Именно для этого и были введены protected object-ы. На них Вы можете реализовать все примитивы низкого уровня БЕЗ использования атомарных ИНСТРУКЦИЙ. Разница в значении в том, что атомарные инструкции используют неявную блокировку встроенную в процессор. Как например атомарный mov - держит шину и все стоит. protected object - делает то же, но на

машинно-независимом уровне, в скорее всего медленнее. Но все равно, то же.

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

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

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

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

 

protected type Low_Level is

procedure CAS

( Condition : Integer;

Value : Integer;

Modified : out Boolean

);

private

Register : Integer;

end Low_Level;

 

protected body Low_Level is

procedure CAS

( Condition : Integer;

Value : Integer;

Modified : out Boolean

) is

begin

Modified := Register = Condition;

if Modified then

Register := Value;

end if;

end CAS;

end Low_Level;

 

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

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

 

Atomic там используется только для разделяемых переменных, для которых "update" достаточно. Т.е. для тех, где изменение значения не зависит от прежнего значения, или, иначе, такие изменения происходят на контексте protected action, тогда как чтение может происходить асинхронно. X := X + 1 в эту категорию не попадает.

 

Странно.

 

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

 

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

 

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

 

Так и должно быть, т.к. эта библиотека использует машинно-зависимые примитивы низкого уровня, а не protected object.

 

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

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

fallback implementation.

 

Не уверен. Во всяком случае, simple components использует protected object для работы со счетчиками. Хотя я не сравнивал эффективность с Windows InterlockedExchangeAdd на x86. Я не ожидаю особо "УЖАСНОЙ" разницы, но можно было бы померить.

 

Я помню мы тут мерили protected object для VxWorks (по другому поводу) на x86, вроде было не плохо. Конечно с процедурами. Точки входа были раза в два медленнее, где-то на 20мкс, если не вру, не помню я цифр. Но это - явно из-за работы с очередью, а не из-за lock-еров.

 

--

Regards,

Dmitry A. Kazakov

http://www.dmitry-kazakov.de

On Thu, 5 Nov 2009 15:00:16 +0100, you wrote:

 

Я помню мы тут мерили protected object для VxWorks (по другому поводу) на x86, вроде было не плохо. Конечно с процедурами. Точки входа были раза в два медленнее, где-то на 20мкс, если не вру, не помню я цифр.

 

Вру, наны это были, а не микры.

 

--

Regards,

Dmitry A. Kazakov

http://www.dmitry-kazakov.de

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

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