初探GF-Complete(伽羅瓦運算庫)

GF-Complete 是一個開源、綜合性的伽羅瓦運算庫,相應的文章發表在FAST13 中(見參考文獻【1】)。做者是大名鼎鼎的Jim Plank 教授,做爲開源糾錯碼庫Jerasure 的開發者,在這個伽羅瓦運算庫中創新地採用了SSE 指令集來加速糾錯碼運算的瓶頸---伽羅瓦運算中的乘法運算,並採用了其餘運算方法,綜合獲得GF-Complete。該庫可在Plank 主頁中下載獲得,下面就GF-Complete 庫作簡要分析,詳細可參考文檔【2】。   1、文件的組成 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 的經常使用運算測試;   2、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 中),而後轉置該矩陣獲得逆元素 3、字長和選項 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 - - 」最快的區域乘二   3、源碼分析 先看幾個 .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 = 3二、6四、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) 經過手動輸入參數進行初始化。   參考文獻: 【1】FAST13’:  Screaming Fast Galois Field Arithmetic Using Intel SIMD Instructions.  PDF SLIDE 【2】GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic (version 0.1). PDF 【3】Optimizing Galois Field arithmetic for diverse processor architectures and applications. PDF 【4】Efficient Software Implementations of Large Finite Fields GF(2n) for Secure Storage Applications PDF 【5】An XOR-Based Erasure-Resilient Coding Scheme.  PDF
相關文章
相關標籤/搜索