SSE Stdlib-esque图书馆?

Nec*_*lis 15 c c++ assembly sse visual-c++

一般来说,我在网上看到的与SSE/MMX相关的一切都是向量和数据的数学东西.但是,我正在寻找SSE优化的"标准函数"库,如Agner Fog提供的,或GCC中的一些基于SSE的字符串扫描算法.

作为一个简单的概述:这些将是像memset,memcpy,strstr,memcmp BSR/BSF,即从SSE intrsuctions构建的stdlib-esque

我最好喜欢它们用于SSE1(正式MMX2)使用内在函数而不是汇编,但两者都很好.希望这不是一个广泛的范围.

更新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功能.

第一次测试是我的家用机器(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
Run Code Online (Sandbox Code Playgroud)

全面测试

第二次测试批次是在大学工作站上完成的(Intel E6550,2.33Ghz,2gb 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
Run Code Online (Sandbox Code Playgroud)

全面测试

可以看出,SSE在我的家庭系统上非常快,但落在了intel机器上(可能是由于编码错误?).我的x86程序集变体在我的家用机器上排在第二位,在intel系统上排在第二位(但结果看起来有点不一致,一个拥抱它阻塞它在SSE1版本中占主导地位).MSVC memcpy赢得了英特尔系统测试手的完成,这是由于SSE2矢量化,但在我的家用机器上,它失败了,甚至可怕的__movsd打败它......

陷阱:内存是所有对齐的权力2.缓存(希望)刷新.rdtsc用于计时.

兴趣点:MSVC有一个(未列出任何参考文献)__movsd内在函数,它输出我正在使用的相同汇编代码,但它失败了(即使内联!).这可能是它未上市的原因.

可以强制VC9 memcpy在我的非sse 2机器上进行矢量化,但它会破坏FPU堆栈,它似乎也有一个bug.

这是我以前测试的完整来源(包括我的修改,再次,归功于http://www.mindcontrol.org/~hplus/原版).二进制文件可根据要求提供项目文件.

总而言之,似乎切换变体可能是最好的,类似于MSVC crt one,只有更坚固更多选项和单次一次性检查(通过内联函数指针?或更像内部直接调用更狡猾的东西)补丁),但内联可能不得不使用最佳案例方法

更新3

Eshan提出的问题提醒了一些有用且与此相关的问题,虽然只对比特集和比特操作,BitMagic而且对于大比特集非常有用,它甚至有一篇关于SSE2(比特)优化的好文章.不幸的是,这仍然不是CRT/stdlib esque类型库.似乎大多数这些项目都专注于特定的小部分(问题).

这提出了一个问题,那么它是否值得创建一个开源的,可能是多平台性能的crt/stdlib项目,创建各种版本的标准化功能,每个版本都针对特定情况进行了优化以及"最佳情况" '/ general函数的变体,带有标量/ MMX/SSE/SSE2 +(即MSVC)的运行时分支或强制编译时标量/ SIMD swich.

这对于HPC或者每个性能都很重要的项目(如游戏)都很有用,可以让程序员免于担心内置函数的速度,只需要进行一点调整即可找到最佳的优化变体.

更新4

我认为应该扩展这个问题的性质,包括可以使用SSE/MMX来优化非矢量/矩阵应用程序的技术,这也可以用于32/64位标量代码.一个很好的例子是如何使用标量技术(位操作),MMX和SSE/SIMD一次检查给定32/64/128/256位数据类型中字节的出现

另外,我看到很多答案都是"只使用ICC",这是一个很好的答案,这不是我的答案,因为首先,ICC不是我可以持续使用的东西(除非英特尔有免费的学生版本)对于Windows),由于30试验.其次,更有针对性的是,我不仅仅是在库之后,而是用于优化/创建它们所包含的功能的技术,用于我个人的编辑和改进,因此我可以将这些技术和原理应用到我自己的代码中(如果需要),与这些库的使用相结合.希望清除那部分:)

Pau*_*l R 1

对于 memset、memcpy 等计算量很少的简单操作,SIMD 优化没有什么意义,因为内存带宽通常是限制因素。