系统相关
首页 > 系统相关> > c – 从任何内存地址读取UInt32的最有效方法?

c – 从任何内存地址读取UInt32的最有效方法?

作者:互联网

从C中的任意内存地址读取UInt32值的最有效方法是什么? (假设Windows x86或Windows x64架构.)

例如,考虑使用一个指向内存中某处的字节指针来阻止包含整数,字符串数据等的组合,这些组合都混合在一起.以下示例显示了在循环中从此块读取各个字段.

typedef unsigned char* BytePtr;
typedef unsigned int UInt32;

...

BytePtr pCurrent = ...;

while ( *pCurrent != 0 )
{
    ...

    if ( *pCurrent == ... )
    {
        UInt32 nValue = *( (UInt32*) ( pCurrent + 1 ) );    // line A

        ...
    }

    pCurrent += ...;
}

如果在A行,pPtr恰好包含一个4字节对齐的地址,则读取UInt32应该是单个内存读取.如果pPtr包含一个非对齐的地址,则需要多个内存周期,这会降低代码的速度.有没有更快的方法从非对齐地址读取值?

解决方法:

我建议将memcpy放入循环中的UInt32类型的临时内容中.

这利用了以下事实:在启用优化的情况下,编译器将内联一个四字节memcpy,并具有一些其他好处:

>如果你在一个对齐很重要的平台上(hpux,solaris sparc,……),你的代码就不会陷阱.
>在对齐很重要的平台上,可能有必要对对齐进行地址检查,然后进行常规对齐加载或一组4字节加载和位ors之一.您的编译器的memcpy很可能会以最佳方式执行此操作.
>如果您所在的平台上允许未对齐访问并且不会影响性能(x86,x64,powerpc,…),那么您几乎可以保证这样的memcpy将是最便宜的方式这种访问.
>如果您的内存最初是指向其他数据结构的指针,则由于别名问题,您的代码可能未定义,因为您正在转换为其他类型并取消引用该转换.由于别名相关的优化问题导致的运行时问题非常难以追查!假设您可以解决它们,在已建立的代码中修复也可能非常困难,您可能必须使用模糊的编译选项,如-fno-strict-aliasing或-qansialias,这可能会显着限制编译器的优化能力.

标签:c,x86,windows,memory-alignment,64-bit
来源: https://codeday.me/bug/20190826/1731286.html