代码之家  ›  专栏  ›  技术社区  ›  Sudhanshu

我可以在x86/x86_上自动增加一个16位计数器吗?

  •  2
  • Sudhanshu  · 技术社区  · 16 年前

    我想通过将现有的32位计数器转换为16位计数器来节省内存。此计数器以原子方式递增/递减。如果我这样做:

    1. 我在x86/x86_64上使用Atomic_Inc(uint16_t x)的哪些说明?
    2. 这在多处理器x86/x86_64计算机中是否可靠?
    3. 这样做是否会对这些体系结构造成性能损失?
    4. 如果(3)为“是”,预期的绩效惩罚是多少?

    谢谢你的评论!

    4 回复  |  直到 8 年前
        1
  •  4
  •   phuclv    8 年前

    下面是一个使用GCC组件扩展的方法,作为Steve Delphi答案的替代:

    uint16_t atomic_inc(uint16_t volatile* ptr)
    {
        uint16_t value(1);
        __asm__("lock xadd %w0, %w1" : "+r" (value) : "m" (*ptr));
        return ++value;
    }
    

    将1改为-1,然后 ++ 具有 -- ,用于减量。

        2
  •  3
  •   phuclv    8 年前

    下面是一个Delphi函数:

    function LockedInc( var Target :WORD ) :WORD;
    asm
            mov     ecx, eax
            mov     ax, 1
       Lock xadd    [ecx], ax
            Inc     eax
    end;
    

    我想你可以把它转换成你需要的任何语言。

        3
  •  0
  •   IamIC    15 年前

    执行原子增加的最简单方法如下(这是内联asm):

    asm
      lock inc dword ptr Counter;
    end;
    

    其中j是整数。这将直接增加计数器的内存位置。

    我用蛮力测试过这个,它可以100%工作。

        4
  •  -1
  •   Gunther Piez    16 年前

    回答其他三个问题:

    1. 找不到从2开始的编号列表
    2. 是的,这在多处理器环境中是可靠的
    3. 是的,有一个表演惩罚
    4. “lock”前缀不仅为处理器锁定总线,也为任何外部硬件锁定总线,这些硬件可能希望通过DMA(大容量存储、图形…)访问总线。所以它很慢,通常约100个时钟周期,但可能更昂贵。但是,如果您有“兆字节”的计数器,很有可能会遇到缓存丢失,在这种情况下,您将不得不等待大约100个时钟(内存访问时间),在页面丢失的情况下,几百个,因此锁的开销可能无关紧要。