2016-04-20 4 views
1

Ich arbeite an einem rechenintensiven C# -Projekt, das mehrere Algorithmen implementiert. Das Problem ist, dass wenn ich meine Anwendung profilieren möchte, die Zeit für einen bestimmten Algorithmus variiert. Zum Beispiel dauert das Ausführen des Algorithmus 100 Mal ungefähr 1100 ms und ein weiteres Mal 100 Mal dauert viel mehr Zeit als 2000 oder sogar 3000 ms. Es kann sogar im selben Lauf variieren. Es ist also unmöglich, Verbesserungen zu messen, wenn ich ein Stück Code optimiere. Es ist einfach unzuverlässig.CPU-Affinität für Profilerstellung festlegen

enter image description here

ist hier ein anderer Lauf:

enter image description here

Also im Grunde möchte ich sicherstellen, dass eine CPU meiner App gewidmet ist. Der PC hat eine alte Dual-Core-Intel E5300 CPU läuft auf Windows 7 32 Bit. Ich kann also nicht nur die Prozessaffinität festlegen und einen Kern für immer vergessen. Es würde den Computer für tägliche Aufgaben sehr langsam machen. Ich brauche andere Apps, um einen bestimmten Kern zu verwenden, wenn ich es wünsche, und wenn ich fertig bin, Profiling, die CPU-Affinitäten wieder normal zu werden. Eine Fledermaus-Datei zu haben, wäre eine fantastische Lösung.

Meine Frage ist: Ist es möglich, eine Bat-Datei zu haben, um Prozessaffinität für jeden Prozess auf Windows 7 zu setzen?

PS: Der Algorithmus ist korrekt und jedes Mal wird der gleiche Codepfad ausgeführt. Ich habe einen Objektpool erstellt, so dass nach dem ersten Lauf kein Speicher mehr zugewiesen wird. Ich habe auch Speicherzuordnung mit Dottrace profiliert und es zeigte keine Zuordnung nach dem ersten Lauf. Ich glaube also nicht, dass GC ausgelöst wird, wenn der Algorithmus arbeitet. Physischer Speicher ist verfügbar und das RAM des Systems ist nicht erschöpft.

Ergebnis: Die Antwort von Chris Becke erledigt die Aufgabe und stellt die Prozessaffinitäten genau so ein, wie es beabsichtigt ist. Dies führte zu einheitlicheren Ergebnissen, insbesondere wenn Hintergrund-Apps wie Visual Studio und Dottrace laufen. Eine weitere Untersuchung der abweichenden Ausführungszeit ergab, dass die Ursache für die Unvorhersehbarkeit CPU-Überhitzung ist. Der CPU-Überhitzungsalarm war ausgeschaltet, während die Temperatur über 100 ° C war! Nach der Reparatur des defekten Lüfters wurden die Ergebnisse vollkommen einheitlich.

+0

Behandeln Sie niemals einen Benchmark, der nur optimistisch gute Ergebnisse liefert, die sich nie in der Produktion reproduzieren. Wenn Sie * double * in Ihrem Berechnungscode verwenden und es im 32-Bit-Modus ausführen, können Sie 3 unterschiedliche Zeitpunkte erhalten. Worst-Case ist ein Fett x3 langsamer als der Best-Case. Riecht so, als würde das passieren. Entfernen Sie das Jitter-Forcen, damit es im 64-Bit-Modus ausgeführt werden kann. Projekt> Eigenschaften> Registerkarte Erstellen> Platform target = AnyCpu und Prefer 32-bit unmarked. –

+0

@HansPassant Ich habe die Projekteinstellungen überprüft und es ist auf Any CPU und die 32bit ist lieber deaktiviert.Ich verstehe Ihren Standpunkt, dass Sie die Benchmark nicht behandeln. Das Problem, mit dem ich konfrontiert bin, ist, dass die Ausführungszeit für den Code in der laufenden Sitzung sehr unterschiedlich ist. Auf den Screenshots wird gezeigt, dass manchmal die Ausführungszeit je Aufruf unterschiedlich ist und manchmal ist es fast gleich. Ich versuche nicht, einen künstlichen Gewinn zu erzielen. Ich möchte eine zuverlässige und wiederholbare Umgebung, sodass ich jedes Mal, wenn ich versuche, eine Methode zu optimieren, weiß, ob sie den Code schneller oder langsamer macht. –

+0

Nun, Sie haben anscheinend ein 32-Bit-Betriebssystem, daher werden diese Einstellungen keinen Unterschied machen. Wenn du kein 64-Bit-Betriebssystem bekommst, dann mach einfach weiter, es wird nicht hübscher. Nimm den Median und nenne ihn einen Tag. –

Antwort

2

Sie meinen SetProcessAffinityMask?

Ich sehe diese Frage, während gekennzeichnete Fenster, ist C#, also ... Ich sehe das System.Diagnostics.Process Objekt hat ein ThreadAffinity Mitglied, das die gleiche Funktion ausführen sollte.

Ich bin nur nicht sicher, dass dies die CPU-Zeiten in der Art, wie Sie erwarten, stabilisieren wird. Eine einzelne busy-Task, die IO nicht ausführt, sollte trotzdem auf dem gleichen Core geplant bleiben, es sei denn, ein anderer Thread unterbricht sie. Daher denke ich, dass Ihre variablen Zeiten eher darauf zurückzuführen sind, dass andere Threads/Prozesse Ihren Algorithmus unterbrechen Core - Wenn Sie nicht die Affinität für alle anderen Threads im System festlegen, um Ihren bevorzugten Core auszuschließen, kann ich diese Hilfe nicht sehen.

+0

Eigentlich frage ich nach einer Möglichkeit, die Affinität aller anderen Prozesse festzulegen, so dass sie die Leistung meiner Anwendung nicht beeinflussen. Ich entfernte das C# -Tag, weil es etwas irreführend war. Das tut mir leid. –

+1

Nun, SetProcessAffinityMask wird tun, was Sie wollen. 'EnumProcesses' füllt ein Array mit Prozess-IDs und' OpenProcess' konvertiert diese in die HANDLE, die Sie für 'SetProcessAffinityMask' benötigen. Sie haben wahrscheinlich einige Probleme beim Öffnen bestimmter Systemprozesse. Vergiss nicht, danach alles zurück zu legen. –

+0

Da dies kein Produktionscode ist, könnten Sie bessere Ergebnisse erzielen, wenn Sie nur Ihre Threadpriorität über 'SetThreadPriority' erhöhen. –

Verwandte Themen