Contagem populacional mais rápida de 64 bits (peso de Hamming)

Eu tive que calcular o peso de Hamming para um fluxo contínuo muito rápido de dados de 64 bits e usando opopcnt As instruções de montagem lançam uma exceção para o meu Intel Core i7-4650U.

Eu verifiquei o prazer da minha bíblia Hacker e examinei a Web em busca de todos os tipos de algoritmos (é um monte por aí desde que começaram a lidar com esse 'problema' no nascimento da computação).

Passei o fim de semana brincando com algumas idéias próprias e criei esses algoritmos, onde estou quase na velocidade em que posso mover dados para dentro e para fora da CPU.

    //64-bit popcnt using BMI2
_popcnt_bmi2:
        mov         (%rdi),%r11
        pext        %r11,%r11,%r11
        not         %r11
        tzcnt       %r11,%r11
        mov         %r11,(%rdx)
        add         $8h,%rdi
        add         $8h,%rdx
        dec         %rsi
        jnz         _popcnt_bmi2
        ret

No código acima eu usopext (IMC2) onde os dados recebidos estão se usando como a máscara. Todos os bits existentes entrarão em colapso começando com o bit menos significativo no registro de resultados (ele próprio novamente). Então eu preciso calcular o número de bits recolhidos para inverter todos os bits e usartzcnt para contar o número de, agora zera. Eu pensei que era uma boa idéia.

Então eu também tentei uma abordagem AVX2:

//64-bit popcnt using AVX2
_popcnt_avx2:
        vmovdqa     (%rcx),%ymm2
        add         $20h,%rcx
        vmovdqa     (%rcx),%ymm3
        add         $20h,%rcx
        vmovdqa     (%rcx),%ymm4
popcnt_avx2_loop:
        vmovdqa     (%rdi),%ymm0
        vpand       %ymm0, %ymm2, %ymm1
        vpandn      %ymm0, %ymm2, %ymm0
        vpsrld      $4h,%ymm0, %ymm0
        vpshufb     %ymm1, %ymm3, %ymm1
        vpshufb     %ymm0, %ymm3, %ymm0
        vpaddb      %ymm1,%ymm0,%ymm0       //popcnt (8-bits)
        vpsadbw     %ymm0,%ymm4,%ymm0       //popcnt (64-bits)
        vmovdqa     %ymm0,(%rdx)
        add         $20h,%rdi
        add         $20h,%rdx
        dec         %rsi
        jnz         popcnt_avx2_loop

No caso do AVX2, li 32 bytes e ocultei os petiscos (ymm2), então eu usoymm3 como uma tabela de pesquisa para contar pouco os petiscos. Depois adiciono os resultados aos de 8 bits e depois uso o super condensadovpsadbw para adicionar 8 bytes a um valor de 64 bits (ymm4 = 0).

Alguém conseguiu algo mais rápido nas mangas?

Editar:

A falhaPOPCNT foi devido a um erro que cometi no meu código, essa função funciona no meu Intel Core i7-4650U. Por favor, veja o meu post abaixo exibindo os resultados do banco.

questionAnswers(2)

yourAnswerToTheQuestion