I componenti incorporati __popcnt *() sono per le istruzioni ABM (Advanced Bit Manipulation) di AMD. Vedi http://blogs.amd.com/developer/2007/09/26/barcelona-processor-feature-advanced-bit-manipulation-abm/
Gli intrinsechi _mm_popcnt_u *() sono per l'implementazione di Intel, che non fanno parte di SSE4.2 in sé, ma sono stati implementati nello stesso periodo. Vedi http://en.wikipedia.org/wiki/SSE4#POPCNT_and_LZCNT
In base allo http://chessprogramming.wikispaces.com/Population+Count, entrambe le implementazioni sono compatibili binario, nonostante i loro diversi nomi intrinsechi.
di Intel architecture manual afferma che:
prima di un'applicazione tenta di utilizzare l'istruzione POPCNT, si deve verificare che il processore supporta SSE4.2 (se CPUID.01H: ECX.SSE4_2 [20 bit] = 1) e POPCNT (se CPUID.01H: ECX.POPCNT [bit 23] = 1).
di AMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions AMD dice
sostegno per l'istruzione POPCNT è indicato da ECX bit 23 (POPCNT) come restituito da CPUID funzione 0000_0001h. Il software DEVE controllare il bit CPUID una volta per programma o inizializzazione della libreria prima di utilizzare l'istruzione POPCNT, altrimenti si potrebbe verificare un comportamento incoerente.
Non vedo alcun motivo per cui popcnt richiede la presenza di SSE4.2, quindi penso che il controllo del bit 23 di ECX sia sufficiente per determinare la presenza di popcnt.
AMD di Barcellona, la prima CPU AMD ad avere popcnt, non ha implementato completamente SSE4, quindi è possibile che il manuale di architettura di Intel suggerisca un metodo per determinare la presenza che funzionerà su CPU Intel e fallirà anche su CPU AMD qualificate.
Quindi c'è una differenza in quando utilizzare ciascuno nel software? Dovrebbe essere controllato un bit cpuid diverso? Se voglio scrivere agnostico Intel/AMD che ancora utilizza il comando, cosa dovrei fare? –
Non sembra che siano diversi o incompatibili. Vedi la mia risposta sopra modificata. – mattst88
Ottima risposta. Grazie. –