В общем, все, что я встречаю "по-сети" по отношению к SSE/MMX, появляется как материал математики для векторов и матрасов. Тем не менее, я ищу библиотеки оптимизированных "стандартных функций" SSE, таких как те, которые предоставляются Agner Fog или некоторые из строк на основе SSE алгоритмы сканирования в GCC.
Как быстрое общее изложение: это будут такие вещи, как memset, memcpy, strstr, memcmp BSR/BSF, т.е. stdlib-esque, созданный из SSE-интроктов
Я бы предпочел, чтобы они были для SSE1 (формально MMX2), используя intrinsics, а не сборку, но либо это нормально. надеюсь, это не слишком широкий спектр.
Обновление 1
После некоторых поисков я наткнулся на некоторые многообещающие вещи, одна библиотека привлекла мое внимание:
- LibFreeVec: кажется, только mac/IBM (из-за того, что он основан на AltiVec), поэтому мало пользы (для меня), плюс Я не могу найти прямую ссылку для скачивания и не укажу минимально поддерживаемую версию SSE.
Я также встретил статью о нескольких векторных строковых функциях (strlen, strstr strcmp). Однако SSE4.2 выходит из моей досягаемости (как было сказано ранее, я хотел бы придерживаться SSE1/MMX).
Обновление 2
Paul R побудил меня сделать небольшой бенчмаркинг, к сожалению, поскольку мой опыт сборки сборки SSE близок к zip, я использовал кого-то другого (http://www.mindcontrol.org/~hplus/) и добавлен к нему. Все тесты (исключая оригинал, который является VC6 SP5), который скомпилирован под VC9 SP1 с полной/настраиваемой оптимизацией и /arch:SSE
on.
Первый тест был одним из моих домашних компьютеров (AMD Sempron 2200+ 512mb DDR 333), ограниченным SSE1 (таким образом, без векторизации с помощью MSVC memcpy):
comparing P-III SIMD copytest (blocksize 4096) to memcpy
calculated CPU speed: 1494.0 MHz
size SSE Cycles thru-sse memcpy Cycles thru-memcpy asm Cycles thru-asm
1 kB 2879 506.75 MB/s 4132 353.08 MB/s 2655 549.51 MB/s
2 kB 4877 598.29 MB/s 7041 414.41 MB/s 5179 563.41 MB/s
4 kB 8890 656.44 MB/s 13123 444.70 MB/s 9832 593.55 MB/s
8 kB 17413 670.28 MB/s 25128 464.48 MB/s 19403 601.53 MB/s
16 kB 34569 675.26 MB/s 48227 484.02 MB/s 38303 609.43 MB/s
32 kB 68992 676.69 MB/s 95582 488.44 MB/s 75969 614.54 MB/s
64 kB 138637 673.50 MB/s 195012 478.80 MB/s 151716 615.44 MB/s
128 kB 277678 672.52 MB/s 400484 466.30 MB/s 304670 612.94 MB/s
256 kB 565227 660.78 MB/s 906572 411.98 MB/s 618394 603.97 MB/s
512 kB 1142478 653.82 MB/s 1936657 385.70 MB/s 1380146 541.23 MB/s
1024 kB 2268244 658.64 MB/s 3989323 374.49 MB/s 2917758 512.02 MB/s
2048 kB 4556890 655.69 MB/s 8299992 359.99 MB/s 6166871 484.51 MB/s
4096 kB 9307132 642.07 MB/s 16873183 354.16 MB/s 12531689 476.86 MB/s
Вторая тестовая партия была выполнена на университетской рабочей станции (Intel E6550, 2,33 ГГц, 2 ГБ DDR2 800?)
VC9 SSE/memcpy/ASM:
comparing P-III SIMD copytest (blocksize 4096) to memcpy
calculated CPU speed: 2327.2 MHz
size SSE Cycles thru-sse memcpy Cycles thru-memcpy asm Cycles thru-asm
1 kB 392 5797.69 MB/s 434 5236.63 MB/s 420 5411.18 MB/s
2 kB 882 5153.51 MB/s 707 6429.13 MB/s 714 6366.10 MB/s
4 kB 2044 4447.55 MB/s 1218 7463.70 MB/s 1218 7463.70 MB/s
8 kB 3941 4613.44 MB/s 2170 8378.60 MB/s 2303 7894.73 MB/s
16 kB 7791 4667.33 MB/s 4130 8804.63 MB/s 4410 8245.61 MB/s
32 kB 15470 4701.12 MB/s 7959 9137.61 MB/s 8708 8351.66 MB/s
64 kB 30716 4735.40 MB/s 15638 9301.22 MB/s 17458 8331.57 MB/s
128 kB 61019 4767.45 MB/s 31136 9343.05 MB/s 35259 8250.52 MB/s
256 kB 122164 4762.53 MB/s 62307 9337.80 MB/s 72688 8004.21 MB/s
512 kB 246302 4724.36 MB/s 129577 8980.15 MB/s 142709 8153.80 MB/s
1024 kB 502572 4630.66 MB/s 332941 6989.95 MB/s 290528 8010.38 MB/s
2048 kB 1105076 4211.91 MB/s 1384908 3360.86 MB/s 662172 7029.11 MB/s
4096 kB 2815589 3306.22 MB/s 4342289 2143.79 MB/s 2172961 4284.00 MB/s
Как видно, SSE очень быстро работает на моей домашней системе, но падает на машину Intel (возможно, из-за плохого кодирования?). мой вариант сборки x86 входит на втором месте на моей домашней машине, а второй - на систему intel (но результаты выглядят немного непоследовательными, один объятия блокирует его доминирование в версии SSE1). MSVC memcpy выигрывает тесты системных систем Intel, это связано с векторизации SSE2, хотя на моей домашней машине он терпит неудачу, даже ужасный __movsd
бьет его...
ловушки: в памяти были все выровненные полномочия 2. Кэш был (надеюсь) покраснел. rdtsc использовался для синхронизации.
Интересные объекты: MSVC имеет (не включенную в любую ссылку) __ movsd intrinsic, он выводит тот же код сборки, который я использую, но он терпит неудачу в унылом состоянии (даже когда он встраивается!). Вероятно, поэтому его не внесенные в список.
VC9 memcpy может быть принудительно векторизован на моей машине, отличной от sse 2, однако он повредит стек FPU, он также, похоже, имеет ошибку.
Это полный источник для того, что я использовал для тестирования (включая мои изменения, опять же, кредит http://www.mindcontrol.org/~hplus/ для оригинала). Бинарники файлов проекта доступны по запросу.
В заключение, кажется, что вариант переключения может быть лучшим, похожим на MSVC crt one, только намного более прочным с большим количеством опций и одиночными однократными проверками (с помощью указателей функций inline'd или чего-то более коварного типа внутренний патч прямого вызова), однако встраивание, вероятно, должно было бы использовать метод наилучшего случая вместо
Обновление 3
Вопрос, заданный Эшаном, напомнил о чем-то полезном и связанном с этим, хотя и для бит-бит и бит ops, BitMagic и быть вполне полезно для больших наборов бит, у него даже есть хорошая статья на оптимизация SSE2 (бит). К сожалению, это все еще не библиотека типа CRT/stdlib esque. кажется, что большинство из этих проектов посвящено конкретному небольшому разделу (проблем).
Возникает вопрос: тогда было бы целесообразно создать проект с открытым исходным кодом, возможно многоплатформенный проект crt/stdlib, создающий различные версии стандартизованных функций, каждый из которых оптимизирован для определенной ситуации, а также " наилучшего варианта/общего использования функции с ветвлением развёртки для скаляра /MMX/SSE/SSE 2 + (à la MSVC) или сканированием времени принудительной компиляции /SIMD swich.
Это может быть полезно для HPC или проектов, где каждый бит производительности (например, игры), освобождая программиста от беспокойства о скорости встроенных функций, требует лишь небольшого количества настроек для поиска оптимального оптимизированного варианта.
Обновление 4
Я думаю, что характер этого вопроса должен быть расширен, чтобы включить методы, которые могут быть применены с использованием SSE/MMX для оптимизации для приложений, отличных от вектора/матрицы, это, вероятно, может быть использовано и для 32/64-битного скалярного кода. Хорошим примером является проверка наличия байта в заданном типе данных 32/64/128/256 бит сразу с использованием скалярных методов (бит-манипуляция), MMX и SSE/SIMD
Кроме того, я вижу много ответов по строкам "просто использую ICC", и это хороший ответ, это не мой ответ, поскольку, во-первых, ICC - это не то, что я могу использовать постоянно (если у Intel нет бесплатная версия для студентов для окон), из-за 30 проб. во-вторых, и, что более уместно, я не только после того, как библиотеки сами по себе, но и методы, используемые для оптимизации/создания функций, которые они содержат, для моего личного изменения и улучшения, и поэтому я могу применять такие методы и принципы к своему собственному коду (там, где это необходимо), в сочетании с использованием этих библиотек. надеюсь, это очистит эту часть:)