ReBits 32 x64

В ReBits 32 и ReBits 32 x4 использовался компилятор под IA-32 (часто обозначаемую как «x86»). Однако, почти все x86-совместимые ЦП, выпускаемые в настоящее время, поддерживают 64-битные расширения (часто называемые «x86-64» или, сокращённо, «x64»), предложенные AMD в 2000 (первый процессор вышел в 2003). ОС, работающие в 64-битном режиме всё шире распространяются на домашних ПК. Поэтому, на мой взгляд, именно x64, а не IA-32 следует рассматривать как основную целевую платформу для новых приложений, особенно, если они должны будут обрабатывать большие объёмы данных.

Система команд x64 включает в себя обязательную поддержку SSE2, причём количество регистров xmm удвоено (до 16). Количество РОНов также удвоено, что, в частности, позволяет ускорить вызов функций (использовать больше регистров для передачи параметров). Посмотрим, как будут работать полученные ранее решения в 64-битном режиме.

Первое разочарование, которое ждёт пользователей MSVC на этом пути — это отсутствие инлайн-ассемблера x64. Придётся выбирать между использованием внешних модулей на ассемблере или интринсиков. На мой взгляд, это хороший повод поближе познакомиться с интринсиками.

Для условной компиляции кода, имеющего разные версии под IA-32 и x64, MSVC предлагает макрос _M_X64 (определён для целевой платформы x64).

Рассматривались следующие варианты: N0, H0, H1 и цикл H5, как написанные на C и не требующие изменений перед перекомпиляцией под x64. Были переписаны H5 (как лучший доступный вариант для обработки одного 32-битного блока), циклы с использованием SSE2 и SSSE3. MSVC предлагает следующие заголовочные файлы:

  • intrin.h — набор всех интринсиков (включает все ниже перечисленные), новый вариант H5 использует _rotl/_rotr (вместо rol/ror: циклический сдвиг влево/вправо) и _byteswap_ulong (вместо bswap: обращение порядка байт);
  • mmintrin.h — команды MMX;
  • xmmintrin.h — команды SSE, включает mmintrin.h;
  • emmintrin.h — команды SSE2, включает xmmintrin.h;
  • pmmintrin.h (Prescott) — команды SSE3, включает emmintrin.h;
  • tmmintrin.h (Tejas) — команды SSSE3, включает pmmintrin.h;
  • smmintrin.h (?) — команды SSE4.1, включает tmmintrin.h;
  • nmmintrin.h (Nehalem) — команды SSE4.2, включает smmintrin.h;
  • wmmintrin.h (Westmere) — команды AES NI и CLMUL, включает nmmintrin.h;
  • immintrin.h (?) — команды AVX, включает wmmintrin.h;
  • ammintrin.h — команды, предложенные AMD (бывший SSE5).

Удвоенное количество регистров позволяет хранить инвертированные маски (и сократить таким образом количество инструкций), а также обрабатывать не одну четвёрку, а, например, две четвёрки за итерацию цикла. При этом вторая загрузка происходит после первого блока вычислений. Теоретически такое «смешивание» команд должно минимизировать простой XMM блоков ЦП. Итак, переписанные на интринсиках варианты: для SSE2, для SSSE3. Сравним их результаты (за 100% приняты соответственно H1 и цикл на H5, обозначенный H5x4).

Можно заметить, что SSE2 улучшил свои относительные показатели. N0 не показан из-за его низкой скорости (чтобы не портить масштаб), кроме того, для N0 переход на x64 ничего не дал (на Deneb даже стало медленнее на 11%). Ниже представлена диаграмма, показывающая отношение времени, затраченного x64 версией, ко времени IA-32 версии. Для большинства рассмотренных вариантов переход на x64 оказался полезен.

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: