博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初探GF-Complete(伽罗瓦运算库)
阅读量:2436 次
发布时间:2019-05-10

本文共 4344 字,大约阅读时间需要 14 分钟。

GF-Complete 是一个开源、综合性的伽罗瓦运算库,相应的文章发表在FAST13 中(见参考文献【1】)。作者是大名鼎鼎的Jim Plank 教授,作为开源纠错码库Jerasure 的开发者,在这个伽罗瓦运算库中创新地采用了SSE 指令集来加速纠错码运算的瓶颈---伽罗瓦运算中的乘法运算,并采用了其他运算方法,综合得到GF-Complete。该库可在Plank 主页中下载得到,下面就GF-Complete 库做简要分析,详细可参考文档【2】。
 
一、文件的组成
GF-Complete 有以下文件:
1. gf_complete.h 是应用程序使用的的头文件,所有的其他源程序将生成各自的 .o 文件,所有的 .o 文件将被打包为gf_complete.a ,供应用程序使用。gf_complete.h 包含了通用的数据类型gf_t (GF(2w) 中所有值得类型)和其他运算接口;
2. gf_general.h 中包含了不同大小w 的伽罗瓦域基础运算,尽力消除不同w 大小带来不同数据类型运算的痛苦。文件gf_wgen.c / gf_w4.c / gf_w16.c / gf_w32.c / gf_w64.c / gf_w128.c 分别对应着w<32 / w=4,8,16,32,64,128 的基础运算(加法,乘法,除法,乘2等);
3. gf_rand.h 和gf_rand.c 是一个随机数生成器;
4. gf_int.h 定义了gf_w** 需要使用的一些初始化函数和其他类型;
 
下面几个文件并不是该库所必须的,主要用于测试和例子:
6. gf_mult.c / gf_div.c  / gf_add.c 分别是域上的单个乘法/除法/加法工具;
7. whats_my_sse.c 是用于查看该机器支持哪些指令集,直接通过gcc 可编译;
2. gf_method.h 和 gf_method.c 是用来帮助用户知道自己可以使用的方法(不同处理器支持的指令集不同);
8. gf_time.c / gf_uint.c / gf_ploy.c 分别用于测试速度,单元测试和域中寻找本原多项式;
9. gf_example_1/2/3/4 分别对应着伽罗瓦域上的单个乘法和除法、一块区域乘以一个常量、w=64 的常用运算,w=128 的常用运算测试;
 
二、gf_time
gf_time 是其中一个最重要的测试速度的工具,命令格式如下:
UNIX>gf_time w tests seed buffer-size iterations method
其中w 是位长,大于零小于等于32,或者为64 和128;seed 是用于随机数的种子;buffer-size 为每次运算的区域的大小,iterations 为循环次数(用于测速);最重要的两个参数是tests 和 method,tests 指测试的选项,有以下几种:
‘M’ 单个乘法计算
‘D’ 单个除法计算
 ‘I’    单个元素转置
‘G’  一个随机常量乘以一块区域
‘0’ 零乘以一块区域(等同于bzero())
‘1’ 一乘以一块区域(等同于memcpy() 和 XOR)
‘2’ 二乘以一块区域,这比一般的乘二运算要快(通过移位实现)
‘S’ 所有三种单个测试‘M’,‘D’,‘I’
‘R’ 所有四个区域测试‘G’,‘0’,‘1’,‘2’
‘A’ 所有七个测试
method 是伽罗瓦域上计算采用的技术(取决于机器支持的指令集,现有的伽罗瓦域运算方法和位长w ),通过gf_method 可以查询到对应机器支持的方法,gf_method 有三部分组成:乘法方法,区域乘法方法和除法方法。
乘法对应有以下方法:
 ‘TABLE’          乘法表
 ‘LOG’              对数表
‘LOG_ZERO’ 类似于对数表
 ‘SHIFT’           通过不可约多项式进行移位乘法,速度很慢,参考【3】
 ‘BYTWO_p’    通过循环乘二并选择性异或被乘数得到乘法结果,可以利用到Anvin 乘二的优化
 ‘BYTWO_b’    同上
 ‘SPLIT’            乘法裂表(比如LR表,或者利用SIMD 的表,详见【1】)分别有wa 和wb 两个参数
 ‘GROUP’         使用左右组合表的方法(参考文献【4】)
 ‘COMPOSITE’在一个组合域上进行运算,GF((2l)k) 在参考文献【3】、【4】有介绍
区域乘法有以下方法:
 ‘-’              使用默认方法
 ‘LAZY’      区域乘法前生成查询表
 ‘SSE’        如果有SSE4 指令集,则使用
‘NOSSE’ 不使用SSE4 指令集
‘SINGLE’ 每次查询一个元素运算的表
‘DOUBLE’每次查询两个元素运算的表
 ‘QUAD’     每次查询四个元素运算的表,‘SINGLE’是一般的查询表,之所以有另外两个表,是为了加速较小w 的运算,达到内存使用和计算的均衡
‘STDMAP’使用标准字位对其,内存块分割为连续的字
‘ALTMAP’非标准字位对其,每个字分割在不同的内存块中
‘CAUCHY’将内存分为w 块且仅进行Cauchy Reed-Solomon 中的异或运算【5】
除法有以下方法选择:
 ‘-’               使用默认方法
‘EUCLID’ 使用欧几里得算法,方法慢,但允许使用乘法进行除法计算
‘MATRIX’  将每个元素转化为w×w 大小的bit-matrix(像在Cauchy Reed-Solomon 中),然后转置该矩阵得到逆元素
三、字长和选项
w = 4:
“BYTWO_b SSE -”是默认的区域运算的一半速度,几乎和乘二一样快,但单个运算慢;
“BYTWO_b NOSSE -”是不使用SSE4 指令最快的区域运算方法;
“TABLE QUAD -”是不使用SSE 指令,基于查询表最快的方法;
w = 8:
默认下速度最快
w = 16:
“SPLIT 16 4 SSE,ALTMAP -”这是w = 16时最快的区域乘法,关于这部分算法可以参考【2】
“BYTWO_b SSE -” 这对于区域乘二是最快的选项,但其他乘法就慢了
w = 32:
“SPLIT 32 4 SSE,ALTMAP -” 和w = 16一样,这个比默认方法要快
“SPLIT 8 8 - -” 单个乘法最好的选择,但要预分配1.75MB 内存
“BYTWO_b SSE -” 乘二非常快
“SPLIT 32 8 - -” 不使用SSE4 指令集最快的区域乘法,不使用1.75MB 内存
“COMPOSITE 2 1 SPLIT 16 4 SSE,ALTMAP - ALTMAP -” 对于较大的w,组合(composite)操作是最好的方法,但对于单个乘法计算不友好
w = 64:
“SPLIT 64 4 SSE,ALTMAP -” 这是最快的区域运算,采用128个不同的查找表,单个运算慢,建议使用默认方法
“COMPOSITE 2 1 SPLIT 32 4 SSE,ALTMAP - ALTMAP -”  区域运算也很快
“BYTWO_b SSE -” 这一直是区域乘二的最快方法
w = 128:
“SPLIT 128 4 - -” 方法尚不完善,这是暂时最快的方法
“BYTWO_b - - ”最快的区域乘二
 
三、源码分析
先看几个 .h头文件(gf_complete.h 包含于gf_general.h 和gf_int.h 中)定义了一些数据结构:
gf_general_t  (gf_general.h)代表伽罗瓦域中元素类型,减少w 不同带来不同数据类型运算的痛苦;
 1: typedef union { 
 2: uint32_t w32; 
 3: uint64_t w64; 
 4: uint64_t w128[2]; 
 5: } gf_general_t; 
 
gf_internal_t  (gf_int.h)代表伽罗瓦运算,包含了运算指定的类型和参数;
 1: typedef struct { 
 2: int mult_type; 
 3: int region_type; 
 4: int divide_type; 
 5: int w; 
 6: uint64_t prim_poly; 
 7: int free_me; 
 8: int arg1; 
 9: int arg2; 
 10: gf_t *base_gf; 
 11: void *private; 
 12: } gf_internal_t; 
 
gf_region_data  (gf_int.h)代表一块要进行区域乘法计算的内存块;
 1: typedef struct { 
 2: gf_t *gf; 
 3: void *src; 
 4: void *dest; 
 5: int bytes; 
 6: uint64_t val; 
 7: int xor; 
 8: int align; 
 9: void *s_start; 
 10: void *d_start; 
 11: void *s_top; 
 12: void *d_top; 
 13: } gf_region_data; 
 
gf_val_32_t , gf_val_64_t , gf_val_128_t 分别作为w = 32、64、128时伽罗瓦域中的元素类型,是uint32_t,uint64_t 和uint64_t * 的别名。
gf_func_a_b 是两个元素乘法或除法的函数指针,对于不同w 有三种函数指针;
gf_func_a     是一个元素求逆的函数指针
gf_func_region 是一个元素乘以一个区域的函数指针
gf_t  是一个伽罗瓦域运算的结构体,某个gf_t的实例(且允许我这么说)代表了一个伽罗瓦域的运算方法
 1: typedef struct gf { 
 2: gf_func_a_b multiply; 
 3: gf_func_a_b divide; 
 4: gf_func_a inverse; 
 5: gf_region multiply_region; 
 6: gf_extract extract_word; 
 7: void *scratch; 
 8: } gf_t; 
这些结构通过gf_free 释放空间
 但一个应用程序调用这些方法时,需要指定参数进行初始化,比如生成查找表等,这些可以通过gf_init_easy() 和gf_init_hard(),前者是后者的一个默认参数的选择,如果手动选择参数调用后者即可。也可以通过提供的create_gf_from_argv(&gf, w, argc, argv, 6) 通过手动输入参数进行初始化。

转载地址:http://ougmb.baihongyu.com/

你可能感兴趣的文章
企业文化和价值观
查看>>
推荐书籍:金字塔原理
查看>>
基础存储知识
查看>>
PostgreSQL 源码解读(37)- 查询语句#22(查询优化-grouping_plan...
查看>>
PostgreSQL 源码解读(44)- 查询语句#29(等价类相关数据结构)
查看>>
PostgreSQL 源码解读(48)- 查询语句#33(query_planner函数#9)
查看>>
PostgreSQL 源码解读(45)- 查询语句#30(query_planner函数#6)
查看>>
PostgreSQL 源码解读(47)- 查询语句#32(query_planner函数#8)
查看>>
PostgreSQL 源码解读(17)- 查询语句#2(查询优化基础)
查看>>
Windows Vista内置趣味实用工具大搜罗(转)
查看>>
FreeBSD安装文件系统(转)
查看>>
最简单FreeBSD网关方案(转)
查看>>
Windows 98 多用户的管理(转)
查看>>
更改Windows XP 的日期和时间(转)
查看>>
windows2000中的“秘密武器”(三)(转)
查看>>
Linux程序应用开发环境和工具经验谈(转)
查看>>
Linux办公一条龙之电子表格Calc(转)
查看>>
在NETBSD上配置ADSL+IPF+IPNAT(转)
查看>>
Windows 98 使用维护向导(转)
查看>>
用win2000收发传真(转)
查看>>