C# 4.0 校验和算法的并行优化?

C# 4.0 校验和算法的并行优化?,c#-4.0,parallel-processing,crc,C# 4.0,Parallel Processing,Crc,下面的代码示例是我在一个项目中使用的CRC-CCITT的实现 public static unsafe ushort CRC(byte * it, byte * end) { unchecked { ushort crc = 0xFFFF; ushort quick = 0; for (;;)

下面的代码示例是我在一个项目中使用的CRC-CCITT的实现

public static unsafe ushort CRC(byte * it, byte * end)
            {
                unchecked
                {
                    ushort crc = 0xFFFF;
                    ushort quick = 0;

                for (;;)
                {
                    ushort tmp = (ushort)((crc >> 8) ^ (*it));
                    crc <<= 8;

                    quick = (ushort)(tmp ^ (tmp >> 4));
                    crc ^= quick;

                    quick <<= 5;
                    crc ^= quick;

                    quick <<= 7;
                    crc ^= quick;

                    if (it == end)
                        break;
                    it++;
                }
                return crc;
            }
        }
问:上面的多项式不过是一系列的加法/乘法运算。数学的基本定律表明加法/乘法运算是可互换的,因此表达式如下:

SUM(从1到10)==SUM(从1到5)+SUM(从6到10)
为真

我需要优化上面的代码,它可能是我的项目中调用频率最高的代码(至少120次/秒)。考虑到上述情况,使用CRC校验和是否可行?我正在考虑使用Parallel.For(…)来做这个把戏,这有意义吗?有人有什么建议吗

更新:


实际上,每次连接120次。我正在处理至少15个同时传入的连接,数据速率为120[Hz]等。字节数组可能会有所不同-理论上最大值为65k字节,但这种情况很少发生,通常约为1k字节。

这能解决您的问题吗? (对不起,我不知道如何避开已删除的帖子!)

//灵感来自http://automationwiki.com/index.php?title=CRC-16-CCITT
静态ushort[]crc\U表={
0x0000、0x1021、0x2042、0x3063、0x4084、0x50a5、,
0x60c6、0x70e7、0x8108、0x9129、0xa14a、0xb16b、,
0xc18c、0xd1ad、0xe1ce、0xf1ef、0x1231、0x0210、,
0x3273、0x2252、0x52b5、0x4294、0x72f7、0x62d6、,
0x9339、0x8318、0xb37b、0xa35a、0xd3bd、0xc39c、,
0xf3ff、0xe3de、0x2462、0x3443、0x0420、0x1401、,
0x64e6、0x74c7、0x44a4、0x5485、0xa56a、0xb54b、,
0x8528、0x9509、0xe5ee、0xf5cf、0xc5ac、0xd58d、,
0x3653、0x2672、0x1611、0x0630、0x76d7、0x66f6、,
0x5695、0x46b4、0xb75b、0xa77a、0x9719、0x8738、,
0xf7df、0xe7fe、0xd79d、0xc7bc、0x48c4、0x58e5、,
0x6886、0x78a7、0x0840、0x1861、0x2802、0x3823、,
0xc9cc、0xd9ed、0xe98e、0xf9af、0x8948、0x9969、,
0xa90a、0xb92b、0x5af5、0x4ad4、0x7ab7、0x6a96、,
0x1a71、0x0a50、0x3a33、0x2a12、0xdbfd、0xcbdc、,
0xfbbf、0xeb9e、0x9b79、0x8b58、0xbb3b、0xab1a、,
0x6ca6、0x7c87、0x4ce4、0x5cc5、0x2c22、0x3c03、,
0x0c60、0x1c41、0xedae、0xfd8f、0xcdec、0xddcd、,
0xad2a、0xbd0b、0x8d68、0x9d49、0x7e97、0x6eb6、,
0x5ed5、0x4ef4、0x3e13、0x2e32、0x1e51、0x0e70、,
0xff9f、0xefbe、0xdfdd、0xcffc、0xbf1b、0xaf3a、,
0x9f59、0x8f78、0x9188、0x81a9、0xb1ca、0xa1eb、,
0xd10c、0xc12d、0xf14e、0xe16f、0x1080、0x00a1、,
0x30c2、0x20e3、0x5004、0x4025、0x7046、0x6067、,
0x83b9、0x9398、0xa3fb、0xb3da、0xc33d、0xd31c、,
0xe37f、0xf35e、0x02b1、0x1290、0x22f3、0x32d2、,
0x4235、0x5214、0x6277、0x7256、0xb5ea、0xa5cb、,
0x95a8、0x8589、0xf56e、0xe54f、0xd52c、0xc50d、,
0x34e2、0x24c3、0x14a0、0x0481、0x7466、0x6447、,
0x5424、0x4405、0xa7db、0xb7fa、0x8799、0x97b8、,
0xe75f、0xf77e、0xc71d、0xd73c、0x26d3、0x36f2、,
0x0691、0x16b0、0x6657、0x7676、0x4615、0x5634、,
0xd94c、0xc96d、0xf90e、0xe92f、0x99c8、0x89e9、,
0xb98a、0xa9ab、0x5844、0x4865、0x7806、0x6827、,
0x18c0、0x08e1、0x3882、0x28a3、0xcb7d、0xdb5c、,
0xeb3f、0xfb1e、0x8bf9、0x9bd8、0xabbb、0xbb9a、,
0x4a75、0x5a54、0x6a37、0x7a16、0x0af1、0x1ad0、,
0x2ab3、0x3a92、0xfd2e、0xed0f、0xdd6c、0xcd4d、,
0xbdaa、0xad8b、0x9de8、0x8dc9、0x7c26、0x6c07、,
0x5c64、0x4c45、0x3ca2、0x2c83、0x1ce0、0x0cc1、,
0xef1f、0xff3e、0xcf5d、0xdf7c、0xaf9b、0xbfba、,
0x8fd9、0x9ff8、0x6e17、0x7e36、0x4e55、0x5e74、,
0x2e93、0x3eb2、0x0ed1、0x1ef0
};
公共静态不安全ushort CRC(字节*it,字节*end)
{
ushort crc=0;
乌斯波特温度;
做
{
temp=(ushort)((*it^(crc>>8))&0xff);

crc=(ushort)(crc_表[temp]^(crc)为您执行此操作平均需要多长时间?我担心创建和连接线程的成本可能比您每秒获得120次的成本要高?真的吗?这还不算太糟。您分析过它吗?您执行此操作的字节数组需要多长时间?这将是决定并行开销对速度有任何影响…实际上每个连接120次。我正在处理至少15个同步连接,数据速率为120Hz等。字节数组可能会有所不同-理论上最大值为65k字节,但很少是这种情况,大多数情况下大约是1k字节。你需要一个查找表,而不是并行性。通过查找,每个字节的操作都会发生变化字节归结为一个异或和一个赋值(假设查找在CPU缓存中),我想现代CPU可以在1个周期内完成。
 (X^16 + X^12 + X^5 + 1)
//  inspired by http://automationwiki.com/index.php?title=CRC-16-CCITT

static ushort[] crc_table =  {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5,
0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c,
0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b,
0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5,
0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969,
0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03,
0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6,
0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1,
0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c,
0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2,
0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447,
0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2,
0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c,
0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0,
0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba,
0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};

public static unsafe ushort CRC(byte* it, byte* end)
{
    ushort crc = 0;
    ushort temp;

    do
    {
        temp = (ushort)((*it ^ (crc >> 8)) & 0xff);
        crc = (ushort)(crc_table[temp] ^ (crc << 8));
    }
    while (it++ != end);

    return crc;
}