Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

371
Visualizações
C++: forma más rápida de obtener enteros dentro de un rango

Necesito generar claves hash para aproximadamente N = 100 millones de claves. Según mi estudio, parece que murmur3 (MurmurHash3_x86_32, ver hash de murmur3 ) sería la función hash más rápida con la mejor latencia y una tasa de colisión lo suficientemente pequeña. El problema al que me enfrento es que la función devuelve key como void * . Más específicamente, la plantilla es:

void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out);

Como el tamaño de mi tabla hash sería más pequeño que el hash más grande que puede generar, necesito colocarlo en el rango de la tabla [0, N-1]. La solución más fácil parece ser usar el operador % . Pero como se sabe que es un operador lento, me pregunto si hay una forma más rápida de resolver el problema.

Una sugerencia interesante que encontré fue¿Existe alguna alternativa al uso de % (módulo) en C/C++? en StackOverflow mismo. Sugiere 'una potencia de dos, las siguientes obras (suponiendo una representación de complemento de dos)':

return i & (n-1);

Mi problema con esto es que en las CPU más nuevas, a veces (¿o es la mayoría de las veces?), el rendimiento se degrada alrededor de los tamaños 2^n, IIRC, debido a las líneas de caché de múltiples vías. (Este enlace proporciona una ilustración sobre las inserciones de Big Memory, Parte 3.5: ¡Google sparsehash! ).

Por el momento, las ventajas de murmur3 parecen quedar anuladas por problemas relacionados con el hardware y la conocida ineficiencia del operador % . Como el rendimiento es una limitación, solicito soluciones más rápidas y de baja latencia para mis requisitos, incluso si no es MurmurHash3_x86_32.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

El problema al que me enfrento es que la función devuelve key como void * .

No es asi. No devuelve nada ( void ). El resultado del hash se registra en el búfer que especifique (un puntero a) a través del último argumento. Para MurmurHash3_x86_32() , tiene más sentido que sea un puntero a uint32_t .

Como el tamaño de mi tabla hash sería más pequeño que el hash más grande que puede generar, necesito colocarlo en el rango de la tabla [0, N-1]. La solución más fácil parece ser usar el operador %. Pero como se sabe que es un operador lento, me pregunto si hay una forma más rápida de resolver el problema.

El % no solo es la solución más fácil, sino la más habitual. "Lento" es relativo: % es más lento que + , pero mucho, mucho más rápido que una llamada a MurmurHash3_x86_32() .

Una sugerencia interesante que encontré [...] sugiere [usar un tamaño de tabla de potencia de dos y calcular el módulo a través del operador & ]

Tenga en cuenta que, contrariamente a la afirmación en la respuesta SO, de hecho, esto no depende en absoluto de la representación del complemento a dos.

Mi problema con esto es que en las CPU más nuevas, a veces (¿o es la mayoría de las veces?), el rendimiento se degrada alrededor de los tamaños 2^n, IIRC, debido a las líneas de caché de múltiples vías. (Este enlace proporciona una ilustración sobre las inserciones Big Memory, Parte 3.5: ¡Google sparsehash!).

La degradación del rendimiento descrita en el informe que vinculó se atribuye a la repetición de hash, lo que parece bastante plausible. Eso no tiene nada que ver con las operaciones por las que preguntas. Es concebible que la asociatividad de la memoria caché (falta de) pueda afectar el rendimiento de las tablas hash grandes, pero probablemente no más de lo que suele afectar tener tablas hash grandes. Los patrones de acceso a la memoria inherentes al uso de una tabla hash producen naturalmente una localidad de caché deficiente. Ese es prácticamente el punto .

Por el momento, las ventajas de murmur3 parecen quedar anuladas por problemas relacionados con el hardware y la conocida ineficiencia del operador %. Como el rendimiento es una limitación, solicito soluciones más rápidas y de baja latencia para mis requisitos, incluso si no es MurmurHash3_x86_32.

Estás pensando demasiado en esto. La falta de uso efectivo de la caché de su CPU es simplemente un precio que paga por usar una tabla hash grande. No está asociado con la función hash (siempre y cuando la función hash haga bien su trabajo). El costo de una sola operación aritmética, ya sea % o & , no se notará en comparación con el costo de calcular un hash para operar , por lo que poco importa cuál elija. Si desea una pequeña ventaja para esa operación, use una tabla de tamaño de potencia de dos y el operador & . Por otro lado, eso descarta algunos de los bits de hash que tanto trabajo le costó calcular. Considere, en cambio, elegir un tamaño de tabla hash principal y el operador % ; luego, todos los bits hash contribuirán a la selección del segmento, lo que puede mejorar su margen.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda