- 论坛徽章:
- 9
|
本帖最后由 wlmqgzm 于 2015-10-29 11:06 编辑
自修复协议栈, 内部校验用的, Crc32c部分的代码. 全部是自己敲出来的代码, 版权所有.
硬件CRC32的全部代码, 用于实现高速校验的. 利用Intel SSE4.2指令实现超高速硬件级CRC32校验- #include <cpuid.h>
- #include <boost/crc.hpp>
- #include "error_message.hpp"
- #ifndef _crc32c_hpp
- #define _crc32c_hpp
- class Crc32c
- {
- public:
- Crc32c();
- unsigned int value( const char *chars, unsigned int int_length );
- unsigned int value( std::string &str_in );
- #ifdef DEBUG
- int test( const char *chars=NULL, unsigned int int_length=0 );
- #endif // DEBUG
- private:
- boost::crc_optimal<32, 0x1EDC6F41, 0, 0, true, true> boost_crc1;
- bool is_select_sse_u64;
- bool is_select_sse_u8;
- unsigned int intel_crc32c_u8( const char *chars, unsigned int int_length );
- unsigned int intel_crc32c_u64( const char *chars, unsigned int int_length );
- bool bool_cpu_is_support_sse4_2(void);
- unsigned int boost_crc32c_u8( const char *chars, unsigned int int_length );
- };
- Crc32c::Crc32c()
- {
- char *chars = NULL;
- unsigned int address_size = sizeof(chars); // =8判断地址长度是64位, =4判断是32位
- is_select_sse_u64 = false;
- is_select_sse_u8 = false;
- if( bool_cpu_is_support_sse4_2() ) {
- if(address_size>=8) is_select_sse_u64 = true; // =8判断地址长度是64位, =4判断是32位
- else is_select_sse_u8 = true;
- }
- return;
- }
- unsigned int Crc32c::intel_crc32c_u8( const char *chars, unsigned int int_length )
- {
- const char *p_begin;
- const char *p_end;
- unsigned int int_crc = 0;
- p_begin = chars;
- p_end = chars + int_length;
- while( p_begin < p_end ) {
- int_crc = _mm_crc32_u8(int_crc,*p_begin);
- ++p_begin;
- continue;
- }
- return int_crc;
- }
- // 要求 支持64位CPU指令, 支持SSE4.2
- // 运行64位系统, 测试发现即使不是8字节位对齐,也可以正常运行
- unsigned int Crc32c::intel_crc32c_u64( const char *chars, unsigned int int_length )
- {
- unsigned long long *long_begin;
- unsigned long long *long_end;
- unsigned int i ;
- unsigned int n ;
- unsigned int long_long_size = sizeof(unsigned long long);
- //if( int_length<long_long_size) return intel_crc32c_u8( chars, int_length );
- // 可省略, 可以处理特殊情况
- unsigned int int_crc = 0;
- long_begin = (unsigned long long*) chars;
- long_end = long_begin + (int_length/long_long_size);
- while( long_begin < long_end ) {
- int_crc = _mm_crc32_u64(int_crc, *long_begin);
- ++long_begin;
- continue;
- }
- i = int_length/long_long_size*long_long_size;
- n = int_length;
- while( i < n ) {
- int_crc = _mm_crc32_u8(int_crc,chars[i]);
- ++i;
- continue;
- }
- return int_crc;
- }
- /* 判断处理器是否支持SSE4.2,应采取如下方法: true if CPUID.01H:ECX.SSE4_2[bit 20] = 1
- eax == 1,则在eax中返回Family/Model/Stepping等信息, 在EBX ECX和EDX返回一些信息
- // ecx define bit_SSE4_2 (1 << 20) */
- bool Crc32c::bool_cpu_is_support_sse4_2(void)
- {
- #ifdef __cpuid // 在cpuid.h中定义
- unsigned int eax, ebx, ecx, edx;
- __cpuid(1, eax, ebx, ecx, edx);
- if(ecx & bit_SSE4_2) {
- //log_message("cpu support SSE4.2",5);
- return true;
- }
- #endif // __cpuid
- if( g_display_level_default>=2 ) warn_message("__cpuid define not find. No use intel sse4.2 in crc32c. ");
- return false;
- }
- unsigned int Crc32c::boost_crc32c_u8( const char *chars, unsigned int int_length )
- {
- boost_crc1.reset(0);
- boost_crc1.process_bytes(chars, int_length);
- return boost_crc1.checksum();
- }
- unsigned int Crc32c::value( const char *chars, unsigned int int_length )
- {
- if( is_select_sse_u64 ) {
- return intel_crc32c_u64( chars, int_length );
- }
- // 32位系统,选择最简单的单字节提交, 不考虑做优化32位的代码了,因为32位系统已经淘汰了,不值得做更多代码
- if(is_select_sse_u8) {
- return intel_crc32c_u8( chars, int_length );
- }
- // 不支持SSE4.2的CPU, 还是软件方式吧.
- return boost_crc32c_u8( chars, int_length );
- }
- unsigned int Crc32c::value( std::string &str_in )
- {
- if( is_select_sse_u64 ) {
- return intel_crc32c_u64( str_in.c_str(), str_in.length() );
- }
- // 32位系统,选择最简单的单字节提交, 不考虑做优化32位的代码了,因为32位系统已经淘汰了,不值得做更多代码
- if(is_select_sse_u8) {
- return intel_crc32c_u8( str_in.c_str(), str_in.length() );
- }
- // 不支持SSE4.2的CPU, 还是软件方式吧.
- return boost_crc32c_u8( str_in.c_str(), str_in.length() );
- }
- // 下面为开发过程中的测试程序, 已经验证了程序的正确性.
- #ifdef DEBUG
- int Crc32c::test( const char *chars_in, unsigned int int_length_in)
- {
- int int_ret1;
- int int_ret2;
- int int_ret3;
- int int_ret = 0;
- char *chars ;
- unsigned int int_length=10000000;
- unsigned int i;
- bool bool_chars_need_delete;
- if(0==int_length_in||NULL==chars_in) {
- chars = new char[int_length];
- if(NULL==chars) {
- error_message("memory require failed.");
- return -1;
- }
- bool_chars_need_delete = true;
- for (i = 0; i <int_length; ++i) chars[i] = i;
- }
- else {
- int_length = int_length_in;
- chars = (char *)chars_in;
- bool_chars_need_delete = false;
- }
- for(i=0;i<2;++i) { // 循环执行2次
- {
- boost::timer::auto_cpu_timer a1;
- int_ret1 = boost_crc32c_u8( chars, int_length );
- log_message_int("boost_crc32c_u8",int_ret1);
- }
- {
- boost::timer::auto_cpu_timer a2;
- int_ret2 = intel_crc32c_u8( chars, int_length );
- log_message_int("intel_crc32c_u8",int_ret2);
- }
- {
- boost::timer::auto_cpu_timer a3;
- int_ret3 = intel_crc32c_u64( chars, int_length );
- log_message_int("intel_crc32c_u64",int_ret3);
- }
- if(int_ret1!=int_ret2) {
- int_ret = -2;
- error_message("boost_crc32c_u8 <> intel_crc32c_u8. ");
- }
- if(int_ret2!=int_ret3) {
- int_ret = -3;
- error_message("intel_crc32c_u8 <> intel_crc32c_u64");
- }
- }
- if(bool_chars_need_delete && NULL!=chars) {
- delete chars;
- chars = NULL;
- }
- if(0==int_ret) log_message("crc32c test run ok. no error find. ");
- return int_ret;
- }
- #endif // DEBUG
- #endif // _crc32c_hpp
复制代码 |
|