frais généraux de calcul en C # - En utilisant getters / setters par rapport à la modification des réseaux et des vitesses directement coulée

StackOverflow https://stackoverflow.com/questions/3018536

Question

J'allais écrire un message de longue haleine, mais je vais la faire bouillir ici:

Je suis en train d'imiter le style graphique de la vieille école de la NES via XNA. Cependant, mon FPS est lent, en essayant de modifier 65K pixels par image. Si je viens de boucle à travers tous 65K pixels et les mettre dans une certaine couleur arbitraire, je reçois 64FPS. Le code que je fait pour Recherch les couleurs devraient être placés là où, je me 1FPS.

Je pense qu'il est à cause de mon code objet orented.

En ce moment, j'ai des choses divisés en six classes, avec getters / setters. Je devine que je suis au moins appeler 360K getters par image, qui je pense est beaucoup de frais généraux. Chaque classe contient soit / et ou des tableaux 1D ou 2D contenant énumérations personnalisés, int, couleur, ou Vector2D, octets.

Et si je combiné toutes les classes en un seul, et accessible le contenu de chaque réseau directement? Le code ressemblerait un désordre et un fossé les concepts de codage orienté objet, mais la vitesse pourrait être beaucoup plus rapide.

Je suis pas non plus préoccupé par les violations d'accès, comme toute tentative pour obtenir / définir les données dans les tableaux se fait dans des blocs. Par exemple, toute écriture à des tableaux aura lieu avant que les données sont accessibles de leur part.


En ce qui concerne la coulée, j'ai dit que j'utilise énumérations personnalisés, int, couleur, et Vector2D, octets. Quels sont les types de données sont les plus rapides à utiliser et l'accès au NET Framework, XNA, XBox, C #? Je pense que la coulée constante pourrait être une cause de ralentissement ici.

En outre, au lieu d'utiliser les mathématiques pour déterminer quels index les données doivent être placés dans, je l'ai utilisé des tables précalculées recherche donc je n'ai pas à utiliser la multiplication constante, addition, soustraction, division par trame. :)

Était-ce utile?

La solution

Il y a une présentation formidable de la GDC 2008 qui mérite d'être lu si vous êtes un développeur XNA. Il est appelé Comprendre XNA Framework Performance .

Pour votre architecture actuelle - vous n'avez pas vraiment décrit assez bien pour donner une réponse définitive - vous êtes probablement faire trop de « choses » inutiles dans une boucle serrée. Si je devais deviner, je vous suggère que votre méthode actuelle est le cache débattait -. Vous devez corriger votre mise en page de données

Dans le cas idéal, vous devriez avoir une belle grande gamme de petits-as-possible Types de valeur (structs non classes), et une boucle très inline que les données lui fourre dans de façon linéaire.

( Mis : en ce qui concerne ce qui est rapide: entier et flottant mathématiques point est très rapide - en général, vous ne devriez pas utiliser des tables recherche des appels de fonction sont assez rapides - au point que la copie d'un. struct lorsque vous les transmettre seront plus importantes que le JIT inline accesseurs simples et setters -. bien que vous ne devriez pas dépendre de quoi que ce soit en ligne d'autre dans les boucles très serrées -. comme votre blitter)

CEPENDANT - même si optimisé - votre architecture actuelle suce. Ce que vous faites va à l'encontre de la façon dont fonctionne un GPU moderne. Vous devriez le chargement de votre sprites sur votre GPU et de le laisser composite scène.

Si vous voulez manipuler vos sprites à un niveau de pixel (par exemple: swapping palette que vous avez mentionné), vous devriez utiliser les shaders de pixels. La CPU sur les 360 (et sur PC) est rapide, mais le GPU est tellement plus rapide quand vous faites quelque chose comme ça!

Le Effets Sprite échantillon XNA est un bon endroit pour commencer.

Autres conseils

Avez-vous votre code pour profilé déterminer où le ralentissement est? Avant d'aller réécrire votre application, vous devez au moins savoir quelles parties doivent être réécrites.

Je soupçonne fort que les frais généraux des accesseurs et des conversions de données est trivial. Il est que vos algorithmes beaucoup plus susceptibles font un travail inutile, les valeurs recalcul qu'ils pourraient mettre en cache, et d'autres choses qui peuvent être abordés sans faire sauter la conception de votre objet.

Êtes-vous définir une couleur et pour chaque pixel tel ou quelque chose? Si tel est le cas, je pense que vous devriez vraiment penser à l'architecture un peu plus. Commencez à utiliser sprites qui permettra d'accélérer les choses.

EDIT

D'accord, je pense que votre solution pourrait être charge plusieurs sprites avec des couleurs différentes (un sprite de quelques pixels) et de réutiliser ceux-ci. Il est plus rapide pour pointer vers le même sprite que d'assigner une couleur différente à chaque pixel comme l'image-objet a déjà été chargé dans la mémoire

Comme tout problème de performance, vous devez profiler l'application pour identifier les goulots d'étranglement plutôt que d'essayer de deviner. Je doute sérieusement que des accesseurs sont à la racine de votre problème. Le compilateur inline presque toujours ces sortes de fonctions. Je suis aussi curieux de ce que vous avez contre les mathématiques. Deux entiers multipliant, par exemple, est l'une des choses les plus rapides de l'ordinateur peut faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top