Можно ли атомарно увеличить 16-битный счетчик на x86 / x86_64? - PullRequest
2 голосов
/ 09 октября 2009

Я хочу сэкономить память путем преобразования существующего 32-разрядного счетчика в 16-разрядный. Этот счетчик атомарно увеличивается / уменьшается. Если я сделаю это:

  1. Какие инструкции я использую для atomic_inc (uint16_t x) на x86 / x86_64?
  2. Надежно ли это на многопроцессорных компьютерах x86 / x86_64?
  3. Есть ли штраф за производительность, выплачиваемый какой-либо из этих архитектур за это?
  4. Если да (3), какова ожидаемая потеря производительности?

Спасибо за ваши комментарии!

Ответы [ 4 ]

4 голосов
/ 09 октября 2009

Вот тот, который использует расширения сборки GCC, в качестве альтернативы ответу Стива на 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, а ++ с --, для уменьшения.

3 голосов
/ 09 октября 2009

Вот функция Delphi, которая работает:

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

Полагаю, вы можете перевести его на любой язык, который вам требуется.

0 голосов
/ 28 июля 2010

Самый простой способ выполнить атомное увеличение заключается в следующем (это встроенный ASM):

asm
  lock inc dword ptr Counter;
end;

где J - целое число. Это непосредственно увеличит счетчик в его ячейке памяти.

Я проверил это с помощью грубой силы, и оно работает на 100%.

0 голосов
/ 09 октября 2009

Чтобы ответить на три других вопроса:

  1. Не нашел способа составить нумерованный список, начинающийся с 2
  2. Да, это надежно в многопроцессорной среде
  3. Да, штраф за производительность
  4. Префикс «lock» блокирует шины не только для процессора, но и для любого внешнего оборудования, которое может захотеть получить доступ к шине через DMA (запоминающее устройство, графика ...). Так что это медленно, обычно ~ 100 тактов, но это может быть дороже. Но если у вас есть «мегабайты» счетчиков, скорее всего, вы столкнетесь с отсутствием кэша, и в этом случае вам все равно придется подождать около ~ 100 часов (время доступа к памяти), в случае пропуска страницы сотен, поэтому накладные расходы от блокировки могут не иметь значения.
...