Техника, используемая для reverse2
, довольно идиоматична (например, здесь ), и ваши собственные испытания показали, что она должным образом оптимизирована на всех системах, на которых вы тестировали. Чтобы упростить понимание реализации, вы можете ввести больше пробелов и следовать более регулярному шаблону.
uint32_t reverse2(uint32_t d)
{
return ((d & 0x000000FFU) << 24) |
((d & 0x0000FF00U) << 8) |
((d & 0x00FF0000U) >> 8) |
((d & 0xFF000000U) >> 24) ;
}
Попробуйте онлайн: gcc
Попробуйте онлайн: clang
К вашим конкретным точкам:
Существуют ли какие-либо советы, самые известные методы, рекомендации по написанию переносимого кода на C, чтобыкомпилятор сможет обнаружить (давайте оставим в стороне ошибки компилятора) шаблон и использовать максимальные возможности целевой архитектуры ЦП.
Ключ, который нужно убрать, должен попытаться написать идиоматический код. Считать код понятным несколько субъективно. То, что мне может показаться понятным, может показаться непостижимым для кого-то другого (и наоборот). Тем не менее, в программировании на Си есть общие идиомы, которым следует следовать всякий раз, когда это уместно.
К сожалению, у меня нет в голове удобного списка идиом. Но я могу сказать, что я в значительной степени выучил C, прочитав Язык программирования C (конечно, от K & R). И я был заядлым читателем FAQ по программированию на C (автор Steve Summit).
Тем не менее, очень хороший ресурс по идиомам C можно найти, читая и понимая проекты C с открытым исходным кодом, иконечно, база исходного кода компании, в которой вы работаете. Следование последнему имеет дополнительное преимущество, заключающееся в том, что любой код, который вы добавляете в соответствии с существующими соглашениями, естественным образом увеличивает шансы его понимания кем-то еще в компании.
Я часто слышу, как люди говорят, чтокод должен быть написан так, чтобы даже младший программист мог легко понять его, а современные компиляторы достаточно «умны», чтобы позаботиться об оптимизации. Теперь у меня есть доказательства того, что это не так (или, по крайней мере, не всегда так).
Компиляторы - это просто программы, поэтому они не могут читать ваши мысли. Компилятор будет запрограммирован на поиск определенных шаблонов в AST и применение оптимизаций для преобразования дерева в то, что он считает более оптимальным. Аналогичным образом, оптимизатор глазка будет искать шаблоны в сгенерированных машинных инструкциях, а затем преобразовывать их в меньшее количество эквивалентных инструкций.
Но эти преобразования возможны только в том случае, если сгенерированное дерево или сгенерированные инструкции следуют распознаваемому шаблону. И эти шаблоны часто определяются путем анализа реального программного обеспечения, чтобы увидеть, какой код генерируется для определенных операций. Если ваш код не приводит к коду, который может быть распознан компилятором, возможно, вы частично теряете компиляторы, помогая оптимизировать.
Таким образом, это еще одна причина, чтобы попытаться написать идиоматический код на Си.
Теперь можно утверждать, что принуждение к написанию идиоматического C является формой микрооптимизации. Если вы попытаетесь научить компилятор оптимизировать способ написания кода, или пусть компилятор научит вас писать код, который умеет оптимизировать? Тем не менее, импульс несут существующие программисты C, которые пишут код идиоматически. Новые C-программисты принимают эти идиомы ради написания кода, более понятного людям, которые будут пересматривать их код.