Très vite memcpy pour le traitement de l'image?
Je fais du traitement d'image en C qui exige la copie de gros blocs de données de la mémoire - la source et la destination ne doivent pas se chevaucher.
Qu'est-ce que l'absolu de la façon la plus rapide de le faire sur la plate-forme x86 à l'aide de GCC (où L'ESS, SSE2, mais PAS SSE3 sont disponibles)?
J'attends la solution sera dans l'assemblée ou à l'aide de GCC intrinsèques?
J'ai trouvé le lien suivant, mais n'ai aucune idée si c'est la meilleure façon d'aller à ce sujet (l'auteur dit aussi qu'il a quelques bugs): http://coding.derkeiler.com/Archive/Assembler/comp.lang.asm.x86/2006-02/msg00123.html
EDIT: à noter qu'une copie est nécessaire, je ne peut pas contourner avoir à copier les données (je pourrais expliquer pourquoi, mais je vous épargne l'explication :))
- pouvez-vous écrire votre code, de sorte que la copie n'est pas nécessaire, en premier lieu?
- Ron, non, je ne peux pas 🙁
- Si vous pouvez obtenir une prise de le compilateur Intel, vous pourriez avoir plus de chances de l'optimiseur de conversion dans le vecteur instructions du processeur
- Jetez un oeil à ceci: software.intel.com/en-us/articles/memcpy-performance
- Savez-vous par comment beaucoup trop lent de votre compilateur, memcpy() est? Pouvez-vous préciser quel processeur le code sera exécuté sur? Et Quel OS?
- Je suppose que vous vous rendez compte que le maintien de la mémoire des blocs de 16 octets aligné aidera. Ou, si elles ne sont pas de 16 octets alignés, puis de gérer les premiers et derniers octets comme un cas particulier, et copiez le reste du bloc de 16 octets aligné limites.
- Aussi, lire Intel conseils sur rapide memcpy avec GCC software.intel.com/en-us/articles/memcpy-performance
- Je ne sais pas ce qui est le mieux pour vous, mais en ce qui concerne memcpy il y a des versions plus rapide. Essayez Agner de la Brume asmlib (google). Il a l'assemblée optimisé fonctions telles que A_memcpy et A_memmove qui devrait être plus rapide que memcpy
Vous devez vous connecter pour publier un commentaire.
Courtoisie de William Chan et Google. De 30 à 70% plus rapide que memcpy dans Microsoft Visual Studio 2005.
Vous pourriez être en mesure de l'optimiser en fonction de votre situation exacte, et les hypothèses que vous êtes capable de faire.
Vous pouvez également vouloir vérifier le memcpy source (memcpy.asm) et la bande son cas particulier de la manipulation. Il peut être possible d'optimiser encore plus!
À tout niveau d'optimisation de
-O1
ou au-dessus, GCC va utiliser builtin définitions pour les fonctions telles quememcpy
- avec le droit-march
paramètre (-march=pentium4
pour l'ensemble des caractéristiques que vous mentionnez), il devrait générer assez optimale spécifiques à l'architecture de code en ligne.J'aimerais comparer et voir ce qui vient.
L'ESS-Code posté par hapalibashi est le chemin à parcourir.
Si vous avez besoin d'encore plus de performance et de ne pas hésiter à la longue et sinueuse route de l'écriture d'un pilote de périphérique: Toutes les principales plateformes de nos jours ont un DMA-contrôleur est capable de faire un copier-travail plus rapide et en parallèle de code de CPU pourrait le faire.
Qui implique l'écriture d'un driver. Pas de gros OS que je suis conscient de expose cette fonctionnalité à l'utilisateur de côté en raison des risques de sécurité.
Cependant, il peut être vaut la peine (si vous avez besoin de la performance), puisque aucun code sur la terre pourraient surperformer un morceau de matériel qui est conçu pour faire un tel travail.
Cette question est de quatre ans maintenant et je suis un peu surpris que personne n'a mentionné la bande passante de la mémoire encore. CPU-Z les rapports que ma machine a PC3-10700 RAM. Que la RAM a une bande passante maximale (aka le taux de transfert, débit, etc), de 10700 Mo/s. Le CPU dans ma machine est un i5-2430M CPU, avec un pic de fréquence turbo de 3 GHz.
Théoriquement, avec une infinie rapide CPU et ma RAM, memcpy pourrait aller à 5300 Mo/s, c'est à dire la moitié de 10700 parce que memcpy doit lire, puis écrire dans la mémoire RAM. (edit: Comme v. oddou signalé, c'est une simple approximation).
En revanche, imaginons que nous ayons à l'infini de la RAM rapide et réaliste de la CPU, de quoi pourrions-nous atteindre? Nous allons utiliser mes 3 GHz CPU comme un exemple. Si il pouvait faire une version 32 bits de lire et 32-bit à écrire chaque cycle, alors il pourrait transférer 3e9 * 4 = 12000 Mo/s. Cela semble accessible, pour un PROCESSEUR récent. Déjà, on peut voir que le code en cours d'exécution sur le PROCESSEUR n'est pas vraiment le goulot d'étranglement. C'est l'une des raisons que les machines modernes ont des caches de données.
Nous pouvons mesurer ce que le CPU peut vraiment le faire par l'analyse comparative memcpy quand nous savons que les données mises en cache. Faire cette précision est délicat. J'ai fait une application simple qui a écrit des nombres aléatoires dans un tableau, memcpy avais sur un autre tableau, alors checksumed les données copiées. Je traversai le code dans le débogueur assurez-vous que l'habile compilateur n'avait pas supprimé la copie. Modifier la taille de la matrice altère les performances du cache - petits tableaux tient dans le cache, plus gros moins de la sorte. J'ai obtenu les résultats suivants:
Évidemment, mon CPU peut lire et écrire plus de 32 bits par cycle, depuis 16000 est de plus de 12000 je théoriquement calculée ci-dessus. Cela signifie que le PROCESSEUR est encore moins d'un goulot d'étranglement que je ne le pensais. J'ai utilisé Visual Studio 2005, et pas à pas dans la norme de memcpy mise en œuvre, je peux voir qu'il utilise le movqda instruction sur ma machine. Je suppose que cela peut en lecture et en écriture à 64 bits par cycle.
Nice code hapalibashi posté atteint 4200 Mo/s sur ma machine est d'environ 40% plus rapide que VS 2005 mise en œuvre. Je suppose que c'est plus rapide car il utilise les instructions prefetch pour améliorer les performances du cache.
En résumé, le code s'exécutant sur le PROCESSEUR n'est pas le goulot d'étranglement et à l'écoute de code à ne faire que de petites améliorations.
Si spécifique aux processeurs Intel, vous pourriez bénéficier d' IPP. Si vous savez qu'il fonctionnera avec un processeur graphique Nvidia peut-être que vous pourriez utiliser CUDA - dans les deux cas, il peut être mieux de regarder de plus large que l'optimisation de memcpy() - ils offrent des possibilités d'amélioration de votre algorithme à un niveau supérieur. Ils sont cependant tributaires de matériel spécifique.
Si vous êtes sur Windows, utilisez le DirectX Api, ce qui a des GPU-routines optimisées pour les graphiques de la manipulation (à quelle vitesse pourrait-il être? Votre CPU n'est pas chargé. Faire autre chose pendant que le GPU croque-il).
Si vous voulez être un système d'exploitation agnostique, essayez OpenGL.
Ne pas jouer avec de l'assembleur, car il n'est que trop probable que vous allez échouer lamentablement à surperformer 10 ans+ maîtrise de la bibliothèque-faire des ingénieurs en logiciel.