170 похожих чатов

Есть вопрос по атомарным/неатомарным операциям. Имеется x86_64, mingw под виндой

(если это важно), N тредов и общий стейт типа int. Вопросы:
1. Можно ли как-то "засечь" ("протестировать") torn read / torn write для int? Насколько я понимаю - на x86 чтение/запись слова всегда атомарна, если память выровнена
2. Можно ли как-то заалайнить общий стейт так, чтобы чтение/запись слова перестало быть атомарным?
3. Как вообще задизайнить тест на torn read / torn write? Пока в мыслях следующий алгоритм: цикл на ~1кк итераций, внутри стартуем два треда, один пишет в общий стейт "+1", второй - "-1", джойним треды, проверяем abs(state) == 1. Будет ли такой алгоритм вообще работать?

9 ответов

15 просмотров

2. #pragma pack(push, 1) struct { char botva; int state; } state; #pragma pack(pop) 3. Звучит разумно, надо тестить.

стоит иметь в виду, что простой тип int при модификации из нескольких потоков не будет ничего знать о потоках и как следствие может не трогать память совсем. Это можно решить с помощью volatile, но от ub на уровне языка это не спасает. Возможно, на x86 это работать и начнет (volatile), но я не уверен. А вот просто int без volatile я вообще не уверен

Oleksandr- Автор вопроса
Egor Suvorov
2. #pragma pack(push, 1) struct { char botva; int ...

2. Спасибо, так и сделал 3. К сожалению на 1кк итераций не удалось ничего словить (ни с int, ни с volatile int). Вот код теста: #include <iostream> #include <thread> #include <cassert> //typedef volatile int value_t; typedef int value_t; #pragma pack(push, 1) struct Packed { char padding; value_t data; }; #pragma pack(pop) int main() { Packed p; value_t* value_ptr = &p.data; int nIterations = 1000000; for (int i = 0; i < nIterations; i++) { std::thread t1 ([&]() { *value_ptr = 1; }); std::thread t2 ([&]() { *value_ptr = -1; }); t1.join(); t2.join(); assert(std::abs(*value_ptr) == 1); } return 0; }

а откуда взялось утверждение в п.1, про потерю атомарность у мува из-за невыровненного адреса?

Oleksandr- Автор вопроса
Denis P
а откуда взялось утверждение в п.1, про потерю ато...

Серьезных пруфов предоставить пока не могу. Сам читаю статьи по атомарности/барьерам в блоге Preshing on Programming, в одной из статей он пишет следующее: https://preshing.com/20130618/atomic-vs-non-atomic-operations/ Non-Atomic CPU Instructions ... As another example, it’s well-known that on x86, a 32-bit mov instruction is atomic if the memory operand is naturally aligned, but non-atomic otherwise. In other words, atomicity is only guaranteed when the 32-bit integer is located at an address which is an exact multiple of 4.

Oleksandr
Серьезных пруфов предоставить пока не могу. Сам чи...

что-то сомнительно. Вот если пересечь границу строки кэша, тогда скорее всего можно сломать.

Oleksandr
2. Спасибо, так и сделал 3. К сожалению на 1кк ите...

Чтоб иметь возможность словить проблему потоки должны стартануть почти в один момент. Я бы добавил ожидание на condition variable и сделал бы notify_all

Boris Usievich
что-то сомнительно. Вот если пересечь границу стро...

8.1.1 Guaranteed Atomic Operations The Intel486 processor (and newer processors since) guarantees that the following basic memory operations will always be carried out atomically: • Reading or writing a byte • Reading or writing a word aligned on a 16-bit boundary • Reading or writing a doubleword aligned on a 32-bit boundary The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically: • Reading or writing a quadword aligned on a 64-bit boundary • 16-bit accesses to uncached memory locations that fit within a 32-bit data bus The P6 family processors (and newer processors since) guarantee that the following additional memory operation will always be carried out atomically: • Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line Accesses to cacheable memory that are split across cache lines and page boundaries are not guaranteed to be atomic by the Intel Core 2 Duo, Intel® Atom™, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, P6 family, Pentium, and Intel486 processors. The Intel Core 2 Duo, Intel Atom, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, and P6 family processors provide bus control signals that permit external memory subsystems to make split accesses atomic; however, nonaligned data accesses will seriously impact the performance of the processor and should be avoided.

Oleksandr
Серьезных пруфов предоставить пока не могу. Сам чи...

Скажем так - выровненная операция записи приедет в память атомарно (в том смысле что если 2 ядра туда пишут, не будет такого что часть бит от одного а часть от другого). Доедет копия от кого-то одного. Это гарантирует протокол когерентности кешей. И это на большинстве архитектур.

Похожие вопросы

Обсуждают сегодня

Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
И никого не интересует какие пакеты кто использует. ((% Заходишь на сайт симфони и видишь поддержку Украины - по законам РФ это ж экстремизм. Только никто не отказывается от с...
Am Ambrion
11
лучше скажите, причём тут паскаль?
Alexey Kulakov
36
Чтобы перехватить все нажимания буков на форме, надо хук ставить? Пробовал на форме ОнКейДаун, оно ловит клаву если фокус не на компоненте с вводом текста
Serjone
15
Но, может, есть уже проверенная? Наши требования такие: 1. Сообщения должны приходить из Инста в CRM оду 2. Должна быть возможность подключить несколько экаунтов Инстаграм. Р...
Alexander Sharoiko MSE / Александр Шаройко
7
Народ! Впервые клиенту пришло письмо от РКН, у вас, дескать, есть яндекс метрика, а нигде не написано, что вы ее юзаете. Никто не сталкивался?
Sasha Beep
14
Всем привет! вывожу на общей стр дочерние ресурсыв каждом ресурсе галерея, и первая фотка должна выводиться на общей [!DocLister? &prepare=photo !]
Alekso
12
Я правильно понимаю что нет способов получить список ожидающих заявок на вступление в группу с помощью бота из mtproto?
Шамиль Прилов
7
А можно вопрос? Мне сегодня сказали что у меня функция (которая просто заполняет массив значениями) не правильная void Full(double * arr, int n) { for (int i = 0; i < n; i...
† C E †
7
Добрый вечер. Хочу чтобы у меня в классе поле было функцией, которая возвращает строку. Делаю так: interface ... TGetOutPath = function : String of object; ... protec...
Kirill Filippenok
12
Карта сайта