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

 
 
> Атомарность операций
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



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

 


RSS Текстовая версия Сейчас: 11th August 2025 - 15:37
Рейтинг@Mail.ru


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