龙空技术网

ISA-L加速库介绍以及在SPDK中的集成

编码小哥 102

前言:

现时小伙伴们对“isa算法”大致比较讲究,咱们都想要了解一些“isa算法”的相关内容。那么小编也在网络上收集了一些有关“isa算法””的相关知识,希望朋友们能喜欢,我们一起来学习一下吧!

转载自DPDK与SPDK开源社区公众号

ISA-L分为了isa-l_pub版本和isa-l_crypto版本, 如图1所示。前者主要包含了在存储领域的一些算法,后者主要包含的是密码学的一些算法,包括在最新版本中增加了高性能SM3算法的支持。

图 1 ISA-L 库概况

ISA-L的运算快的主要原因是用了SIMD。那么SIMD是什么呢?SIMD(Single Instruction Multiple Data)的中文释义是单指令流多数据流。顾名思义,就是单条指令,可以处理多条数据流。举个具体例子,如图2所示,我们存在两个数组,分别存了4个int,如果需要下标相同的元素相加的话,正常代码需要写一个循环,分别加4次再存到数组中。而在SIMD中,只需要做一次add操作就可以完成。并且SIMD中的寄存器每一个小块的空间也是相对独立的(当然不同指令集的操作长度也不同),和数组一样,下标为1的数值相加溢出后,不会影响到下标0的数值。

图 2 SIMD add指令示例

从最早的MMX,到后来的SSE(包括SSE、SSE2、SSE3、SSE4)、AVX,AVX2,再到如今的AVX512指令集,都是SIMD的指令集。而ISA-L的核心就是对于SIMD的使用,将指令集运算细节封装,再暴露出上层C的接口,以达到加速的目的。对于不同的SIMD指令集,运算寄存器组有如下区别:SSE :XMM0 ~ XMM7 , 提供了8个128位寄存器SSE(x86-64) : XMM0 ~ XMM15,提供了16个128位寄存器AVX(AVX-128): XMM0 ~ XMM15,寄存器同于SSE(x86-64),不同于SSE的是,提供了更为多且方便的运算指令,比如使用vshufps代替shufps。AVX2(AVX-256): YMM0 ~ YMM15,提供了16个256位寄存器。提供了更多的运算指令。AVX512:ZMM0 ~ ZMM31,提供了32个512位寄存器。提供了更多的运算指令。值得一提的是,AVX512的ZMM寄存器和AVX2的YMM寄存器有着重叠的关系,AVX2的YMM寄存器组和SSE的XMM寄存器组同样存在着重叠的关系。 举个例子,当你机器同时拥有AVX512和AVX2指令集时,当你操作YMM0的时候,会改变ZMM0低位256位的寄存器组。它们的关系如图3所示:

图 3 XMM, YMM, ZMM 寄存器之间的关系

所以,当你混用不同指令集的时候,需要注意指令集的操作范围,防止得出来的计算结果只能正确一部分。SIMD基本原理介绍完了,那么ISA-L是如何使用SIMD来加速运算的呢?首先,在项目include目录下有一个multibinary.asm汇编文件,该文件提供了一系列的汇编方法名为mbin_dispatch_init,而在ISA-L中的每一种算法都必须注册这个汇编方法,该方法会检查你的CPU flag,来获得支持的指令集,从而进行数据流的分发。举个例子,当你调用ISA-L中sha256的方法,ISA-L会检测到你的CPU只支持AVX2,那么会把数据流分发到AVX2的汇编算法进行下一步操作。而当ISA-L分发好了数据流,选定了计算所用的指令集后,就会将数据流从内存填充到具体的寄存器,再调用具体的指令集进行算法计算。一般来说,在内存中的数据流都是由多段buffer组成的,这样对于SIMD来说是友好的。举个例子,当用户需要计算多个数据的hash结果时,用户将数据放到内存中,组成一个char *的数组。再调用ISA-L的接口,得到一个存了所有计算好hash的数组。而在中间过程中,无论用户放到内存中的数组有多长,ISA-L每次只取出固定lane的数据进行计算(lane指的是一次计算能处理的最大长度,比如名为sha256_mb_x16_avx512.asm实现的axv512版本的sha256,x16代表了一次可以取16个lane的数据,对应到数组为取16个元素),但是用户输入的数据中,单个元素中的char *长度可能有长有短,比如图4 中的data2,因为数据过长,在第一次hash过程中,只处理了部分数据,得到了一个中间值,那么它将加入下一轮计算,而data1已经计算完成了,那么会填充到内存中,不再经过下一轮计算。

图 4 ISA-L中hash计算

除了SIMD之外,ISA-L也支持了一些比较“另类”的指令集,比如SHANI,这是为了加速少量数据HASH而设计的,之前说过SHA256的AVX512版本一次处理16个lane的数据,但是但用户一次提交的数据数目过少,或者SIMD计算后只剩下单个或两个过长的buffer没有计算完,SHANI就可以加速这种情况。当然除了SHANI之外,ISA-L同样也用了AESNI指令集对AES进行加速。另外在ISA-L中,为了减少内存的throughput,我们尽量的避免了在算法过程中使用栈,为了代替栈的使用,我们尽量的使用寄存器作为暂存数据(当然这也带来了代码的可读性降低)。但是在一些情况下也是不可避免的使用了栈进行缓存,比如当你的寄存器已经占满,不够用的时候,或者算法要求的预运算值会占用比较大的空间。这也是另外一点ISA-L计算快的原因。

二ISA-L支持的算法

isa-l_pub目前版本(v2.30.0)包含了以下算法:EC(erasure codes) : 类型为Reed-Solomon编码的纠错码,使用了GF(2^8),并且提供了一些有限域内运算的接口。CRC(Cyclic Redundancy Check) : 支持iscsi32, ieee32, t10dif, ecma64, iso64, jones64多项式的循环冗余校验,不同的标准返回的crc长度也是不同的。Raid(Redundant Array of Independent Disks) : 并不是支持磁盘阵列的标准,而是支持raid标准中经常需要用到的XOR和P + Q运算。Igzip(ISA-L GNU ZIP) : 主要支持deflate和inflate算法,同时也支持了GNU ZIP的头部信息的写入和解析。isa-l_crypto目前版本(v2.23.0)包含了以下算法:Multi-buffer hashes : 包含了标准SHA1、SHA256、SHA512、MD5、SM3的hash算法集。MH (Multi hashes) : 自研hash算法,包含了mh-sha1和mh-sha256。它的设计为了串行的hash过程 ,设计核心是将单个的buffer分组为多个块进行SIMD过程, 有兴趣的读者可以看看multi-hash-paper(在文末点击“阅读原文”即可)。(注意:mh1-sha256得出的结果和标准sha256得出的结果并不一致。)AES(Advanced Encryption Standard) : 标准的AES算法,支持GCM、CBC、XTS三种模式,并且支持128位、192位、256位密钥长度。Rolling hash : 标准的划窗hash

三ISA-L的使用

要进行编译以及安装库,通常只需运行如下即可:

./autogen.sh./configuremakesudo make install

对于isa-l_pub来说,如果需要编译target:make check : 编译并运行基本的运行测试,测试包含了一些内置的测试集make tests : 编译并运行基本的单元测试make perfs : 编译并运行isa-l_pub的性能测试软件,将会和openssl对比性能make ex : 编译内置的example,并非所有算法都有examplemake other : 编译工具集,目前isa-l_pub只提供了igzip的一个工具集。make doc : 编译创建api文档对于isa-l_crypto来说,由于isa-l_crypto并没有额外的工具集提供,所以并没有make other选项提供。其他的编译target的选项和isa-l_pub一致。当你构建并安装好ISA-L后,默认情况下头文件安装在/usr/include,库文件安装在/usr/lib64/下。你可以将相应的库和头文件引入项目即可使用。但是在接口方面,ISA-L的和openssl的并不完全一致。对于一些算法来说,ISA-L提供了example和工具来展示接口如何使用,这并不是全部算法都包含的。这个时候,你可以参考算法的API文档或者相应的tests来编写自己的应用程序。再或者,如果你目前的项目使用的是openssl,想切换到isa-l,那么你可以参考一下ISA-L中带有rand test的测试案例,这种测试案例都是和openssl进行对比测试。拿sha256_mb/sha256_mb_rand_ssl_test.c为例,这里ISA-L用了自己的sha256接口和openssl的接口分别运算同一串字符串,得到结果进行对比测试。调用openssl的接口用到了SHA256()函数,但我们ISA-L的接口却用到了三个函数:sha256_ctx_mgr_init : 初始化sha256的ctxsha256_ctx_mgr_submit : 将ctx里面的数据提交sha256_ctx_mgr_flush : 将ctx未计算完的数据全计算完成我们接口能接收的数据是多个buffer,而非单串字符串。接收多个buffer后,使用SIMD,性能自然是openssl的数倍,当然我们也能够提供提个类似于openssl SHA256的接口,但是这并不符合ISA-L设计的初衷。

四SPDK/DPDK中 ISA-L的支持情况

在DPDK中,ISA-L帮助DPDK构建了 Compression dev和 crypto dev,具体使用情况如下:在Compression dev中使用DEFLATE接口(包含在igzip中),来帮助PMD进行压缩/解压操作CRC32,来帮助PMD进行数据完整性校验在crypto dev中AES,帮助PMD进行AES的加密/解密操作HASH,帮助PMD对数据进行hash操作而在SPDK中,ISA-L作为一个git submodule被包含了进去,在很多地方也有使用ISA-L,具体如下:SPDK中提供了vbdev_crypto和vbdev_compress,这是借助于DPDK中Compression dev和crypto dev实现的,底层同样运行了ISA-LISA-L的CRC被SPDK封装成了一个util,在blobstore,tcp,iscsi,ftl,ocf等模块中都有用到。

标签: #isa算法