2012-05-29 27 views
5

¿Cómo implemento un recuento de 1 bits en una palabra de 16/32/64 bits utilizando la instrucción Intel POPCNT muy rápida, en Delphi XE o XE2? ¿Hay una rutina de biblioteca que dé acceso directo a esta instrucción? ¿Puede alguien escribir una sección de demostración de asm que ilustre su uso, por favor? Y, por último, ¿cuáles son las opciones para Delphi de 64 bits (sin asm disponible)? gracias de antemano tPOPCNT en Delphi XE/XE2 64bit

+1

asm, disponibles en 64 bits Delphi también. – Giel

+0

Supongo que no es tan simple como simplemente escribir 'popcnt eax, eax' o' popcnt rax, rcx' dentro de un bloque de asm, ¿o sí? –

+1

Un poco fuera de tema: http://www.strchr.com/crc32_popcnt tiene una tabla de comparación de implementaciones popcnt, donde una variante SSSE3 ('pshufb' para búsqueda de tablas de nibble) en realidad supera' popcnt' en algunos sistemas. Solo un pequeño%, no necesariamente el mismo en todas las CPU, y solo es beneficioso si realiza la operación para una gran cantidad de datos (más de 100 bytes). _Muy rápido_ es relativo. –

Respuesta

2

Como Rob Kennedy ha sugerido, aquí tiene funciones para Delphi IDE de 32 bits y 64 bits.

function GetBitCount(num: integer): integer; 
asm 
    POPCNT eax, num 
end; 

function GetBitCount(num: Int64): integer; 
asm 
    POPCNT rax, num 
end; 

EDIT: Este es de 32 bits y de 64 bits Delphi versión compatible

{$IF CompilerVersion < 23} //pre-XE2 
    NativeInt = integer; 
{$IFEND} 

function GetBitCount(num: NativeInt): integer; 
asm 
{$IFNDEF CPUX64} 
    POPCNT eax, num 
{$ELSE CPUX64} 
    POPCNT rax, num 
{$ENDIF CPUX64} 
end; 
+0

Este último parece dudoso, probablemente funcionará con un valor de 32 bits y se almacenará en uno de 64 bits. ¿Desea cero a la parte superior de 32 bits o la declara como int64? –

+0

@Marco van de Voort Gracias, sí, es de 32 bits por defecto, pero puede declarar num como 'NativeInt' o' Int64' o 'UInt64' en su lugar, funciona con todos los tham. Corregido a Int64! –

+0

Si usa un tamaño int variable, también necesita ifdef el registro en la línea popcnt. –