es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

AVX2: Contar ceros finales en elementos de 8 bits en el registro AVX

Me gustaría tener una implementación para una función como _mm256_lzcnt_epi8(__m256i a), donde se cuenta y extrae el número de ceros finales para cada elemento de 8 bits.

En una pregunta anterior sobre cómo implementar el conteo de ceros principales, hay una solución que utiliza una tabla de búsqueda. Me pregunto si se puede utilizar el mismo método para esto.

Solo AVX y AVX2, por favor, y el comportamiento para una entrada de 0 puede ser indefinido.

Gracias por tu ayuda.

https://stackoverflow.com/questions/68985039/avx2-bitscanreverse-or-countleadingzeros-on-8-bit-elements-in-avx-register

¡Gracias por tu ayuda!

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para implementar una función como _mm256_lzcnt_epi8(__m256i a) utilizando instrucciones AVX y AVX2, se puede utilizar el mismo método que para contar ceros principales. Sin embargo, en lugar de utilizar una tabla de búsqueda, se puede utilizar la instrucción pext para extraer los ceros finales de cada byte en el vector de entrada. La instrucción pext extrae bits del operando fuente basado en los bits establecidos en el operando de máscara, y almacena el resultado en el operando de destino. Para crear el operando de máscara para _mm256_lzcnt_epi8, necesitamos generar un patrón de bits que tenga un 1 en la posición del bit cero menos significativo, y ceros en otras posiciones. Una forma de generar esta máscara es utilizar la instrucción blsi, que borra todos los bits excepto el bit establecido menos significativo. Podemos tomar el complemento del vector de entrada, aplicar blsi para obtener la posición del bit cero menos significativo, y luego generar la máscara con pext. Finalmente, podemos contar el número de bits establecidos en la máscara de resultados utilizando la instrucción popcnt, que nos da el número de ceros finales para cada byte en el vector de entrada.

    Aquí hay una implementación utilizando instrucciones AVX2:

    c++
    __m256i _mm256_lzcnt_epi8(__m256i a)
    {
    __m256i mask = _mm256_sub_epi8(_mm256_set1_epi8(-1), a); // complemento del vector de entrada
    __m256i bitpos = _mm256_xor_si256(_mm256_add_epi8(mask, _mm256_set1_epi8(1)), mask); // posición del bit cero menos significativo
    __m256i result = _mm256_xor_si256(a, _mm256_set1_epi8(-1)); // complemento del vector de entrada nuevamente
    result = _mm256_pext_epi8(result, bitpos); // extraer ceros finales
    result = _mm256_popcnt_epi8(result); // contar el número de ceros finales
    return result;
    }

    Tenga en cuenta que el comportamiento para 0 como entrada no está definido, según se especifica en la pregunta.

Comments are closed.