ARM: это запись / чтение из int atomic? - PullRequest
12 голосов
/ 22 февраля 2012

В архитектуре ARM, к сожалению, я не знаю точно, что это за чип, является ли он 32-битным целым для чтения / записи?

Есть ли какие-либо гарантии относительно чтения / записи в базовые типы?

Ответы [ 2 ]

11 голосов
/ 22 февраля 2012

Он должен быть атомарным, ЗА ИСКЛЮЧЕНИЕМ, если этот int хранится по невыровненному адресу.

10 голосов
/ 23 февраля 2012

Это задокументировано либо в TRM для ядра, либо в спецификации AMBA / AXI. Вам нужно посмотреть используемое ядро ​​оттуда, если вы можете выяснить, какой вариант шины AMBA / AXI, и в этой спецификации она раскрывает атомарный / неатомарный характер каждого из типов транзакций.

Например, swp и ldrex / strex являются атомарными. Strd и stm также должны быть атомарными. Но на ARM11 Mpcore, который мне наиболее знаком, он разбивает записи на одиночные 64-битные циклы шины, выполняет stm с 8 регистрами. Я думаю, что он становится 4 отдельными длинами по 1 шинному циклу, где ldm из 8 регистров, я думаю, является одним транзакция длиной четыре.

Самое время отметить, что программисты часто не используют ldrex и strex должным образом. Linux имеет это неправильно, например. Они предназначены для блокировки при использовании многоядерного процессора в системе с общей памятью, а НЕ для блокировки потоков программного обеспечения на одном процессоре. Используйте SWP для этого. Вам повезло, если у вас включен кэш L1, поскольку ldrex / strex работает (в пределах одного процессора).

Примечание. ARM всегда разрешал доступ без выравнивания, иногда по умолчанию (ARM7TDMI), после этого по умолчанию было выброшено прерывание данных, но вы могли изменить настройку так, чтобы она этого не делала. Unaligned на ARM не делает, например, что хотят программисты x86. если вы читаете 32 бита по адресу 0x02, вы не обязательно получите набор байтов 0x02, 0x03, 0x04, 0x05, вы можете / получите 0x02, 0x03, 0x00, 0x01, используя 32-битную шину AMBA / AXI. Вы МОЖЕТЕ получить желаемый результат на 64-битной шине AMBA / AXI, но, возможно, нет, определенно на 32-битной и 64-битной шинах, если вы прочитаете 32-битные по адресу 0x0E, вы получите 0x0E 0x0F и либо 0x08 0x09, либо 0x0c 0x0D. Совсем не то, что ожидают программисты (обычно те, кто знает, как это работает, используют это как хороший байт-обменщик), поэтому его часто оставляют как сброс данных и программист, исправляющий их код.

Компиляторы C очень часто создают не выровненный доступ, поэтому программистам x86 сложно либо перенести свой код, либо перейти с этой платформы на любую другую систему. Они платят большой штраф за x86 (ужасная производительность), но не так сильно, как другие процессоры (сбой памяти). SO загружен вопросами по теме, как мне заставить мой код работать на процессоре xyz.

Я сойду с мыла. ARM отлично документирует все эти вещи (по сравнению с другими производителями чипов). TRM (техническое справочное руководство, у каждого ядра есть) описывает шину AMBA / AXI или выбор шины и будет входить в типы транзакций. Затем документы AMBA / AXI идут дальше, чтобы объяснить, что происходит. В дыре может быть карта между инструкциями и типами транзакций. Когда вы выполняете ldm из 6 слов по адресу 0x4 на 64-битной шине AXI, вы получаете одно 32-битное чтение по адресу 4 длиной 1. Затем вы получаете длину 2 64-битного чтения (четыре байта) по адресу 0x8 (охватывающие слова 0x8, 0xC, 0x10 и 0x14, затем отдельное 32-битное чтение по адресу 0x18. То, что он становится 3-осевым транзакциями, не означает, что он не атомарный; он оставляет возможность для него быть неатомарным, конечно , но вы должны проверить документы ARM.

...