2011-07-25 5 views
3

C'est une question que j'aurais probablement dû poser plus tôt, mais je n'ai pas pris la peine de m'amuser avec les trucs de type p/invoke dans MonoTouch. Fondamentalement, j'ai un problème avec les performances relatives à un très grand nombre d'opérations en virgule flottante, en particulier celles impliquant des fonctions min/max, la multiplication de vecteurs et des choses simples (détectant fondamentalement si différents types de formes se croisent ou non).Utiliser P/invoke pour améliorer la performance, faisable ou juste un vœu pieux?

La raison de ces opérations est due à un moteur de physique 2D écrit en C#. Sur certaines plates-formes telles que Windows Phone 7 et la Xbox 360, le moteur physique fonctionne sans accrocs, il vole des cycles de processeur mais laisse beaucoup de temps pour que le jeu tourne à un débit constant.

Le problème est dans MonoTouch fonctionnant sur l'iPhone. Il semble que MonoToch ne soit pas si génial avec autant d'opérations en virgule flottante et que l'iPhone (et EVEN l'iPad 2) se trouve gravement touché et que la physique soit le goulot d'étranglement des performances évident. J'ai profiled the performance et il se résume à un ensemble de fonctions mathématiques relativement simples comme I mentioned before et il n'y a pas de véritable moyen d'optimiser ces fonctions, le moteur physique lui-même est très bien écrit et je ne vois pas d'endroit évident, il est à la traîne et franchement Je doute qu'il y ait quelque chose qui ne va pas en tant que moteur physique 2D C#. À cette fin, j'ai résolu de trouver un moteur de physique écrit en C (ou C++ si possible) et de le brancher avec l'application principale MonoTouch. Mon raisonnement est que les problèmes de performance dans MonoTouch ont probablement quelque chose à voir avec le fait que le compilateur MonoTouch ne compile pas le code .net aussi vite que le font les compilateurs WIT de Jp7/xbox 360 (ce qui est compréhensible) et les exécuter nativement aiderait à améliorer la performance. Donc, mon idée est que je vais utiliser Box2D, écrire un tas de fonctions wrapper statiques (telles que CreateWorld(), CreateBox(), GetBodyPosition (int id), etc., etc) et de tout ce qui se passe dans via p/invoquer la fonctionnalité et l'intégrer dans ma classe de wrapper physique, de cette façon la logique du jeu de base nécessitera peu ou pas de modifications et je peux maintenir l'intégrité de la conception de code originale mais aussi gagner en performance en raison du fonctionnement de la physique En C. natif

Mais cela m'a fait penser, les problèmes de performance découlent de fonctions mathématiques très simples et directes, de simples multiplications et de comparaisons de tailles. Si l'exécution de fonctions via p/invoke améliore la vitesse, il suffit de réécrire une fonction telle que Vector2.Max en tant que fonction C et d'invoquer cela pour améliorer également les performances.

Cela semble toutefois un peu tiré par les cheveux, si ce n'était pas le cas, Mono le ferait quand même? Donc, ma question générale est la suivante: est-ce que les bibliothèques natives liées statiquement fonctionnent mieux lorsqu'elles sont appelées depuis p/invoke que la fonction C# équivalente compilée par MonoTouch?

Répondre

3

Il n'y a vraiment qu'une seule façon de savoir si c'est plus rapide: comparer votre cas. Il se peut que le compilateur c que vous utiliseriez pour la bibliothèque native soit capable d'optimiser plus que ce que fait le jit mono, ou que le cpu ne soit pas bien adapté à votre charge de travail particulière. Si vous souhaitez essayer d'utiliser une bibliothèque native, sachez que vous ne voulez pas appeler le code natif de la gestion souvent, il y a un impact significatif sur les performances pour chaque transition native (quelle importance dépend de beaucoup) de facteurs, mais moins de transitions est toujours mieux). Cela dit, mon estimation personnelle serait que le mono jit ne gère pas les opérations à virgule flottante aussi bien qu'il le pourrait (il y a eu des problèmes avec cela auparavant sur certains processeurs, je ne me souviens plus si ces problèmes n'existe pas sur lequel cpus), donc vous bénéficieriez d'utiliser une bibliothèque native.

+0

-vous Ména les questions relatives à la compilation du pouce? Je ne suis pas sûr que ce soit spécifique au mono mais j'ai été sûr de l'éteindre car il aurait un impact sur les performances des opérations en virgule flottante. Mon objectif est de faire le moins possible en code managé et de reporter autant d'opérations sur natif, le moteur physique fonctionnera nativement et n'interagira qu'un nombre minimal de fois pour garder les valeurs mises à jour du côté géré (ie l'état de la scène, la position de tous les corps, etc, etc). – tweetypi

+0

Les problèmes pourraient avoir été avec la compilation de pouce, je ne suis pas sûr, je me souviens juste de lire quelque chose sur les questions de mathématiques à virgule flottante quelque part. Votre approche semble être la bonne pour obtenir tous les avantages possibles du code natif. –

2

Si vous avez des sections critiques de votre code, vous pouvez essayer d'utiliser "non sécurisé" pour éviter la vérification automatique de la portée de l'accès au tableau. Pour les réseaux courts tels que les vecteurs 2 ou 3 et les opérations simples (comme les produits normaux ou scalaires), cela peut avoir un effet.

Les opérations mathématiques simples ne doivent pas être plus lentes, mais il est difficile de déterminer quelles parties du code sont plus lentes sans les résultats de profilage. Si la version native utilise sse lourdement ou si votre version gérée utilise involontairement beaucoup de boxe etc., cela peut causer la divergence.Pour P/invoke être utile, vous devriez faire quelques appels qui font beaucoup de travail, il peut donc être utile si vous pouvez mettre à jour l'état entier dans un appel à la DLL natif. Mais je ne vais certainement pas essayer de faire des fonctions triviales natives.

1

En plus de la bonne réponse de Rolf, vous pourriez envisager d'utiliser l'optimisation LLVM lors de la construction de votre jeu.

Je trouve surprenant que Windows Phone 7 a un meilleur compilateur JIT que statique Mono

+0

J'utilise la compilation LLVM mais malheureusement les améliorations sont marginales. Pensez-vous qu'il est possible que le matériel WP7 soit juste plus puissant que le matériel iPhone4, donc pourquoi WP7 gère-t-il mieux les framerate sur le même code? Ils ont tous les deux des processeurs 1ghz mais de différents fournisseurs. Pourtant, l'iPad 2 qui doit avoir de meilleures caractéristiques que WP7 reste en retard sur le jeu et donne un framerate plus important qu'un WP7 ... – tweetypi

+0

J'adorerais voir ton code qui fonctionne lentement, on peut y jeter un coup d'oeil profiler –

+0

Je serais heureux de vous laisser jeter un oeil sur le code, écrivez-moi à [email protected] et je vous envoie le projet – tweetypi

Questions connexes