用32位字快速交换C#中的尾数

用32位字快速交换C#中的尾数,c#,bit-manipulation,endianness,C#,Bit Manipulation,Endianness,在中,以下代码: public static void Swap(byte[] data) { for (int i = 0; i < data.Length; i += 2) { byte b = data[i]; data[i] = data[i + 1]; data[i + 1] = b; } } 公共静态无效交换(字节[]数据) { 对于

在中,以下代码:

public static void Swap(byte[] data)
{
        for (int i = 0; i < data.Length; i += 2)
        {
                byte b = data[i];
                data[i] = data[i + 1];
                data[i + 1] = b;
        }
}
公共静态无效交换(字节[]数据)
{
对于(int i=0;i
已在不安全代码中重写以提高其性能:

public static unsafe void SwapX2(Byte[] Source)  
{  
    fixed (Byte* pSource = &Source[0])  
    {  
        Byte* bp = pSource;  
        Byte* bp_stop = bp + Source.Length;  

        while (bp < bp_stop)  
        {
            *(UInt16*)bp = (UInt16)(*bp << 8 | *(bp + 1));  
            bp += 2;  
        }  
    }  
}
公共静态不安全无效SwapX2(字节[]源)
{  
已修复(字节*pSource=&源[0])
{  
字节*bp=pSource;
字节*bp_stop=bp+源.Length;
同时(bppublicstaticvoidswapx4(Byte[]源)
{  
已修复(字节*pSource=&源[0])
{  
字节*bp=pSource;
字节*bp_stop=bp+源.Length;
同时(bp(*bp此版本将不会超出缓冲区的界限。适用于小型和大型Endian体系结构。在更大的数据上速度更快。(更新:为x86和x64添加生成配置,为32位(x86)预定义x86,为64位(x64)预定义x64,速度会稍快一些。)

公共静态不安全无效Swap4(字节[]源)
{
已修复(字节*psource=源)
{
#如果X86
变量长度=*((uint*)(psource-4))&0xFFFFFFFEU;
#elif X64
变量长度=*((uint*)(psource-8))&0xFFFFFFFEU;
#否则
变量长度=(source.length和0xFFFFFFFE);
#恩迪夫
而(长度>7)
{
长度-=8;
乌龙*普龙=(乌龙*)(P来源+长度);
*普隆=((*普隆>>24)和0x000000FF000000FFUL)
|((*pulong>>8)和0x00000FF000000FF00UL)
|(*普隆24))
|((*puint>>8)和0x00000FF00U)

| ((*puint重写,作为记录,只能在一台小小的endian机器上正常工作。此外,从性能角度来看,从内存读取的次数越少越好。表达式的右侧有两个,一个就足够了。编译器可能会优化,也可能不会优化。太棒了。它的运行速度是原来的两倍,在100,0上测试00 8192字节数组。如果源代码的长度不是四的倍数,请小心。此代码可能会损坏多达三个字节的内存,或导致页面错误。为防止出现这种情况,如果长度不是四的倍数,请引发异常,或者如果不是四的倍数,请不要交换最后一个字节。例如,将“bp+Source.length”更改为“bp+(Source.Length&0xfffffc)“有趣。我来看看。这可能只在64位上更快(正如我所提到的,对于更大的数据块)。另一个代码很好,但请看我的评论。我试图修改代码,但被stackoverflow拒绝。这让我担心,许多人会复制粘贴代码,如果他们不小心,这些代码会产生错误。这也适用于swap2,并且该版本在大数据块的情况下速度会快三倍。绝对严格这不是设计要求;已针对您描述的错误条件检查了提供给此函数的数据。最重要的考虑因素是尽可能好的性能。没有任何地方警告应针对特定条件检查数据。因此,不知情的程序员可能会在错误条件下使用该代码。我不是指你的案例,而是指读者的案例。这是一个许多人用来查找代码的网站,他们经常在不了解细节的情况下使用这些代码。(imo)/进行了一次更新,使之稍微快一点。
public static void SwapX4(byte[] data)
{
    byte temp;
    for (int i = 0; i < data.Length; i += 4)
    {
        temp = data[i];
        data[i] = data[i + 3];
        data[i + 3] = temp;
        temp = data[i + 1];
        data[i + 1] = data[i + 2];
        data[i + 2] = temp;
    }
}
public static unsafe void SwapX4(Byte[] Source)  
{  
    fixed (Byte* pSource = &Source[0])  
    {  
        Byte* bp = pSource;  
        Byte* bp_stop = bp + Source.Length;  

        while (bp < bp_stop)  
        {
            *(UInt32*)bp = (UInt32)(
                (*bp       << 24) |
                (*(bp + 1) << 16) |
                (*(bp + 2) <<  8) |
                (*(bp + 3)      ));
            bp += 4;  
        }  
    }  
}
public static unsafe void Swap4(byte[] source)
{
    fixed (byte* psource = source)
    {
#if X86
            var length = *((uint*)(psource - 4)) & 0xFFFFFFFEU;
#elif X64
            var length = *((uint*)(psource - 8)) & 0xFFFFFFFEU;
#else
            var length = (source.Length & 0xFFFFFFFE);
#endif
        while (length > 7)
        {
            length -= 8;
            ulong* pulong = (ulong*)(psource + length);
            *pulong = ( ((*pulong >> 24) & 0x000000FF000000FFUL)
                      | ((*pulong >> 8)  & 0x0000FF000000FF00UL)
                      | ((*pulong << 8)  & 0x00FF000000FF0000UL)
                      | ((*pulong << 24) & 0xFF000000FF000000UL));
        }
        if(length != 0)
        {
            uint* puint = (uint*)psource;
            *puint = ( ((*puint >> 24))
                     | ((*puint >> 8) & 0x0000FF00U)
                     | ((*puint << 8) & 0x00FF0000U)
                     | ((*puint << 24)));
        }
    }
}