2

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

  1. 我对 x86/x86_64 上的 atomic_inc(uint16_t x) 使用什么指令?
  2. 这在多处理器 x86/x86_64 机器中是否可靠?
  3. 这样做是否会对这些架构中的任何一个造成性能损失?
  4. 如果 (3) 是,那么预期的性能损失是多少?

感谢您的意见!

4

4 回答 4

4

这是使用 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,将 , 更改++--递减。

于 2009-10-09T06:25:27.990 回答
3

这是一个有效的Delphi函数:

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

我想您可以将其转换为您需要的任何语言。

于 2009-10-09T06:13:13.107 回答
0

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

asm
  lock inc dword ptr Counter;
end;

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

我已经用蛮力测试了它,它可以 100% 工作。

于 2010-07-28T02:34:55.703 回答
-1

回答其他三个问题:

  1. 没有找到一种方法来制作以 2 开头的编号列表
  2. 是的,这在多处理器环境中是可靠的
  3. 是的,有性能损失
  4. “锁定”前缀锁定总线,不仅针对处理器,还针对任何可能希望通过 DMA(大容量存储、图形......)访问总线的外部硬件。所以它很慢,通常约为 100 个时钟周期,但成本可能更高。但是,如果您有“兆字节”的计数器,很可能您将面临缓存未命中,在这种情况下,无论如何您都必须等待大约 100 个时钟(内存访问时间),以防页面未命中,几个一百,因此锁定的开销可能无关紧要。
于 2009-10-09T09:13:20.403 回答