通常,我遇到的与SSE/MMX有关的“网上”所有内容都是作为 vector 和矩阵的数学知识而出现的。但是,我正在寻找SSE优化的“标准函数”的库,例如Agner Fog提供的库或GCC中某些基于SSE的字符串扫描算法。

作为一般的简要介绍:这些将是诸如memset,memcpy,strstr,memcmp BSR/BSF之类的东西,即基于SSE插入构建的stdlib风格

我最好希望它们用于使用内在函数而不是汇编函数的SSE1(以前为MMX2),但是两者都很好。希望这不会太广泛。

更新1

经过一番搜索,我发现了一些很有前途的东西,一个图书馆引起了我的注意:

  • LibFreeVec:似乎仅适用于mac/IBM(由于基于AltiVec),因此对我几乎没有用,而且我似乎找不到直接下载链接,也没有说明受支持的最低SSE版本

  • 我还遇到了一些矢量化字符串函数(strlen,strstr strcmp)上的an article。但是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
    

    full tests

    第二次测试是在大学工作站上完成的(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
    

    full tests

    可以看出,SSE在我的家庭系统上非常快,但是落在intel机器上(可能是由于编码错误?)。我的x86装配体变体在家用计算机中排名第二,在英特尔系统中排名第二(但是结果看起来有点不一致,一个拥抱阻止它在SSE1版本中占主导地位)。 MSVC memcpy赢得了intel系统测试的成功,这是由于SSE2向量化,尽管在我的家用计算机上,它失败了,甚至可怕的__movsd也击败了它。

    陷阱:内存全部对齐2的幂。(希望)刷新了缓存。 rdtsc用于计时。

    兴趣点:MSVC具有(未在任何引用文献中列出)__movsd内部函数,它输出与我正在使用的相同的汇编代码,但是却失败(即使是内联!)。这可能就是为什么其未上市。

    可以强制VC9 memcpy在我的非sse 2机器上进行矢量化,但是它将破坏FPU堆栈,它似乎也有错误。

    这是我用来测试的full source(再次包括我的更改,请记入http://www.mindcontrol.org/~hplus/作为原始内容)。可根据要求提供项目文件的二进制文件。

    总之,似乎与MSVC crt类似,切换变体可能是最好的,只有更多选项和单次过帐检查(通过内联函数指针?)或更坚固的东西(如内部直接调用)才能使坚固性更强补丁),但是内联可能必须使用最佳情况下的方法

    更新3

    Eshan提出的一个问题提醒了一些有用且与此相关的问题,尽管仅对位集和位操作BitMagic有用,但对于大位集非常有用,它甚至在SSE2 (bit) optimization上有一篇不错的文章。不幸的是,这仍然不是CRT/stdlib风格的类型库。这些项目中的大多数似乎都专门针对(问题)的一小部分。

    这就提出了一个问题,那就是是否值得创建一个开源的,可能是多平台的性能crt/stdlib项目,创建各种版本的标准化功能,每个版本都针对特定情况以及“最佳情况”进行了优化。 '/函数的通用用法变体,具有标量/MMX/SSE/SSE2 +(称为MSVC)的运行时分支或强制编译时标量/SIMD三明治。

    这对于HPC或每个性能都至关重要的项目(例如游戏)很有用,从而使程序员不必担心内置功能的速度,只需要进行少量调整即可找到最佳的优化版本。

    更新4

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

    另外,我看到了很多“仅使用ICC”的答案,那是一个很好的答案,这不是我的答案,因为首先,ICC不是我可以连续使用的东西(除非Intel有免费的学生版) (适用于Windows),由于30次试用。其次,更重要的是,我不仅关注库本身,还关注用于优化/创建它们所包含功能的技术,以进行个人化和改进,因此我可以将此类技术和原理应用于自己的代码中(如果需要),并结合使用这些库。希望可以清除那部分:)

    最佳答案

    这是有关如何使用SIMD指令向量化字符计数的文章:

    http://porg.es/blog/ridiculous-utf-8-character-counting

    10-05 18:28