Использование xor reg, reg дают преимущество перед mov reg, 0? [дубликат]

Я скучал и синхронизировал миллиард повторений трех подходов. Компилятор является gcc-O3. ЦП - то, что они вставляют 1-го генерала MacBook Pro.

Самый Быстрый следующее, в 3,7 секунды:

static unsigned char wordbits[65536] = { bitcounts of ints between 0 and 65535 };
static int popcount( unsigned int i )
{
    return( wordbits[i&0xFFFF] + wordbits[i>>16] );
}

Второе место переходит к тому же коду, но ищущие 4 байта вместо 2 полуслов. Это заняло приблизительно 5,5 секунд.

Третье место переходит к битовому жонглированию 'поперечное дополнение' подход, который занял 8,6 секунд.

Четвертое место переходит к GCC's __ builtin_popcount () в позорных 11 секунды.

подсчет one-bit-at-a-time подход был waaaay медленнее, и я скучал ожидания его для завершения.

Поэтому, если Вы заботитесь о производительности прежде всего остального тогда, используют первый подход. Если Вы заботитесь, но недостаточно потратить 64 КБ RAM на нем, используйте второй подход. Иначе используйте читаемое (но медленный) one-bit-at-a-time подход.

трудно думать о ситуации, где Вы хотели бы использовать подход битового жонглирования.

Редактирование: Подобные результаты здесь .

48
задан starblue 14 November 2009 в 09:28
поделиться

5 ответов

настоящий ответ для вас:

Справочное руководство по оптимизации архитектур Intel 64 и IA-32

Раздел 3.5.1.8 - это то, что вам нужно.

Короче говоря, бывают ситуации, когда предпочтительнее использовать xor или mov. Проблемы сосредоточены вокруг цепочек зависимостей и сохранения кодов условий.

29
ответ дан 26 November 2019 в 19:00
поделиться

Я перестал ремонтировать свои машины после того, как продал свой универсал HR 1966 года. У меня такое же исправление с современными процессорами: -)

Это действительно будет зависеть от основного микрокода или схемы. Вполне возможно, что ЦП сможет распознать «XOR Rn, Rn» и просто обнулить все биты, не беспокоясь о содержимом. Но, конечно, он может делать то же самое с «MOV Rn, 0» . Хороший компилятор в любом случае выберет лучший вариант для целевой платформы, поэтому обычно это проблема, только если вы кодируете на ассемблере.

Если процессор достаточно умен,

12
ответ дан 26 November 2019 в 19:00
поделиться

Я думаю, что на более ранних архитектурах инструкция mov eax, 0 занимала немного больше времени, чем xor eax, eax тоже ... не могу вспомнить, почему. Если у вас есть много других mov s, однако я могу предположить, что вы вряд ли вызовете промахи кеша из-за того одного литерала, который хранится в коде.

Также обратите внимание, что из памяти состояние флагов не идентичны между этими методами, но, возможно, я это неправильно запомнил.

2
ответ дан 26 November 2019 в 19:00
поделиться

Вы пишете компилятор?

И второе примечание: ваш бенчмаркинг, вероятно, не сработает, поскольку у вас есть ветка, которая, вероятно, в любом случае занимает все время. (если только ваш компилятор не разворачивает цикл за вас)

Еще одна причина, по которой вы не можете протестировать одну инструкцию в цикле, заключается в том, что весь ваш код будет кэшироваться (в отличие от реального кода). Таким образом, вы убрали большую часть разницы в размерах между mov eax, 0 и xor eax, eax из изображения, сохраняя его в L1-кэшировании все время.

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

-7
ответ дан 26 November 2019 в 19:00
поделиться

x86 имеет инструкции переменной длины. MOV EAX, 0 требует на один или два байта больше в кодовом пространстве, чем XOR EAX, EAX.

13
ответ дан 26 November 2019 в 19:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: