比常规CRC32C算法快12倍的优化.

Reverse.King 2011-06-13 04:22:26
加精
CRC-32C (Castagnoli) 算法是 iSCSI 和SCTP 数据校验的算法,和常用CRC-32-IEEE 802.3算法所不同的是多项式常数CRC32C是0x1EDC6F41 ,CRC32是0x04C11DB7 ,也就是说由此生成的CRC表不同外算法是一模一样.



CRC32 常规算法如下:


function _CRC32CX86(Data: PByte; aLength: Integer): DWORD;
const
_CRC32CTable: array[0..255] of DWORD = (
$00000000, $F26B8303, $E13B70F7, $1350F3F4, //CRC32C Table
$C79A971F, $35F1141C, $26A1E7E8, $D4CA64EB,
$8AD958CF, $78B2DBCC, $6BE22838, $9989AB3B,
$4D43CFD0, $BF284CD3, $AC78BF27, $5E133C24,
$105EC76F, $E235446C, $F165B798, $030E349B,
$D7C45070, $25AFD373, $36FF2087, $C494A384,
$9A879FA0, $68EC1CA3, $7BBCEF57, $89D76C54,
$5D1D08BF, $AF768BBC, $BC267848, $4E4DFB4B,
$20BD8EDE, $D2D60DDD, $C186FE29, $33ED7D2A,
$E72719C1, $154C9AC2, $061C6936, $F477EA35,
$AA64D611, $580F5512, $4B5FA6E6, $B93425E5,
$6DFE410E, $9F95C20D, $8CC531F9, $7EAEB2FA,
$30E349B1, $C288CAB2, $D1D83946, $23B3BA45,
$F779DEAE, $05125DAD, $1642AE59, $E4292D5A,
$BA3A117E, $4851927D, $5B016189, $A96AE28A,
$7DA08661, $8FCB0562, $9C9BF696, $6EF07595,
$417B1DBC, $B3109EBF, $A0406D4B, $522BEE48,
$86E18AA3, $748A09A0, $67DAFA54, $95B17957,
$CBA24573, $39C9C670, $2A993584, $D8F2B687,
$0C38D26C, $FE53516F, $ED03A29B, $1F682198,
$5125DAD3, $A34E59D0, $B01EAA24, $42752927,
$96BF4DCC, $64D4CECF, $77843D3B, $85EFBE38,
$DBFC821C, $2997011F, $3AC7F2EB, $C8AC71E8,
$1C661503, $EE0D9600, $FD5D65F4, $0F36E6F7,
$61C69362, $93AD1061, $80FDE395, $72966096,
$A65C047D, $5437877E, $4767748A, $B50CF789,
$EB1FCBAD, $197448AE, $0A24BB5A, $F84F3859,
$2C855CB2, $DEEEDFB1, $CDBE2C45, $3FD5AF46,
$7198540D, $83F3D70E, $90A324FA, $62C8A7F9,
$B602C312, $44694011, $5739B3E5, $A55230E6,
$FB410CC2, $092A8FC1, $1A7A7C35, $E811FF36,
$3CDB9BDD, $CEB018DE, $DDE0EB2A, $2F8B6829,
$82F63B78, $709DB87B, $63CD4B8F, $91A6C88C,
$456CAC67, $B7072F64, $A457DC90, $563C5F93,
$082F63B7, $FA44E0B4, $E9141340, $1B7F9043,
$CFB5F4A8, $3DDE77AB, $2E8E845F, $DCE5075C,
$92A8FC17, $60C37F14, $73938CE0, $81F80FE3,
$55326B08, $A759E80B, $B4091BFF, $466298FC,
$1871A4D8, $EA1A27DB, $F94AD42F, $0B21572C,
$DFEB33C7, $2D80B0C4, $3ED04330, $CCBBC033,
$A24BB5A6, $502036A5, $4370C551, $B11B4652,
$65D122B9, $97BAA1BA, $84EA524E, $7681D14D,
$2892ED69, $DAF96E6A, $C9A99D9E, $3BC21E9D,
$EF087A76, $1D63F975, $0E330A81, $FC588982,
$B21572C9, $407EF1CA, $532E023E, $A145813D,
$758FE5D6, $87E466D5, $94B49521, $66DF1622,
$38CC2A06, $CAA7A905, $D9F75AF1, $2B9CD9F2,
$FF56BD19, $0D3D3E1A, $1E6DCDEE, $EC064EED,
$C38D26C4, $31E6A5C7, $22B65633, $D0DDD530,
$0417B1DB, $F67C32D8, $E52CC12C, $1747422F,
$49547E0B, $BB3FFD08, $A86F0EFC, $5A048DFF,
$8ECEE914, $7CA56A17, $6FF599E3, $9D9E1AE0,
$D3D3E1AB, $21B862A8, $32E8915C, $C083125F,
$144976B4, $E622F5B7, $F5720643, $07198540,
$590AB964, $AB613A67, $B831C993, $4A5A4A90,
$9E902E7B, $6CFBAD78, $7FAB5E8C, $8DC0DD8F,
$E330A81A, $115B2B19, $020BD8ED, $F0605BEE,
$24AA3F05, $D6C1BC06, $C5914FF2, $37FACCF1,
$69E9F0D5, $9B8273D6, $88D28022, $7AB90321,
$AE7367CA, $5C18E4C9, $4F48173D, $BD23943E,
$F36E6F75, $0105EC76, $12551F82, $E03E9C81,
$34F4F86A, $C69F7B69, $D5CF889D, $27A40B9E,
$79B737BA, $8BDCB4B9, $988C474D, $6AE7C44E,
$BE2DA0A5, $4C4623A6, $5F16D052, $AD7D5351);
var
i: Integer;
begin
Result := $FFFFFFFF;
for I := 0 to aLength - 1 do
begin
Result := (Result shr 8) xor _CRC32CTable[(Result and $FF) xor Data^];
Inc(Data);
end;
Result := not Result;
end;



CRC32C使用SSE4.2硬件指令优化算法部分代码如下:


function _CRC32CSSE(Data: PByte; aLength: Integer): DWORD;
asm
push esi
push edx
push ecx
mov esi,eax
mov eax,$FFFFFFFF
test edx,edx
jz @Exit
test esi,esi
jz @Exit
mov ecx,edx
shr ecx, 2
test ecx,ecx
jz @Exit
xor edx,edx
@Alignment:
crc32 eax,[edx*4+esi]
inc edx
cmp edx,ecx
jb @Alignment
@Exit:
not eax
pop ecx
pop edx
pop esi
end;


以上2个不同实现方式在Intel Core i7 720QM 1.60GHz CPU上测试成绩如下:

(数据采用随机算法生成,1M*100表示使用1M数据进行100次重复计算,数据量相当于100M)

--------------------------------------------------------------------------------------

| 数据量 | 常规算法时间 | 优化算法时间 | 快出百分比 |

--------------------------------------------------------------------------------------

| 1M *100 | X86 Time:390ms | SSE Time:32ms | 1218% |

--------------------------------------------------------------------------------------

| 4M *100 | X86 Time:1575ms | SSE Time:156ms | 1009% |

--------------------------------------------------------------------------------------

| 8M *100 | X86 Time:3136ms | SSE Time:280ms | 1120% |

--------------------------------------------------------------------------------------

| 32M *100 | X86 Time:12542ms | SSE Time:1092ms | 1148% |

--------------------------------------------------------------------------------------

通过对比可以清楚的看到使用SSE4.2中的新指令crc32可以比常规CRC32C算法要快出最少10倍的效率,Intel新增的指令确实对常规某些算法提供了高效的解决方案,使用好它们将对我们在以后的开发中得到质的提升。

...全文
6430 113 打赏 收藏 转发到动态 举报
写回复
用AI写文章
113 条回复
切换为时间正序
请发表友善的回复…
发表回复
Reverse.King 2011-06-25
  • 打赏
  • 举报
回复
另外CRC32-C的算法的确使用在硬件层数据校验,比如iSCSI(一种使用网络来连接的阵列储存协议)上,或者串流控制传输协议(Stream Control Transmission Protocol ) SCTP也就是IP上传输的电话协议上。
Reverse.King 2011-06-25
  • 打赏
  • 举报
回复
[Quote=引用 104 楼 delphiguy 的回复:]
引用 103 楼 dfasri 的回复:

不知道系统会不会在SOCKET的处理上, 采用SSE4进行优化呢...毕竟每个网络包都有CRC32验证的...


没有。TCP、UDP的checksum、IP的header checksum都是只是简单的累加、取反算法,不是CRC。
ETHERNET、SATA的数据链路层使用CRC32,不过是标准算法,不是CRC32C,PCI-E的数据链路……
[/Quote]
不同意你的看法,SSE4的CRC出来肯定有用处,用来做快速文件校验完全没有问题。
  • 打赏
  • 举报
回复
[Quote=引用 110 楼 codegame 的回复:]

不同意你的看法,SSE4的CRC出来肯定有用处,用来做快速文件校验完全没有问题。
[/Quote]

我是针对103楼所说“毕竟每个网络包都有CRC32验证的”而言的。

“用来做快速文件校验完全没有问题”,是没有问题,关键是CRC-32C并非文件校验的标准算法,winrar、winzip之类的软件都使用标准CRC-32,emule的文件hash使用SHA-1,没谁使用CRC-32C。当然某个用户可以自己使用,仅限于自娱自乐,没有比较意义。

另外,你给出的代码是有问题的,这么长时间你也不更新一下,对于别人有误导之嫌。
一是你的代码只计算长度为4的倍数的数据,结果大多数情况下是错的;二是没有传入初始CRC的功能,用于校验文件只能是一次性装入buffer,不能分块装入,分块装入的话,你的代码计算结果是错误的。
luquansen 2011-06-23
  • 打赏
  • 举报
回复
老实说,我看不懂
szhjm 2011-06-22
  • 打赏
  • 举报
回复
mark一下
vrv15 2011-06-22
  • 打赏
  • 举报
回复
studying studying
dfasri 2011-06-21
  • 打赏
  • 举报
回复
不知道系统会不会在SOCKET的处理上, 采用SSE4进行优化呢...毕竟每个网络包都有CRC32验证的...
mjp1234airen4385 2011-06-21
  • 打赏
  • 举报
回复
这个算法,等大家都使用i系列的cpu就可以普及了。
zlcp520 2011-06-21
  • 打赏
  • 举报
回复
内容存入剪贴板
liubiti1983 2011-06-21
  • 打赏
  • 举报
回复
看不懂啊,厉害
gabby123 2011-06-21
  • 打赏
  • 举报
回复
我也还是不能下载啊
  • 打赏
  • 举报
回复
[Quote=引用 103 楼 dfasri 的回复:]

不知道系统会不会在SOCKET的处理上, 采用SSE4进行优化呢...毕竟每个网络包都有CRC32验证的...
[/Quote]

没有。TCP、UDP的checksum、IP的header checksum都是只是简单的累加、取反算法,不是CRC。
ETHERNET、SATA的数据链路层使用CRC32,不过是标准算法,不是CRC32C,PCI-E的数据链路层使用CRC16,都是硬件实现的,SSE4屁用也没有。
aichiyuderen 2011-06-21
  • 打赏
  • 举报
回复
完全不懂什么。。 看来路还很长了哦。。
cwm5511 2011-06-19
  • 打赏
  • 举报
回复
谢谢分享,学习了!!!
cedricporter 2011-06-18
  • 打赏
  • 举报
回复
MARK...
jr53770 2011-06-18
  • 打赏
  • 举报
回复
没意思 也不给分
shexunyu 2011-06-18
  • 打赏
  • 举报
回复
路过 学习下
子达如何 2011-06-17
  • 打赏
  • 举报
回复
MARK,可惜不知道可移植性如何
wasu125 2011-06-17
  • 打赏
  • 举报
回复
我来学习一下哈
差布多先生 2011-06-16
  • 打赏
  • 举报
回复
那么叼啊
加载更多回复(85)

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧