Maison  >  Article  >  développement back-end  >  Comment charger 8 caractères de la mémoire dans une variable __m256 sous forme de flotteurs compacts à simple précision à l'aide d'AVX2 ?

Comment charger 8 caractères de la mémoire dans une variable __m256 sous forme de flotteurs compacts à simple précision à l'aide d'AVX2 ?

DDD
DDDoriginal
2024-10-31 21:43:02721parcourir

How to Load 8 Characters from Memory into an __m256 Variable as Packed Single Precision Floats Using AVX2?

Chargement de 8 caractères de la mémoire dans une variable __m256 sous forme de flotteurs compacts à simple précision

Dans les algorithmes de flou gaussien, une optimisation pour une exécution plus rapide peut être obtenue en chargeant efficacement les données dans des registres vectoriels. Une de ces optimisations consiste à remplacer un tableau de flotteurs par une variable __m256. Cet article fournit une solution optimale pour cette tâche, exploitant la puissance des instructions AVX2.

Solution utilisant les instructions AVX2

Pour charger efficacement 8 caractères de la mémoire dans une variable __m256 en utilisant AVX2, les instructions suivantes sont recommandées :

VPMOVZXBD  ymm0,  [rsi]  ; or SX to sign-extend  (Byte to DWord)
VCVTDQ2PS   ymm0, ymm0     ; convert to packed foat

Spécificités des instructions

  • VPMOVZXBD : Zéro étend les caractères 8 bits en 32- entiers de bits dans le registre ymm0.
  • VCVTDQ2PS : convertit les entiers de 32 bits en flottants simple précision compressés, les stockant directement dans ymm0.

Optimisation supplémentaire

Pour optimiser davantage ce processus, pensez à utiliser une charge de diffusion pour alimenter l'instruction VPMOVZXBD et une instruction Vpshufb pour les 64 bits élevés. Cette stratégie réduit le nombre global d'uop, améliorant ainsi l'efficacité :

<code class="pseudocode">__m256 b = [float(new_image[x+7]), float(new_image[x+6]), ... , float(new_image[x])];
__m256 b = _mm256_broadcast_ss(&new_image[x])
_mm256_shuffle_epi8(b, _mm256_set1_epi8(0)); // fills upper 64 bits with zeroes
_mm256_cvtps_epu32(b); // convert to integers
_mm256_cvtepu32_ps(b); // convert back to floats</code>

Évitez les techniques sous-optimales

  • Évitez d'utiliser plusieurs charges 128 bits ou 256 bits et les remaniements ultérieurs, car cela pourrait introduire des goulots d'étranglement inutiles.
  • N'utilisez pas une instruction VPMOVZXD suivie d'opérandes de mémoire séparés pour VPMOVZX, car cela conduit à une génération de code sous-optimale.

Considérations supplémentaires

  • Envisagez d'utiliser un intrinsèque sûr, si disponible, pour éviter les problèmes potentiels d'alignement de la mémoire ou d'accès à la mémoire non initialisée.
  • Utilisez les intrinsèques _mm_loadl_epi64 ou _mm_loadu_si64 appropriés pour éviter le chargement plus de données que nécessaire ou provoquant des erreurs de segmentation potentielles.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn