Читать странные адреса, полуслова?
Общеизвестно, что многие архитектуры ЦП (ARM, PPC) не могут считывать нечетные адреса, но будут генерировать исключение, если их принудить, и еще другие могут, но делают это немного медленнее. (x86)
Но есть ли процессор, который может адресовать только полный 32 бит (или даже больше!) слова? То есть он не может обращаться к 16-битным словам? Может быть, amd64?
Я пытаюсь написать портативный, но быстрый c malloc, как распределитель, и хочу правильно настроить доступ к памяти. В настоящее время я нацелен на руку, i386 и amd64, и для них я мог бы посмотреть характеристики, но подумал, что было бы неплохо держать ухо востро.
Я думаю, что конкретный способ поставить мой вопрос был бы;
Есть ли процессор, считывающий 16 бит с адреса 0x2 (предполагая ради аргумента, что диапазон адресов около 0 допустим вообще, я знаю, что некоторые процессоры не используют первую страницу), дал бы ошибку шины, где CPU = любой из MIPS, ARM, x86, amd64, 68k, 88000, SH, OpenRISC, Sparc, PPC, Cell/SPE?
(Кстати, я смотрю на все это с точки зрения программиста на языке Си. Поэтому я предполагаю, что компилятор C дает мне все обычные типы C, такие как char, uint32_t и т. д.)
3 ответа:
Ячейки ПСН имеют только 16-разрядный четырехъядерный слово загрузки/сохранения, и они должны быть выровнены по 16-байтовой границы.
Если вам нужно обратиться к более мелкой детализации, вы должны прочитать-изменить-записать и использовать битовые маски только для обновления соответствующих частей данных.
Очевидно, что в C/C++ компилятор поможет в этом, и в наборе команд есть поддержка для генерации и использования масок.
Для вашего примера чтения 16-бит из адреса '2', вы должны были бы прочитать 128-бит от адреса '0' и маскируйте биты, которые вам нужны. Если вы хотите записать 16-битный адрес '2', вам нужно будет сначала прочитать все 128-битные данные, затем обновить соответствующие 16-битные данные и записать все обратно.
Некоторые из ранних процессоров IBM Power могли читать / писать только на границах размера элемента, но обрабатывали бы не выровненные данные с помощью обработчика ловушек (исключений). (И я думаю, что была даже одна ранняя версия, которая говорила "ОК" и молча передавала вам содержание выровненного слова, игнорируя младшие биты вашего адреса.)
Вполне уверен, что старые коробки IBM серии 7000 могли читать / писать только полное слово на 36-битной границе (размер слова), просто потому, что не было понятия адрес более детализированный, чем этот. Но я думаю, что они читали/писали низкие/высокие операции полуслова.
Процессоры серии HP 2100, IIRC, имели только адреса word (16 бит), но могли выполнять индексацию байтов. Однако индекс интерпретировался только как байтовый индекс для операций с байтами - в противном случае это был индекс слова.С точки зрения выравнивания mallocs, однако, вы обычно должны выравниваться по границе линии кэша. В противном случае трудно предотвратить кэш обмолота является депутат окружающей среды.
Если вы можете обратиться к 16-битному количеству, то вы определенно можете прочитать 16-битные выровненные количества. Я думаю, что вы, вероятно, предполагаете, что у вас будет байтовое адресное пространство. Вы не можете, поэтому рекомендуется соблюдать осторожность. Вполне возможно, что некоторые архитектуры (особенно встроенные) не могут быть байтовыми или даже 16-битными адресными-хотя я не знаю конкретных (и текущих) примеров.
Имеет ли это значение? Если у вас есть машина, это слово addressable, с 32-битным размером слова addressable, то вы никогда не сможете адресовать только 16 бит в любом случае. Однако будьте осторожны с sizeof.
Вы спросили о amd64 (x86-64). Он не имеет ограничений на выровненный доступ к памяти, но вы можете потерять циклы для несогласованного доступа. Имейте в виду, что несоразмерные доступы никогда не будут переносными.
UPDATE: что такое выровненный адрес?
Выровненный адрес типа 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-битных величин.