Обнаружение требований к согласованной памяти на целевом процессоре

StackOverflow https://stackoverflow.com/questions/9336764

Вопрос

В настоящее время я пытаюсь создать код, который должен работать на широком спектре машин, от карманных компьютеров и датчиков до больших серверов в центрах обработки данных.

Одно из (многих) различий между этими архитектурами - требование согласованного доступа к памяти.

Согласованный доступ к памяти не требуется на "стандартном" процессоре x86, но он нужен многим другим процессорам и выдает исключение, если правило не соблюдается.

До сих пор я боролся с этим, заставляя компилятор быть осторожным при доступе к определенным данным, который, как известно, является рискованным, с использованием атрибута Pack (или прагмы). И работает нормально.

Проблема в том, что компилятор настолько осторожен, что при этом теряется большая производительность.

Поскольку производительность важна, было бы лучше переписать некоторую часть кода, чтобы она работала специально для ЦП со строгим выравниванием. С другой стороны, такой код будет медленнее на процессорах, которые поддерживают невыровненный доступ к памяти (например, x86), поэтому мы хотим использовать его только на процессорах, для которых требуется строго выровненный доступ к памяти.

А теперь вопрос: как определить во время компиляции, что целевая архитектура требует доступа к памяти со строгим выравниванием? (или наоборот)

Это было полезно?

Решение

Ни одна из известных мне реализаций C не предоставляет никаких макросов препроцессора, которые помогли бы вам в этом разобраться. Поскольку ваш код предположительно работает на большом количестве машин, я предполагаю, что у вас есть доступ к большому количеству машин для тестирования, поэтому вы можете выяснить ответ с помощью тестовой программы. Затем вы можете написать свой собственный макрос, как показано ниже:

родовое слово

Обратите внимание, что скорость невыровненного доступа будет зависеть от границ, которые он пересекает. Например, если доступ пересекает границу страницы размером 4 КБ, он будет намного медленнее, и могут быть другие границы, из-за которых он будет еще медленнее. Даже на x86 некоторые невыровненные обращения не обрабатываются процессором, а обрабатываются ядром ОС. Это невероятно медленно.

Также нет гарантии, что будущая (или текущая) реализация не изменит внезапно характеристики производительности невыровненного доступа. Это происходило в прошлом и может произойти в будущем; PowerPC 601 очень снисходительно относился к невыровненному доступу, а PowerPC 603e - нет.

Еще больше усложняет ситуацию тот факт, что код, который вы напишете для выполнения невыровненного доступа, будет различаться по реализации на разных платформах. Например, на PowerPC это упрощено тем, что x << 32 и x >> 32 всегда равны 0, если x 32-битный, но на x86 вам не повезло.

Другие советы

Написание кода для строгого выравнивания памяти в любом случае - хорошая идея.Даже в системах x86, которые допускают невыровненный доступ, невыровненные операции чтения / записи вызовут два доступа к памяти и некоторую потерю производительности.Написать эффективный код, работающий на всех архитектурах ЦП, несложно.Следует помнить простое правило: указатель должен быть выровнен по размеру объекта, который вы читаете или пишете.напримересли вы пишете DWORD, то (dest_pointer & 3== 0).Использование костыля, такого как типы «UNALIGNED_PTR», заставит компилятор сгенерировать неэффективный код.Если у вас есть большой объем устаревшего кода, который должен работать немедленно, тогда имеет смысл использовать компилятор, чтобы «исправить» ситуацию, но если это ваш код, то напишите его с самого начала, чтобы он работал на всех системах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top