Читать нечетные адреса, пол слова?
Общеизвестно, что многие архитектуры ЦП (ARM, PPC) не могут считывать нечетные адреса, но генерируют исключение, если принудительно, и все же другие могут, но делают это немного медленнее. (X 86)
Но есть ли процессор, который может адресовать только полные 32-битные (или даже больше!) Слова? Т.е. это не может адресовать 16 битные слова? Возможно amd64?
Я пытаюсь написать переносной, но быстрый C malloc-подобный распределитель и хочу правильно настроить доступ к моей памяти. В настоящее время я нацеливаюсь на ARM, i386 и amd64, и я мог бы посмотреть на характеристики, но подумал, что было бы неплохо держать глаза открытыми.
Я думаю, что конкретный способ поставить мой вопрос будет;
если бы процессор считывал 16 битов с адреса 0x2 (если предположить, что диапазон адресов около 0 в целом действителен, я знаю, что некоторые процессоры не используют первую страницу) выдает ошибку шины, где CPU = любой из MIPS, ARM, x86, amd64, 68k, 88000, SH, OpenRISC, Sparc, PPC, Cell / SPE?
(Между прочим, я смотрю на все это с точки зрения программиста на C. Поэтому я предполагаю, что компилятор C предоставляет мне все обычные типы C, такие как char, uint32_t и т. Д.)
3 ответа
SPE ячейки имеют только 16-байтовую загрузку / хранение четырех слов, и они должны быть выровнены по 16-байтовым границам.
Если вам нужно обращаться с более высокой степенью детализации, вы должны читать-модифицировать-записывать и использовать битовые маски только для обновления соответствующих частей данных.
Очевидно, что в C/C++ компилятор поможет с этим, и в наборе команд есть поддержка для генерации и использования масок.
Для вашего примера чтения 16-битного адреса "2" вы должны прочитать 128-битный адрес адреса "0" и замаскировать нужные вам биты. Если вы хотите записать 16-битный код для адреса "2", вам нужно сначала прочитать все 128-битные данные, затем обновить соответствующие 16-битные и записать всю партию обратно.
Некоторые из ранних процессоров IBM Power могли читать / писать только на границах размера элемента, но обрабатывали невыровненные данные с помощью обработчика ловушек (исключений). (И я думаю, что была даже одна ранняя версия, которая говорила бы "ОК" и молча давала вам содержимое выровненного слова, игнорируя младшие биты вашего адреса.)
Я уверен, что старые блоки IBM серии 7000 могли читать / записывать полное слово только на 36-битной границе (размер слова) просто потому, что не было понятия более точного адреса, чем этот. Но я полагаю, что у них были операции чтения / записи с низким / высоким полсловом.
Процессоры серии HP 2100, IIRC, имели только адрес слова (16 бит), но могли выполнять байтовую индексацию. Однако индекс был интерпретирован только как байтовый индекс для байтовых операций - в противном случае это был индекс слова.
Однако, с точки зрения выравнивания malloc, вы обычно должны выравниваться по границе строки кэша. В противном случае трудно предотвратить перегрузку кэша в среде MP.
Если вы можете обратиться к 16-битной величине, то вы определенно можете прочитать 16-битные выровненные величины. Я думаю, вы, вероятно, предполагаете, что у вас будет адресное пространство байтового адреса. Вы не можете, поэтому рекомендуется соблюдать осторожность. Совершенно очевидно, что некоторые архитектуры (в частности, встроенные) могут быть не байтовыми или даже 16-битными адресуемыми, хотя я не знаю конкретных (и текущих) примеров.
Это действительно имеет значение? Если у вас есть машина с адресной словом, с 32-битным адресным размером слова, то вы все равно никогда не сможете адресовать только 16 бит. Будьте осторожны с sizeof.
Вы спрашивали о amd64 (x86-64). У него нет ограничений на доступ с выравниванием по памяти, но вы можете потерять циклы для доступа с выравниванием. Имейте в виду, что неправильный доступ никогда не будет переносимым.
ОБНОВЛЕНИЕ: Что такое выровненный адрес?
Выровненный адрес типа T - это любой адрес, кратный sizeof(T), где sizeof (T) - количество адресуемых единиц, занимаемых значением. Например, если у вас есть 32-битный размер слова в адресуемом байтовом пространстве, выровненные адреса по крайней мере будут кратны 4. Однако, если машина адресуема в 16-битных единицах, то каждый адрес, кратный 2 будет выровненным адресом для 32-битных величин.
Если вы читаете 16-битные величины, есть три случая:
- Байтовая адресация: нечетные адреса потенциально смещены. Архитектура может рассматривать их как выровненные, но не имеет.
- Адресуемые блоки 16-битные: все адреса совпадают для 16-битных величин.
- Адресуемые единицы больше: на самом деле у вас нет 16-битных величин. Они молча больше.
ОБНОВЛЕНИЕ 2: Есть ли ЦП, считывающий 16 бит с адреса 0x2 (при условии, что диапазон адресов действителен), даст ошибку шины?
Такого процессора не может быть, если только адресуемая единица не младше 8 бит. Причина в том, что выравнивание адреса 0x2 составляет 2 адресуемых блока. Если адресуемая единица является 8-разрядной, то она выравнивается по 16-разрядным.
Кроме того, странные значения для адресуемого размера блока исключаются намерением 16 бит. Если 16-битные значения являются реальными величинами архитектуры, адресуемая единица должна составлять коэффициент 16. Таким образом, это может быть только 1, 2, 4, 8 или 16 бит. Если оно окажется выше, выравнивание тривиально выполняется.
Поскольку архитектура с адресом менее 8 бит не стоит проблем, вы почти гарантированы, что адрес 0x2 будет выровненным адресом для 16-битных величин.