как сделать атомарную копию 128-битного числа в gcc inline x86_64 asm? - PullRequest
1 голос
/ 16 декабря 2010

Я не занимался сборкой со школы (эоны назад) и никогда не делал x86, но я обнаружил досадную ошибку в старом существующем коде, когда кто-то не делает атомарную операцию там, где она должна быть.Человек, который написал код, давно ушел, и никто здесь не знает ответа на мой вопрос.Что мне нужно сделать, это создать атомарную копию для 128-битных значений.Код, который у меня сейчас есть, выглядит следующим образом:

void atomic_copy128(volatile void* dest,volatile const void* source) {
#if PLATFORM_BITS == 64
   #ifdef __INTEL_COMPILER 
      //For IA64 platform using intel compiler
      *((__int64*)source)=__load128((__int64*)dest,((__int64*)source)+1);
   #else 
      //For x86_64 compiled with gcc
      __asm__ __volatile__("lock ; movq  %0,%1"
           : "=r"(*((volatile long *)(source)))
           : "r"(*((volatile long *)(dest)))
           : "memory");
   #endif
#else
   #error "128 bit operations not supported on this platform."
#endif
}

Это не тот код, который я изначально пробовал, так как я немножко испортил его, пытаясь заставить его скомпилировать и запустить.Когда я делаю это полностью недействительной инструкцией, она не компилируется.Когда я запускаю это, он выполняется до тех пор, пока не достигнет этой строки, а затем генерирует сообщение об ошибке «Недопустимая инструкция».Буду признателен за любую помощь.

Ответы [ 2 ]

1 голос
/ 17 декабря 2010

Насколько я знаю, "movq" поддерживает не более одного операнда памяти, и его аргументы в любом случае имеют 64-битный размер, так что даже если бы были поддержаны два операнда памяти, это все равно не дало бы вам такой атомарный 128-битовая копия, которую вы ищете.

0 голосов
/ 21 декабря 2012

Для окон:

::memset( dst, -1, 16 );
_InterlockedCompareExchange128(source, -1, -1, dst );

(но const необходимо удалить)

Для другого использования cmpxchg16b Инструкция

...