Wednesday, June 22, 2016

Ecomplex 19






+

VectorLib Contenu 5.6 OptiVec Messages d'erreur 1. Introduction OptiVec offre un puissant ensemble de routines pour les applications exigeantes numériquement, ce qui rend la philosophie de la programmation vectorisé disponible pour C / C ++ et Pascal / Delphi langues. Il sert à surmonter les limites de la gestion de la boucle des compilateurs classiques qui se sont avérés être un des plus grands obstacles à la manière du programmateur vers un codage efficace pour les applications scientifiques et d'analyse des données. Contrairement aux ensembles intégrés comme MatLab ou autres, OptiVec a l'avantage d'être incorporé dans les langues modernes et polyvalents C / C ++ et Pascal / Delphi. Les deux C ++ et Fortran n'offrent déjà une sorte de traitement vectoriel, en vertu des classes d'itérateurs en utilisant des modèles (C ++) et les fonctions de champ (Fortran90). Ces deux, cependant, sont essentiellement un moyen commode de laisser le compilateur écrire la boucle pour vous et ensuite compiler le code inefficace d'habitude. Le même est vrai pour la plupart des implémentations des BLAS (Basic Linear Algebra Subroutine) les bibliothèques populaires. En comparaison avec ces approches est supérieure OptiVec principalement en ce qui concerne la vitesse d'exécution de la moyenne par un facteur de 03/02, dans certains cas, même jusqu'à 8. La performance est plus limitée par la qualité du compilateur, mais plutôt par la vitesse réelle du processeur! Il y a un certain chevauchement dans la gamme des fonctions offertes par OptiVec et par BLAS, LINPACK, et d'autres bibliothèques et collections de code source. Toutefois, ce dernier doit être compilé, et, par conséquent, leur performance est principalement déterminée par la qualité du compilateur choisi. Au meilleur de notre connaissance, OptiVec. était. en 1996, le premier produit sur le marché offrant une bibliothèque vectorisés-fonctions complètes réalisé dans une véritable mise en œuvre Assembleur. Tous les opérateurs et les fonctions mathématiques de C / C ++ sont mis en œuvre sous forme vectorisée; en outre de nombreuses fonctions mathématiques sont plus inclus qui devrait normalement être calculée par des combinaisons plus ou moins complexes de fonctions existantes. Non seulement la vitesse d'exécution, mais aussi la précision des résultats est grandement améliorée. Les blocs de construction pour l'analyse statistique des données sont fournies. Les produits dérivés, intégrales, schémas d'interpolation sont inclus. Fast Fourier Transform techniques permettent convolutions efficaces, des analyses de corrélation, le filtrage spectral, et ainsi de suite. Représentation graphique des données offre un moyen pratique de suivre les résultats des calculs vectorisés. Un large éventail de fonctions de matrice optimisés comme arithmetics de matrice, l'algèbre, les décompositions, les données de montage, etc. est proposée par MatrixLib. TensorLib est prévu comme une extension future de ces concepts pour les tableaux multidimensionnels généraux. Chaque fonction existe pour chaque type de données pour ce qui est raisonnable. Le type de données est indiqué par le préfixe du nom de fonction. Pas implicite nom mangling ou autre C ++ spécifique fonctionnalités sont utilisées, ce qui le rend utilisable dans OptiVec plain-C, ainsi que dans les programmes C ++. De plus, les noms et la syntaxe de presque toutes les fonctions sont les mêmes en C / C ++ et les langages Pascal / Delphi. Les vecteurs d'entrée et de sortie / matrices de VectorLib et MatrixLib routines peuvent être de taille variable, et il est possible de traiter seulement une partie (par exemple, les 100 premiers éléments, ou tout élément 10) d'un vecteur, qui est un autre avantage important par rapport aux autres approches , où seuls les tableaux entiers sont traités. Une nouvelle interface orientée objet C ++. nommé VecObj. encapsule toutes les fonctions vectorielles, offrant une utilisation encore plus facile et une sécurité accrue de la mémoire. Utilisation de routines OptiVec au lieu de boucles peut rendre votre code source beaucoup plus compact et beaucoup mieux lisible. La large gamme de routines et les fonctions couvertes par OptiVec. l'efficacité numérique élevée et une plus grande facilité de programmation font de cet ensemble un outil de programmation puissant pour les applications scientifiques et d'analyse des données, en concurrence avec (et en battant souvent) de nombreux systèmes intégrés à prix élevé, mais noyées dans votre langage de programmation favori. Retour à VectorLib Table des matières OptiVec maison 1.1 Pourquoi Vectorized programmation Pays Off sur le PC Pour traiter les tableaux unidimensionnels données ou, à savoir l'organisation du code de programme (par les compilateurs intelligents ou par le programmeur lui-même) de manière à optimiser le traitement vectoriel. Vectorisation a toujours été la formule magique pour les superordinateurs avec leurs architectures parallèles multi-processeurs. Sur ces architectures, on essaie de répartir l'effort de calcul de façon égale sur les processeurs disponibles, optimisant ainsi la vitesse d'exécution. Les algorithmes dits décomposent tâches numériques plus complexes en petites boucles sur les éléments du tableau. compilateurs sophistiqués trouvent alors sur la façon la plus efficace la façon de distribuer les éléments du tableau entre les processeurs. De nombreux compilateurs de superordinateurs viennent également avec un grand nombre de fonctions vectorielles et matricielles propriétaires prédéfinis pour de nombreuses tâches de base. Ces fonctions vectorisées offrent la meilleure façon d'atteindre un débit maximal. De toute évidence, le traitement parallèle massif de, disons, un Cray est pas possible, même sur les PC modernes avec leurs configurations de base 2 ou 4 processeurs modestes, et encore moins sur le seul processeur classique PC. Par conséquent, à première vue, il peut sembler difficile d'appliquer le principe de la programmation vectorisé au PC. En fait, cependant, il existe de nombreuses optimisations possibles spécifiques vecteur, même pour les ordinateurs avec un seul CPU. La plupart de ces optimisations ne sont pas disponibles pour présenter les compilateurs. Au contraire, on doit aller jusqu'au niveau code machine. Main optimisée, fonctions vectorielles Assembleur-écrites surperformer compilé boucles par un facteur de deux à trois, en moyenne. Cela signifie que la vectorisation, bien fait, est en effet en vaut la peine, également pour les programmes de PC. 1.1.1 Stratégies générales OptiVec optimisation Voici les stratégies d'optimisation les plus importants, employés dans OptiVec pour améliorer les performances sur un PC (quel que soit le nombre de cœurs de processeur): Précharge de constantes à virgule flottante, ainsi que des constantes entières, employées dans l'évaluation des fonctions mathématiques, sont chargés dans des registres à l'extérieur de la boucle réelle et de rester aussi longtemps qu'ils sont nécessaires. Cela permet d'économiser une grande quantité d'opérations de chargement / déchargement qui sont nécessaires si une fonction mathématique est appelée pour chaque élément d'un vecteur séparément. XMM complète et FPU utilisation de la pile Si nécessaire, tous les huit (64-bit: les seize) registres XMM et / ou tous les huit registres du coprocesseur sont employés. Prefetch des morceaux d'éléments vectoriels commençant par le processeur Pentium III, Intel introduit la fonctionnalité très utile explicite prefetch mémoire. Avec ces commandes, il est possible de "dire" le processeur pour récupérer des données de la mémoire suffisamment à l'avance, de sorte que peu de temps est perdu à attendre pour eux quand ils sont effectivement nécessaires. Utilisation de SIMD commandes On peut se demander pourquoi cette stratégie ne figure pas en premier. L'ESS ou "streaming Single-Instruction-Multiple-Data Extensions", mis en place depuis les jours du Pentium III et amélioré avec chaque nouvelle génération de processeur, fournissent un soutien explicite pour la programmation vectorisé avec des données en virgule flottante à flotteur / simple ou double précision. A première vue, par conséquent, ils devraient révolutionner la programmation de vecteur. Compte tenu de la relation habituelle entre la vitesse du processeur et de bus de données, cependant, la plupart des opérations arithmétiques simples sont le transfert de données limitées, et l'utilisation de SIMD commandes ne rend pas la grande différence (par rapport au code FPU bien écrit) il pourrait faire autrement . Dans de nombreux cas, l'avantage d'utiliser une instruction SIMD au lieu d'instructions FPU séparées fond vers le bas pour une augmentation de 20-30% de la vitesse (qui est pas si mal, quand même!). Pour les opérations plus complexes, d'autre part, SIMD commandes ne peuvent souvent pas être employée, soit parce que les branches conditionnelles doivent être prises pour chaque élément de vecteur individuellement, ou parce que la précision "extra" et la gamme, disponible par des commandes FPU traditionnelles (avec leur interne précision étendue), permet de simplifier les algorithmes tant que le code FPU est encore plus rapide. En conséquence, on utilise uniquement les commandes SIMD où un gain de vitesse réel est possible. S'il vous plaît noter, cependant, que, les versions de la bibliothèque SIMD employant (P8, P9 etc.) sacrifient généralement 1-2 chiffres de précision pour atteindre le gain de vitesse décrit. Si cela est acceptable pour votre tâche spécifique, s'il vous plaît rester avec les bibliothèques de P4. Boucle-déroulage Où instructions SIMD ne peuvent pas être utilisés et où l'appariement optimal des commandes ne peut être obtenue pour des éléments simples, les vecteurs sont souvent traitées en morceaux de deux, quatre, ou même plus d'éléments. Cela permet d'exploiter pleinement les tuyaux d'exécution parallèles. En outre, la quantité relative de temps consacré à la gestion de la boucle est sensiblement réduite. En relation avec des données pré-extraction décrite ci-dessus, la profondeur des boucles déroulées est le plus souvent adapté à la taille de ligne de mémoire cache. adressage simplifié L'adressage des éléments vectoriels est toujours une source majeure d'inefficacité avec les compilateurs présents. Mise en avant et en arrière entre les vecteurs d'entrée et de sortie, un grand nombre d'opérations d'adressage redondants est effectuée. Les définitions strictes (et facile!) De toutes les fonctions OptiVec permettent de réduire ces opérations à un minimum. Remplacement de virgule flottante par nombre entier de commandes Pour toutes les opérations avec les nombres à virgule flottante qui peuvent également être effectuées à l'aide des commandes entières (comme la copie, l'échange, et la comparaison aux valeurs prédéfinies), la méthode plus rapide est toujours employé. Strict compilateurs de contrôle de précision C convertissent un flotteur en double pour passer activement le FPU à simple précision, si cela est suffisant pour une application donnée. Ainsi, l'exécution peut être légèrement accéléré de processeurs Pentium sur. Soyez toutefois prêt à accepter encore plus faible que seule la précision de vos résultats finaux, si vous choisissez cette option. Pour plus de détails et les précautions, voir V_setFPAccuracy. codage Tous les appels de fonctions externes All-inline sont éliminés des boucles internes du traitement vectoriel. Cela permet d'économiser le temps nécessaire pour les couples et pour le chargement des paramètres dans la pile d'exécution. Cache-line correspondant de variables locales Le niveau 1 cache des processeurs modernes utilise des lignes de 64 octets. De nombreuses fonctions OptiVec besoin double précision ou précision étendue réelle des variables locales sur la pile (principalement pour les entiers / conversions à virgule flottante ou vérification de la plage). compilateurs 32 bits aligner la pile sur les limites de 4 octets, ce qui signifie qu'il ya une certaine chance que les 8 octets d'une double ou les 10 octets d'une étendue. stocké sur la pile, traversera une frontière cache en ligne. Ceci, à son tour, entraînerait une pénalité cache line-break, la détérioration de la performance. Par conséquent, ces fonctions OptiVec où cela est un problème, utiliser des procédures spéciales pour aligner leurs variables locales sur 8 octets (pour le double s), 16 octets (pour s étendu), ou les limites de 64 octets (pour les XMM et les valeurs YMM) . fonctions non protégées et la réduction de gamme OptiVec offre des formes alternatives de certaines fonctions mathématiques, où vous avez le choix entre la variante entièrement protégé par la gestion des erreurs et une autre variante non protégés sans. Dans le cas des fonctions de puissance de nombre entier, par exemple, l'absence d'une vérification d'erreur permet à des versions non protégées pour être vectorisés beaucoup plus efficace. De même, les fonctions sinus et cosinus peuvent être codées de manière plus efficace pour les arguments que l'utilisateur peut garantir à se situer dans la plage -2 p et 2 p. Dans ces cas particuliers, le temps d'exécution peut être réduite jusqu'à 40%, selon l'environnement du matériel. Cette augmentation de la vitesse doit toujours être mis en balance avec le risque accru, cependant: Si un élément d'entrée en dehors de la plage valide est rencontré, les fonctions non protégées et la réduction de gamme se bloque sans avertissement. Optimisation 1.1.2 Multi-Processor support multithread modernes processeurs multi-core permettent au système d'exploitation de distribuer les discussions entre les processeurs disponibles, mise à l'échelle de la performance globale du nombre de disponibles cœurs de processeur. Pour cela, toutes les fonctions en cours d'exécution en parallèle doivent être empêchés d'interférer les uns avec les autres grâce à des opérations de lecture / écriture sur les variables globales. À quelques exceptions près (à savoir les fonctions de traçage, qui doivent utiliser des variables globales pour stocker la fenêtre en cours et coordonner les paramètres du système, et les fonctions de données ajustées non-linéaires), toutes les autres fonctions OptiVec sont rentrante et peuvent fonctionner en parallèle. Lors de la conception de votre application multi-thread, vous avez deux options: parallélisme et données fonctionnelles parallélisme. Parallélisme fonctionnelle Si différents threads exécutent différentes tâches on parle de parallélisme fonctionnel. A titre d'exemple, envisager une gestion des threads utilisateur d'entrée / sortie, tandis qu'un autre effectue des calculs d'arrière-plan. Même sur un processeur single-core, ce genre de multi-threading peut offrir des avantages (par exemple l'interface utilisateur ne bloque pas pendant de nombreux calculs d'arrière-plan, mais prend encore entrée). Sur un ordinateur multi-core, les deux (ou plus) threads peuvent effectivement fonctionner simultanément sur les différents cœurs de processeur. En général, cependant, l'équilibrage de charge entre les cœurs de processeur est loin d'être parfait: souvent, un processeur est en cours d'exécution à la charge maximale, tandis qu'un autre est au repos, en attente d'entrée. Pourtant, multithreading fonctionnelle est la meilleure option à chaque fois que vos tâches numériques impliquent des vecteurs et des matrices de seulement petite à modérée taille. Données Parallélisme Afin d'améliorer l'équilibre de la charge entre les cœurs de processeur disponibles, ce qui maximise le débit, il est possible d'utiliser le traitement parallèle classique: les données à traiter est divisé en plusieurs morceaux, chaque thread obtenir un de ces morceaux. Ceci est justement appelé le parallélisme de données. L'utilité de cette approche est limitée par les frais généraux impliqués dans la distribution de données et dans la communication fil à fil. De plus, il y a toujours des parties du code qui doivent être traités de manière séquentielle et ne peut être parallélisables. Par conséquent, le parallélisme de données paie seulement pour les vecteurs et les matrices plus grandes. tailles de rentabilité typiques vont d'environ 100 (pour le calcul des fonctions transcendantes de valeurs d'entrée complexes) à plusieurs 10.000 éléments (comme dans les fonctions arithmétiques simples). Seulement lorsque vos vecteurs et matrices sont considérablement plus grande que ce seuil, la performance est effectivement améliorée par rapport à une approche fonctionnelle parallélisme. Le coup de pouce se rapproche alors rapidement (mais jamais atteint exactement) la limite théorique d'un facteur égal au nombre de cœurs de processeur disponibles. Le choix de la Bibliothèque OptiVec droit Chaque fois que vous voulez que votre application fonctionne sur une large gamme de plates-formes supportées, et quand vos vecteurs et les matrices ne sont que de petits à modéré taille, nous vous recommandons d'utiliser les bibliothèques à usage général. OVVC4.LIB (pour MS Visual C ++), VCF4W. LIB (pour Embarcadero / Borland C ++), ou les unités OptiVec \ lib4 (pour Delphi). Ces bibliothèques combinent de bonnes performances avec back-compatibilité avec le matériel plus ancien, jusqu'à 486DX, Pentium, anciens modèles de Athlon. Ils sont tous multi-thread-safe et soutiennent le parallélisme fonctionnel. Si vous n'avez pas besoin pleine précision en virgule flottante et que quantité de back-compatibilité, vous pouvez obtenir des performances supérieures en passant aux P6, P7, ou des bibliothèques de P8 (marqués par le nombre respectif dans le dans le nom de la bibliothèque). Pour les grands vecteurs / matrices sur les machines mono-core de Pentium III +, nous proposons des versions gagnent un peu de performance en contournant simplement le cache de données. Ces grands-Vector bibliothèques sont marqués par la lettre "L": OVVC6L. LIB (pour MS Visual C ++), VCF6L. LIB (pour Borland C ++), ou les unités OptiVec \ LIB6L (pour Delphi). Remplacer le "6" avec "7" pour obtenir les 4+ versions Pentium, et ainsi de suite. Si mal-utilisés pour les petits vecteurs / matrices, les bibliothèques de grande Vector se produiront significativement plus lent que les bibliothèques à usage général! Enfin, pour les grands vecteurs / matrices sur les machines multi-cœurs, nos nouvelles bibliothèques optimisés multi-core distribuent activement la charge de travail sur les cœurs de processeur disponibles pour les données d'exécution parallèle. Ces bibliothèques sont marquées par la lettre «M», comme dans OVVC7M. LIB (pour MS Visual C ++, en utilisant SSE2), VCF4M. LIB (pour Borland C ++, la précision de la FPU complète), ou les unités OptiVec \ LIB8M (pour Delphi, en utilisant SSE3). Ces bibliothèques sont conçues pour AMD 64 x2, Intel Core2 Duo, ou les machines équipées de plusieurs processeurs discrets de niveau Pentium 4+. Les bibliothèques "M" seront toujours fonctionner sur des machines à noyau unique, mais un peu plus lent que les bibliothèques à usage général. Bien que les bibliothèques "M" sont conçues avec les moyennes et grandes vecteurs à l'esprit, la pénalité pour les utiliser avec les petits vecteurs est presque négligeable, comme le fil moteur OptiVec exécute automatiquement une fonction dans un seul fil, si la taille du vecteur est trop petit pour l'exécution en parallèle pour regagner le coût impliqué dans la communication fil à fil. Si vous utilisez les bibliothèques "M", votre programme doit appeler V_initMT avant que les fonctions vectorielles. 1.1.3 CUDA Device Support Les cartes graphiques modernes sont équipés d'une capacité multiprocesseur puissante allant jusqu'à plusieurs centaines de noyaux de processeurs fonctionnant en parallèle. Ces dernières années, les interfaces ont été développées, ce qui permet d'exploiter cette capacité de traitement, non seulement pour le rendu graphique, mais aussi pour des calculs généraux. Une de ces approches est le concept CUDA par NVIDIA. Pratiquement toutes les cartes actuelles graphiques NVIDIA supportent CUDA. En outre, le matériel de CUDA dédié est offert par NVIDIA avec le «Tesla» et de la famille du conseil d'administration "Fermi". Avec les bibliothèques «C» (par exemple OVVC8 C. LIB), OptiVec offre un moyen simple d'utiliser un dispositif de CUDA pour les calculs vecteur / matrice sans les tracas de la programmation fait dans CUDA. Il y a un certain nombre de points à considérer: De toute évidence, les bibliothèques "C" peuvent être utilisés uniquement avec un dispositif CUDA installé. Cela signifie, seuls les produits NVIDIA sont pris en charge. Sur les compilateurs pris en charge par OptiVec. actuellement, NVIDIA fournit un support de CUDA seulement pour MS Visual C ++. Cela signifie qu'il n'y a actuellement pas de bibliothèques CUDA OptiVec pour les compilateurs Embarcadero / Borland disponibles. Il est nécessaire d'avoir le dernier pilote d'affichage installé. Même les ordinateurs flambant neufs le plus souvent ne sont pas les derniers pilotes. Ils doivent être sélectionnés et téléchargés sur le site web de NVIDIA, nvidia. Déjà une carte sous-100 $ graphiques peut améliorer les performances de certaines fonctions sur un ordinateur avec un milieu de gamme CPU par un facteur de 10, le matériel dédié par beaucoup plus. Cependant, la combinaison d'un CPU haut de gamme avec une carte graphique bas de gamme (comme il est souvent trouvé dans les ordinateurs portables) ne marginalement bénéficier des bibliothèques «C». Le coût de l'échange des données avant et en arrière entre la mémoire et la mémoire graphique principale à bord est si élevé qu'il peut être «gagné» retour seulement pour très grands vecteurs et matrices. Par exemple. pour les fonctions mathématiques comme le sinus ou les fonctions exponentielles, CUDA paie de 100.000 éléments vectoriels sur. Pour la multiplication de matrices, le remboursement se produit dans la région de 200x200 éléments. Toutes les fonctions OptiVec vérifier si l'utilisation du dispositif CUDA est logique et décider en conséquence wether à la source-out traitement pour le processeur graphique ou de rester sur le CPU. En utilisant CUDA avec OptiVec est aussi facile que simplement la liaison avec la bibliothèque "C" et avec les bibliothèques d'importation fournies par NVIDIA. Aucune modification de votre code source sont nécessaires. D'autre part, en éliminant les transferts de données répétées pour chaque fonction, la programmation directement pour les appareils CUDA avec le SDK CUDA de nVidia peut conduire à des performances considérablement plus élevé que ce qui est possible avec l'utilisation des bibliothèques OptiVec "C". Comme support pour double précision en virgule flottante est plus de minerai moins restreinte aux cartes Tesla et Fermi coûteux, OptiVec utilise actuellement le dispositif CUDA seulement pour simple précision. Les OptiVec bibliothèques «C» utilisent réellement DLLs développés par NVIDIA. Ceux-ci doivent être installés en même temps que les bibliothèques OptiVec. NVIDIA pourrait à tout moment modifier les conditions de licence pour leurs bibliothèques CUDA, de sorte que nous pourrions à un moment donné ne sera plus en mesure de les inclure dans nos distributions et / ou pour soutenir CUDA du tout. 1.1.4 Le choix de la Bibliothèque OptiVec droit Chaque fois que vous voulez que votre application fonctionne sur une large gamme de plates-formes supportées, et quand vos vecteurs et les matrices ne sont de petite à modérée taille, nous vous recommandons d'utiliser les bibliothèques à usage général. OVVC4.LIB (pour MS Visual C ++), VCF4W. LIB (Embarcadero / Borland C ++ série compilateur), ou les unités OptiVec \ lib4 (pour Delphi). Ces bibliothèques combinent de bonnes performances avec back-compatibilité avec le matériel plus ancien, même jusqu'à 486DX, Pentium, Athlon. Ils sont tous multi-thread-safe et soutiennent le parallélisme fonctionnel. Si vous n'avez pas besoin pleine précision en virgule flottante et que quantité de back-compatibilité, vous pouvez obtenir des performances supérieures en passant au P8 (ou bientôt aussi P9), les bibliothèques (marquée par le nombre respectif dans le dans le nom de la bibliothèque). Pour les grands vecteurs / matrices sur les machines multi-core, multi-core bibliothèques optimisées distribuent activement la charge de travail sur les cœurs de processeur disponibles pour les données d'exécution parallèle. Ces bibliothèques sont marquées par la lettre «M», comme dans OVVC7M. LIB (pour MS Visual C ++, en utilisant SSE2), VCF4M. LIB (pour Embarcadero / Borland C ++, la précision de la FPU complète), ou les unités OptiVec \ LIB8M (pour Delphi, en utilisant SSE3). Ces bibliothèques sont conçues pour AMD 64 x2, Intel Core2 Duo, ou les machines équipées de plusieurs processeurs discrets de niveau Pentium 4+. Les bibliothèques CUDA sont basées sur les bibliothèques "M" et sont marqués par la lettre "C", comme, par exemple en OVVC8C. LIB. Les bibliothèques «M» et «C» seront toujours fonctionner sur des machines à noyau unique, mais un peu plus lent que les bibliothèques à usage général. Bien que les bibliothèques "M" sont conçues avec les moyennes et grandes vecteurs à l'esprit, la pénalité pour les utiliser avec les petits vecteurs est presque négligeable, comme le fil moteur OptiVec exécute automatiquement une fonction dans un seul fil, si la taille du vecteur est trop petit pour l'exécution en parallèle pour regagner le coût impliqué dans la communication fil à fil. Si vous utilisez les «M» ou «C» des bibliothèques, votre programme doit appeler V_initMT (nAvailProcCores) avant que les fonctions vectorielles. Retour à VectorLib Table des matières OptiVec maison 2. Éléments de OptiVec Routines 2.1 Synonymes pour certains types de données Pour augmenter la polyvalence et l'exhaustivité des OptiVec. types de données supplémentaires sont définies dans l'unité ou VecLib: a) C / C ++ uniquement: Le ui de type de données (abréviation. Le 64-bit de type de données entier (__int64 en Colombie-Britannique ++ Builder et MS Visual C ++, Int64 à Delphes) est appelé quad (pour "entier quadword") dans OptiVec. En 32 bits, le quad type est toujours signé. Fonctions pour entiers non signés 64 bits ne sont disponibles que dans les versions 64 bits de OptiVec. Borland C ++ ci-dessous C ++ Builder 2006 uniquement: Pour les versions de la Colombie-Britannique âgés, qui ne prennent pas en charge directement les entiers 64 bits, le quad du type de données est implémenté comme un struct de deux valeurs 32 bits. Les nombres à virgule flottante (de préférence longues doubles avec leur mantisse 64 bits) doivent être utilisés comme intermédiaires. Les fonctions d'interface nécessaires sont setquad. quadtod et _quadtold. En variante, les deux moitiés de 32 bits peuvent être explicitement définis, comme dans: xq. Hi = 0x00000001UL; xq. Lo = 0x2468ABCDUL; Le type de données étendu. qui est familière aux programmeurs Pascal / Delphi, est défini comme un synonyme dans les versions OptiVec pour ce compilateur. b) Delphi uniquement: Le flotteur de type de données, ce qui est familier à C / C ++ programmeurs, est défini comme un synonyme de l'unité. Nous préférons avoir les lettres définissant les types de données réelles de nombre à proximité alphabétique: "D" pour Double, "E" pour Extended, et «F» pour Float. Comme indiqué plus haut, les futurs possibles de 128 bits et 256 bits nombres réels pourraient trouver leur place dans cette série «G» pour la Grande et «H» pour Hyper. Pour des raisons historiques (remontant au développement de Turbo Pascal), les différents types de données entiers ont une nomenclature un peu confuse en Delphi. Afin de rendre la fonction dérivée préfixes compatible avec les C / C ++ versions de OptiVec. on définit un certain nombre de synonymes, comme décrit dans le tableau suivant: Pour avoir un type de données Boolean disponible qui est de la même taille que Integer, nous définissons les IntBool de type. Il est équivalent à LongBool en Delphi. Vous verrez le type IntBool que la valeur de retour de nombreuses fonctions de VectorLib mathématiques. 2.2 Nombres complexes Comme décrit plus en détail pour CMATH. OptiVec prend en charge les nombres complexes à la fois au format cartésienne et polaire. Si vous utilisez uniquement les fonctions vectorisées complexes (mais pas les fonctions scalaires de CMATH), vous ne devez pas explicitement inclure CMATH. Dans ce cas, les types de données complexes suivants sont définis dans Les définitions correspondantes pour Pascal / Delphi sont contenus dans l'unité VecLib: Type fComplex = record Re, Im: Float; fin; tapez dComplex = record Re, Im: Double; fin; tapez eComplex = record Re, Im: Extended; fin; tapez fPolar = record Mag, Arg: Float; fin; tapez dPolar = record Mag, Arg: Double; fin; tapez ePolar = record Mag, Arg: Extended; fin; Si, par exemple, un nombre complexe z est déclarée Pour double précision nombres complexes, l'utilisation dcplx et dpolr. pour précision étendue des nombres complexes, l'utilisation ecplx et epolr. Pointeurs à des tableaux ou des vecteurs de nombres complexes sont déclarées en utilisant les types de données cfVector, cdVector et ceVector (pour le complexe de cartésienne) et pfVector, pdVector et peVector (pour complexe polaire) décrits ci-dessous. 2.3 Types Vector Data Nous définissons, comme d'habitude, a. Contrairement aux autres approches, VectorLib ne permet pas de vecteurs taille zéro! La base de toutes les routines VectorLib est formé par les différents types de données vectorielles indiquées ci-dessous et déclarées ou l'unité VecLib. Par contraste avec la taille fixe des tableaux statiques, les types VectorLib utilisent l'allocation dynamique de la mémoire et permettent de différentes tailles. En raison de cette flexibilité accrue, nous vous recommandons d'utiliser principalement ce dernier. Les voici: En interne, un type de données comme fVector signifie. Remarque: dans le cadre de programmes de Windows, souvent la lettre, comme décrit ci-dessus et dans ce qui suit. spécifique C / C: les éléments du vecteur sont accessibles soit avec l'opérateur [], comme VA [375] = 1.234; ou par le type spécifique des fonctions VF_element (retourne la valeur de l'élément vectoriel souhaité, mais ne peut pas être utilisé pour remplacer l'élément) et VF_Pelement (renvoie le pointeur sur un élément de vecteur). Surtout pour certaines versions plus anciennes Borland C (qui ont un bogue dans le pointeur-arithmetics), VF_Pelement doit être utilisé à la place de la syntaxe X + n. Dans vos programmes, vous pouvez mélanger ces types de vecteurs avec les tableaux statiques de style classique C. Par exemple: faire flotter un [100]; / * Classique statique tableau * / fVector b = VF_vector (100); / * Vecteur VectorLib * / VF_equ1 (a, 100); / * Définir les 100 premiers éléments d'un égal à 1,0 * / VF_equC (b, 100, 3.7); / * Définir les 100 premiers éléments de b égal à 3,7 * / Pascal / Delphi spécifique: Comme en C / C ++, vous pouvez mélanger ces types de vecteurs avec les tableaux statiques de style Pascal classique. tableaux statiques doivent être transmis aux fonctions OptiVec avec les (premiers * fixés 100 éléments de b = 3,7 *) Delphi propose également des tableaux dynamiquement allouées, qui peuvent également être utilisés comme arguments pour les fonctions OptiVec. Le tableau suivant compare les vecteurs à base de pointeurs de VectorLib avec les types de Pascal / Delphi tableau: Pascal / Delphi tableaux statiques / dynamiques (conversions de type de données comme V_FtoD. type de données fonctions indépendantes comme V_initPlot) Retour à VectorLib Table des matières OptiVec maison 3. VecObj. Interface theObject-Oriented pour VectorLib VecObj. C ++ interface orientée objet aux fonctions de vecteur OptiVec a été écrit par Brian Dale, Case Western Reserve University. Parmi les avantages qu'il offre sont les suivantes: allocation automatique et la désallocation de la mémoire manipulation de vecteur simplifiée risque considérablement réduit de fuites de mémoire amélioration de la sécurité d'accès à la mémoire opérateurs surchargés intuitifs appels de fonctions simples Il y a quelques draw-backs, cependant, que vous devriez être au courant: augmentation de la charge du compilateur frais généraux plus grande (comme pour tout code encapsulé C ++!), conduisant à augmentation de la taille du code l'efficacité de calcul diminué vecteurs peuvent être traitées que dans son ensemble, et non pas dans les parties VecObj est contenue dans les fichiers comprennent. MS Visual (++ versions mais pas précédente Borland C) C ++ et Embarcadero / Borland C ++ Builder: Les programmeurs doivent mettre la directive, encapsuler l'adresse de vecteur (pointeur) et la taille. Pour une utilisation plus facile, ces classes ont des noms d'alias fVecObj, dVecObj, et ainsi de suite, avec le type de données signalé par un ou deux premières lettres du nom de la classe, de la même manière que les types de vecteurs décrits ci-dessus. Toutes les fonctions définies dans VectorLib pour un type de données de vecteur spécifique sont contenues en tant que fonctions membres de la classe tVecObj respective. Les constructeurs sont disponibles sous quatre formes: vecteur (); // Alloué pas de mémoire, la taille définie à 0 vecteur (taille ui); // Vecteur d'éléments de taille allouée vecteur (taille de ui, T remplissage); // Comme avant, mais initialisé avec la valeur Pour toutes les classes de vecteurs, les opérateurs arithmétiques + - * / + = - = * = / = sont définis, à l'exception des classes de vecteurs polaires complexes, où seulement multiplications et divisions, mais aucun additions ou des soustractions sont pris en charge. Ces opérateurs sont les seuls cas dans lesquels vous pouvez directement affecter le résultat d'un calcul à un objet vectoriel, comme fVecObj Z = X + Y; ou fVecObj Z = X * 3,5; Notez, cependant, que les ++ règles de syntaxe de classe C ne permettent pas une mise en œuvre très efficace de ces opérateurs. Les fonctions membres arithmétiques sont beaucoup plus rapides. Si la vitesse est un problème, utilisez fVecObj Z. addV (X, Y); ou fVecObj Z. mulC (X, 3,5); au lieu de la syntaxe de l'opérateur. L'opérateur * fait référence à la multiplication élément par élément, pas au produit scalaire de deux vecteurs. Toutes les autres fonctions arithmétiques et de calcul ne peuvent être appelés en tant que fonctions membres du vecteur de sortie respectif comme, par exemple, Y. exp (X). Bien qu'il serait certainement plus logique d'avoir ces fonctions définies de telle sorte que vous pouvez écrire à la place, la syntaxe membre-fonction a été choisie pour des raisons d'efficacité: La seule façon de mettre en oeuvre la deuxième variante consiste à stocker le résultat de la fonction exponentielle X d'abord dans un vecteur temporaire, qui est ensuite copié dans Y, ce qui augmente considérablement les exigences de charge de travail et la mémoire. Alors que la plupart des fonctions sont des fonctions VecObj membres du vecteur de sortie, il existe un certain nombre de fonctions qui ne disposent pas d'un vecteur de sortie. Dans ces cas, les fonctions sont des fonctions membres d'un vecteur d'entrée. Exemple: s = X. mean () ;. Si vous avez besoin de traiter un vecteur VecObj dans une fonction plain-C VectorLib (par exemple, pour traiter seulement une partie de celui-ci), vous pouvez utiliser les fonctions membres getSize () pour récupérer sa taille, getVector () pour le pointeur ( du type de données tVector, où "t" représente le préfixe de type usuel) et pElement (n) pour un pointeur vers la n ième élément. Continuer avec le chapitre 4. Fonctions VectorLib et Routines: Un bref aperçu Retour à VectorLib Table des matières OptiVec maison Droit d'auteur Développement Dr. Martin Sander Software Dernière mise à jour le 31 Janvier 2016




No comments:

Post a Comment