реклама на сайте
подробности

 
 
> Атомарность операций
sysel
сообщение Oct 2 2009, 07:33
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852



Здравствуйте!

Прошу прощения за оффтоп(хотя ОС Windows CE), но проблема такова:

Пишу многопоточную программу под х86 процессор (защищенный режим) на С++.
Есть глобальная переменная (назовём её Count) для взаимодействия двух потоков. (в обоих потоках присутствуют операции чтение, запись и чтение-модификация-запись (Count=Count+A)).
По логике программы операции чтение и запись не могут привести к нарушению работы, а вот чтение-модификация-запись - может.

Возникла идея реализовать операцию Count=Count+A в виде ассемблерной вставки, где операция выполняется инструкцией Add:
__asm{
push eax
mov eax,A
add Count,eax
pop eax
};
, т.к. код, генерируемый компилятором по умолчанию сводился к:
mov eax,Count
mov ebx,A
add eax,ebx ; опасная строка 1
mov Count,eax ; опасная строка 2

Все эти заморочки вызваны тем, что в любом месте моя программа может быть прервана планировщиком ОС. Т.е. если планировщик вклиниться между опасными командами 1 и 2, запустит на выполнение второй поток, который выполнит опасные команды 1 и 2, и опять запустит на выполнение первый поток, который выполнит опасную команду 2, возникнет ситуация "пепец".

Теперь внимание вопрос: если операция Count=Count+A в ассемблерном коде представлена одной процессорной командой Add, гарантирует ли это отсутствие ситуации "пепец" ?

Иными словами, можно ли ассемблерную инструкцию считать атомарной (выполняемой как единое целое) ?

Иными словами: планировщик современных ОС вклинивается между инструкциями x86 или между инструкциями внутреннего RISC-ядра процессора?

На всякий случай добавлю: пользоваться объектами синхронизации ОС (критические секции, Interlocked...) не вышло - очень замедляет работу моего RealTime приложения. Приложение запущено в пользовательском режиме (кольцо 3), cli и sti не советовать.

На всякий случай доп. информация (скорее всего не существенно):
Среда: Visual Studio 2005
ОС(целевая): Windows CE 6.0 R2
Процессор(целевой): AMD Geode LX800 (x86(набор инструкций P5), FPU, MMX, 3DNow!)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KolyanV
сообщение Oct 4 2009, 06:43
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 91
Регистрация: 1-06-05
Пользователь №: 5 621



Команды процессора с точки зрения прерываний - атомарны. Т.е начатая команда обязательно будет выполнена до конца. Правда с учетом конвеерной обработки, не все так гладко. Возможно, завершение выполнения команды будет происходить тогда, когда процессор начнет вход в прерывание. Но, я думаю, это не должно волновать, так как завершение будет занимать доли/единицы тактов.
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Oct 5 2009, 07:20
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(KolyanV @ Oct 4 2009, 09:43) *
Команды процессора с точки зрения прерываний - атомарны. Т.е начатая команда обязательно будет выполнена до конца. Правда с учетом конвеерной обработки, не все так гладко. Возможно, завершение выполнения команды будет происходить тогда, когда процессор начнет вход в прерывание. Но, я думаю, это не должно волновать, так как завершение будет занимать доли/единицы тактов.


В свое время на BlackFin 537 столкнулся с следующей проблемой:

Код
* * * *
volatile int* piReg_;
* * * *
*piReg_ = /* доступ к внешней памяти */

* * *


Так вот: если во время доступа к внешней памяти происходило прерывание, то вместо одного чтения из памяти, иногда получалось 2. К сожалению в причинах не разобрался - просто на время доступа стал отключать прерывания.
Go to the top of the page
 
+Quote Post
KolyanV
сообщение Oct 6 2009, 20:24
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 91
Регистрация: 1-06-05
Пользователь №: 5 621



Цитата(Dima_G @ Oct 5 2009, 10:20) *
В свое время на BlackFin 537 столкнулся с следующей проблемой:
....
Так вот: если во время доступа к внешней памяти происходило прерывание, то вместо одного чтения из памяти, иногда получалось 2. К сожалению в причинах не разобрался - просто на время доступа стал отключать прерывания.

Ничего не скажу по архитектуре блекфина, но приведенный Вами фрагмент мало о чем говорит. Насколько атомарна выполняемая там операция зависит от того, как компилятор его переведет в машиный код. В случае, приведенном топикстартером модификация ячейки памяти выполняется одной командой (add Count,eax) и поэтому она атомарна (во всяком случае в архитектуре x86).

2 xenia: Никаких cli / sci в коде прикладных программ под ОС высокого уровня Windows/Linux быть не может, и это правильно - времена ДОСов прошли.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Oct 6 2009, 22:08
Сообщение #5


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(KolyanV @ Oct 7 2009, 00:24) *
2 xenia: Никаких cli / sci в коде прикладных программ под ОС высокого уровня Windows/Linux быть не может, и это правильно - времена ДОСов прошли.


Не скажите smile.gif. Вы лично пробовали CLI/STI под WinXP или Vista? Да, это привилегированные команды, которые процессор выполняет только в ядре (0-ом кольце защиты), а в приложении они вызывают "исключение", т.е. прерывание по случаю попытки нарушения защиты. Абортируют ли эти команды приложение? А вот и нет! Исключение и в самом деле происходит, однако супервизор решает, что наружение можно простить smile.gif. Т.е. проверив инструкцию, вызвавшую прерывание (это делается легко, т.к. когда происходит прерывание или исключение, ее адрес лежит на стеке), адрес возврата будет увеличен на единичку, благодаря чему управление вернется на инструкцию, следующую за CLI/STI. В результате выполнение приложения продолжится, как будто этих инструкций не было.

Однако то, что я описала - это только механизм "прощения" такого нарушения, а в реальности супервизор может перед "прощением" повысить приоритет потоку, вызвавшему такое исключение, если нарушившая порядок инструкция была CLI. Или вернуть потоку нормальный приоритет, если это была инструкция STI.

Как видите, под управлением современных ОС высокого уровня, примитивы CLI/STI тоже могут работать, только не напрямую, а опосредованно. И это, между прочим, решает массу проблем! Например, аппаратные прерывания от таймера, мыши, DMA и прочего будет продолжать работать, а процесс вытеснения потоков и задач может быть временно приостановлен. Хотя он будет все равно запущен, если STI долго не придет.

Другое дело, что опираться на подобные механизмы можно только тогда, когда в точности знаешь реакцию данной ОС на CLI/STI.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 7 2009, 05:52
Сообщение #6


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Xenia @ Oct 7 2009, 01:08) *
Другое дело, что опираться на подобные механизмы можно только тогда, когда в точности знаешь реакцию данной ОС на CLI/STI.
И работать, мне кажется, они будут медленнее Interlocked*, уже "забаненных" в первом сообщении за свою за неторопливость.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 23:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.0143 секунд с 7
ELECTRONIX ©2004-2016