2009-04-15 7 views
10

J'écris une application DSP en C# (essentiellement un éditeur multipiste). Je l'ai profilé depuis un certain temps sur des machines différentes et j'ai remarqué des choses «curieuses».Forcer le compilateur .NET JIT à générer le code le plus optimisé lors du démarrage de l'application

Sur mon ordinateur personnel, la première exécution de la boucle de lecture prend environ 50% à 60% du temps disponible (je suppose que c'est dû au JIT qui fait son travail), puis pour les boucles suivantes à une consommation régulière de 5%. Le problème est que, si j'exécute l'application sur un ordinateur plus lent, la première exécution prend plus de temps que le temps disponible, provoquant l'interruption de la lecture et le décodage de l'audio de sortie, ce qui est inacceptable. Après cela, il descend à une consommation de 8% -10%.

Même après la première exécution, l'application continue d'appeler de temps en temps des routines qui prennent du temps (toutes les 2 secondes plus ou moins), ce qui entraîne une consommation régulière de 5% à des pics très courts de 20% à 25% . J'ai remarqué que si je laisse l'application fonctionner pendant un certain temps, ces pics vont également descendre à 7% -10%. (Je ne suis pas sûr que cela soit dû à la recompilation par le JIT de ces portions de code).

Donc, j'ai un sérieux problème avec le JIT. Bien que l'application se comporte bien même dans des machines très lentes, ces «tempêtes de compilation» vont être un gros problème. J'essaie de comprendre comment résoudre ce problème et j'ai trouvé une idée, qui est de marquer toutes les routines 'sensibles' avec un attribut qui dira à l'application de les 'presser' au préalable pendant le démarrage , afin qu'ils soient entièrement optimisés quand ils sont vraiment nécessaires. Mais ce n'est qu'une idée (et je ne l'aime pas trop non plus) et je me demande s'il y a une meilleure solution à tout le problème. Je voudrais savoir ce que vous en pensez.

(NGEN l'application est pas une option, je l'aime et que vous souhaitez toutes les optimisations JIT je peux obtenir.)

EDIT:

consommation de mémoire et de collecte des ordures coups de pied ne sont pas un problème, je suis l'utilisation de pools d'objets et le pic maximal de mémoire pendant la lecture est de 304 Kb.

+1

Il serait utile si vous avez dit ** pourquoi ** NGEN n'est pas une option; comprendre le problème est la moitié du travail ... –

+0

Quelles optimisations JIT ne sont pas disponibles lorsque NGen-ing? – Will

+0

@Marc: J'utiliserais l'application en dernier recours, mais je préférerais ne pas l'utiliser s'il existe une meilleure solution. – Trap

Répondre

16

Vous pouvez déclencher le compilateur JIT pour compiler l'ensemble de vos ensembles au cours de la routine d'initialisation de votre application en utilisant la méthode PrepareMethod ... (sans avoir à utiliser NGen).

Cette solution est décrite plus en détail ici: Forcing JIT Compilation During Runtime.

4

La vitesse initiale ressemble en effet à Fusion + JIT, qui serait aidé par ILMerge (pour Fusion) et NGEN (pour JIT); vous pourriez toujours jouer une piste silencieuse à travers le système au démarrage afin que cela fasse tout le travail sans que l'utilisateur ne remarque aucune distorsion?

NGEN est une bonne option; Y at-il un raison vous ne pouvez pas l'utiliser?

Les problèmes que vous mentionnez après la charge initiale ne pas son comme ils sont liés à JIT. Peut-être la collecte des ordures.

Avez-vous essayé le profilage? CPU et mémoire (collections)?

+0

Pour moi, la seule raison de ne pas utiliser ngen serait qu'il nécessite des privilèges d'administrateur lors de l'installation, ne s'appliquant donc pas aux installations par utilisateur sur les réseaux d'entreprise. Peut-être que c'est aussi la raison du PO? –

+0

Pourquoi ne pas faire NGEN comme une option sur l'installation alors? Donc, si vous avez des droits d'administrateur, faites-le. Sinon, avertissez l'utilisateur et ne le faites pas. –

3

Comme Marc l'a mentionné, les pics en cours ne ressemblent pas à des problèmes JIT. Autres choses à rechercher:

  • Garbage Collection - Allouez-vous de la mémoire lors de votre traitement audio? Si vous créez beaucoup d'ordures, ou même des objets qui survivent à une collection Gen 0, cela peut provoquer des pics notables. Il semble que vous faites une sorte de pré-allocation, mais attention aux allocations cachées dans le code de la bibliothèque (même une boucle foreach peut allouer!)

  • Dénormaux. Il y a un problème avec certains types de processeurs lorsqu'il s'agit de très petits nombres à virgule flottante qui peuvent provoquer des pics d'UC. Voir http://www.musicdsp.org/files/denormal.pdf pour plus de détails.

Edit:

Même si vous ne voulez pas utiliser NGen, au moins comparer une version NGen'd afin que vous puissiez voir ce que fait la différence Jiting

+1

Intéressant. Je n'avais aucune idée que les dénormaux étaient une telle bosse de vitesse monstrueuse. –

2

Si vous pensez que vous êtes impacté par JIT, précompilez votre application avec NGEN et réexécutez les tests. Il n'y a pas de surcharge JIT dans le code qui a été compilé par NGEN. Si vous voyez toujours des pics dans l'application NGEN'd, alors vous savez qu'ils ne sont pas causés par JIT.

Questions connexes