Life Is Good Geschrieben 6. Dezember 2017 Melden Share Geschrieben 6. Dezember 2017 vor 3 Stunden schrieb runner78: Hauptziel von async/await war die UI Programmierung, um den UI-Thread nicht zu blockieren. Hmpf. Ich versteh nicht ganz warum du das jetzt schreibst. Kann man das als Zitat Ja. zusammenfassen und interpretieren ? Wenn du einen Thread entlasten willst hast du bloß 2 Möglichkeiten (so funktionieren CPUs nunmal) entweder du verteilst die Arbeit über mehr Zeit (So wie Coroutinen) oder du lagerst sie auf seperate Threads aus. Da steckt keine dunkle Magie hinter asynchroner Programmierung. (Dass die Heinzelmännchen kommen, wenn du die Keywords async und await nutzt ist bloß ein Mythos ) vor 3 Stunden schrieb runner78: Coroutinen an sich blockieren immer den Main Thread, nur eben aufgeteilt auf mehrere Frames. Was du hier als "blockieren" bezeichnest ist halt die Art, wie unsere Prozessoren funktionieren. Await auf dem selben Thread macht da nichts anderes, siehe oben. vor 3 Stunden schrieb runner78: Das neue Entity System Hier bin ich mal pingelig. Unity Tech arbeitet gerade an einem Entity-Component System.Entity System != Entity Component System; außerdem: Entity Component Model (oft einfach Entity Component, EC) != Entity System und Entity Component != Entity Component System (ECS) vor 3 Stunden schrieb runner78: Das neue Entity System benutzt ein "Data oriented design" und wurde für eine gute Zusammenarbeit mit dem c# Jobsystem entwickelt, das Multithreading auf das äußerste ausreizen dürfte. Jein. Dass Daten & Logik (Behaviour) voneinander getrennt werden ist schon DoD mäßig, das ist richtig. Aber ein ECS schließt im Grunde DoD aus. Siehe https://en.wikipedia.org/wiki/Data-oriented_design Denn 1. ist DoD das genaue Gegenteil von sowas wie ECS, EC, MVC etc. Bei DoD folgst du keinen strengen Paradigmen, und keinem festen Design Plan. 2. ist vieles am ECS (variiert natürlich je nach Implementation) ziemlich anti DoD. Beispiel: Eine super Klasse wie Unity's Object Klasse. Alle Objekte (ob GameObject oder Komponenten) erben von Object. In DoD hast du sowas nicht, weil es Datenmüll und Abhängigkeit produziert. (DoD ist vorallem auf high performance ausgerichtet, wie man dem Namen wohl entnehmen kann.) Manchmal allokiert man absichtlich überflüssigen Speicher, aber das ist ein anderes Thema. Zu deinen anderen Texten: Ich verstehe Englisch recht gut, danke Darauf wollte ich nicht hinaus. Sondern, dass du 2, statt einem Objekt hast, was wieder ziemlich anti DoD ist. Vorallem aber macht es den Code komplexer. Wie gesagt, ECS ist (zumindest aktuell) auch nicht wirklich verbreitet. Ein guter link noch http://gamedevs.org/uploads/pitfalls-of-object-oriented-programming.pdf Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 7. Dezember 2017 Autor Melden Share Geschrieben 7. Dezember 2017 vor 12 Stunden schrieb Life Is Good: Hmpf. Ich versteh nicht ganz warum du das jetzt schreibst. Kann man das als vor 12 Stunden schrieb Life Is Good: zusammenfassen und interpretieren ? Wenn du einen Thread entlasten willst hast du bloß 2 Möglichkeiten (so funktionieren CPUs nunmal) entweder du verteilst die Arbeit über mehr Zeit (So wie Coroutinen) oder du lagerst sie auf seperate Threads aus. Da steckt keine dunkle Magie hinter asynchroner Programmierung. (Dass die Heinzelmännchen kommen, wenn du die Keywords async und await nutzt ist bloß ein Mythos ) Asynchron bedeutend nicht automatisch im Hintergrund. Coroutinen sind abhängig von der Framerate, auch wenn der Prozessor noch Ressourcen frei hat, z.B. bei fixen Frameraten, wird die Ausführung unnötig in die länge gezogen. Ich werde mal heute Abend mal etwas experimentieren, mal sehen wie sich Coroutinen und async/await so in Sachen Performance so verhalten, wenn man im Mainthread bleibt. vor 13 Stunden schrieb Life Is Good: Hier bin ich mal pingelig. Ich war hier einfach zu faul es auszuschreiben vor 13 Stunden schrieb Life Is Good: Jein. Dass Daten & Logik (Behaviour) voneinander getrennt werden ist schon DoD mäßig, das ist richtig. Aber ein ECS schließt im Grunde DoD aus.... Ein so ganz festes Pattern scheint Unity hier aber nicht zu haben. du musst nicht 2 Klassen machen, du kannst ja auch eine ScriptBehaviour machen, die bestehende Daten benutzt, ohne eine eigene DataComponent an das Entity zu hängen. Die Daten-Componenten sind alles structs, die werden nicht mehr von Unitys "Object" ableiten. Eigentlich ist es noch zu früh für diese Diskussion, da man noch nicht selbst reinschnuppern kann. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Life Is Good Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 vor 14 Minuten schrieb runner78: Coroutinen sind abhängig von der Framerate Ahhh, jetzt versteh ich worauf du hinaus willst. Naja, dafür müsste man sich async / await mal genauer anschauen. Wie genau die das intern machen weiß ich gerade nicht. Aber das Prinzip bleibt ja das selbe vor 15 Minuten schrieb runner78: Eigentlich ist es noch zu früh für diese Diskussion, da man noch nicht selbst reinschnuppern kann. Da stimme ich zu, also lass ich's mal so stehen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 Zitat Coroutinen sind abhängig von der Framerate, Sind sie nicht, es ist genau anders herum. Coroutinen beeinflussen die Framerate, werden aber immer zu einem definierten Zeitpunkt durch den Prozessor (in Unity auf dem Mainthread) ausgeführt, dauert eine Coroutine zu lang, verschlechtert sich deine Framerate in Unity. Unity main thread auf CPU Kernel 1: Loop each Frame: { Unitykernelprozess Coroutine 1 (skip/wait or execute next coroutine instructions?) Coroutine 2 (skip/wait or execute next coroutine instructions?) Coroutine 3 (skip/wait or execute next coroutine instructions?) } Werden Instruktionen einer Coroutine ausgeführt, verlängert sich die Ausführungszeit pro Frame (Time.deltatime). Kann man dagegen einen Thread auf den 2. CPU Kernel auslagern, so wird sich deine FPS verbessern (Vorrausetzung ist natürlich man hat eine CPU mit mehreren Kernels und man verwendet keine Unity-Kernelfunktionen innerhalb des Threads) Womit ich mich allerdings noch nicht im Detail beschäftigt habe, wie ermittle ich, auf welchem Kernel der Unity-Mainthread aktuell läuft und wie starte ich einen Thread auf einem spezifischen Kernel. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Life Is Good Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 Ich glaube nicht, dass er das meinte, sondern, dass MoveNext() in Update statt findet. In diesem Sinne ist deine Coroutine schon ein wenig davon abhängig. Ansonsten scheint await nicht sonderlich davon abzuweichen. Der Compiler generiert eine Statemachine, die von der Struktur ähnlich wie IEnumerator & yield aussieht. Der Unterschied ist, das MoveNext() dort über Callbacks (sobald die Arbeit verichtet wurde) aufgerufen wird. Wie das aussieht, wenn auf dem selben Thread gewartet wird hab ich jetzt auf die Schnelle aber nicht herausgefunden.https://weblogs.asp.net/dixin/understanding-c-sharp-async-await-1-compilation Wenn du mit "Kernel" CPU Kerne meinst, das übernimmt für gewöhnlich das Betriebssystem. Vermutlich liegt der Unity Main Thread einfach auf dem 1. Kern. Mit https://msdn.microsoft.com/en-us/library/system.diagnostics.process.processoraffinity.aspx könntest du allerdings Threads auf spezifischen Kernen starten. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 Mit Kernel meinte ich den jeweiligen Prozessorkern. Wenn man Threads oder Tasks ohne Prozessorkernzuordnung startet, dann läuft man Gefahr, daß diese Threads oder Tasks ebenfalls auf dem 1 Core laufen und damit bremst man ja den Core aus, auf dem Unity ohnehin schon läuft. Wenn ich google finde ich auch sowas in der Richtung wss du meintest:https://stackoverflow.com/questions/6584397/how-to-start-a-thread-on-a-specific-core Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 7. Dezember 2017 Autor Melden Share Geschrieben 7. Dezember 2017 vor 3 Stunden schrieb Zer0Cool: Sind sie nicht, es ist genau anders herum. Coroutinen beeinflussen die Framerate, werden aber immer zu einem definierten Zeitpunkt durch den Prozessor (in Unity auf dem Mainthread) ausgeführt, dauert eine Coroutine zu lang, verschlechtert sich deine Framerate in Unity. Doch, Coroutinen sind von der Framerate abhängig, alles zwischen 2 yield returns wird in einem Frame ausgeführt. Bei einer fixen Framerate wäre die Ausführungsdauer unabhängig der Prozessorgeschwindigkeit immer gleich. Auch wenn die Anweßung zwischen zwei yields nur 2 Millisecunden dauert, wird bei 60 FPS erst 15 Millisekunden später wieder vorgesetzt. In solchen Fällen sollte man die Logik in einen seperaten Thred arbeiten lassen, und da ist async/await mit Task die nach meinen bisherigen Erfahrung die Variante mit dem geringsten Overhead. Auf welchen Prozessorkern was läuft, das entscheidet in der Regel das Betriebsystem. vor 46 Minuten schrieb Life Is Good: Der Compiler generiert eine Statemachine, die von der Struktur ähnlich wie IEnumerator & yield aussieht. Der Unterschied ist, das MoveNext() dort über Callbacks (sobald die Arbeit verichtet wurde) aufgerufen wird. Wie das aussieht, wenn auf dem selben Thread gewartet wird hab ich jetzt auf die Schnelle aber nicht herausgefunden. Ein unterschied ist noch, die Statemachine wird als Valuetype realiesiert, der Enumerator als Referenztype. async/await ist nicht wirklich dafür ausgelegt, Logik asynchron innerhalb der Anwendung auf dem Mainthread auszuführen, so wie es die Coroutine macht. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 Zitat Doch, Coroutinen sind von der Framerate abhängig, alles zwischen 2 yield returns wird in einem Frame ausgeführt Da ist man aber selbst schuld wenn man sowas macht. Klar kann ich eine Coroutine jedes Frame ausführen lassen, muss ich aber nicht und sollte man auch nicht, insofern es nicht zwingend notwendig ist. // suspend execution for 5 seconds yield return new WaitForSeconds(5); Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 7. Dezember 2017 Autor Melden Share Geschrieben 7. Dezember 2017 vor 1 Minute schrieb Zer0Cool: Da ist man aber selbst schuld wenn man sowas macht. Klar kann ich eine Coroutine jedes Frame ausführen lassen, muss ich aber nicht. Ich habe auch schon Methoden gesehen, wo jemand erst ganz am ende den yield return gesetzt hatte. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 Gerade eben schrieb runner78: Ich habe auch schon Methoden gesehen, wo jemand erst ganz am ende den yield return gesetzt hatte. Bin ja eh der Meinung so jemand sollte die Finger komplett vom "IEnumerator" weglassen und Invoke() und InvokeRepeat() verwenden Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 7. Dezember 2017 Melden Share Geschrieben 7. Dezember 2017 Man könnte fast meinen, das meinst du ernst Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 8. Dezember 2017 Melden Share Geschrieben 8. Dezember 2017 Hab mal nachgeforscht, man kann zwar den Core für einen Prozess setzen, aber für einen Thread gestaltet es sich schwierig. Die Threads werden wohl entweder durchs Betriebssystem über die Kerne verteilt oder hängen am Kern ihres Prozesses, wobei letzteres schlecht wäre. Hier ist Code zum Setzen eines Cores für einen einzelnen Thread, aber zumindest unter Unity scheint er nicht zu funktionieren:http://blog.rebuildall.net/2010/03/08/Running_NET_threads_on_selected_processor_cores Der Thread lief bei mir nicht an, immer wenn ich die "CurrentThread.ProcessorAffinity" gesetzt habe. Mhh wirft eine Exception: "Operation is not valid due to the current state of the object" Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 8. Dezember 2017 Melden Share Geschrieben 8. Dezember 2017 Ok, das Problem ist, Unity gibt die Threads von sich selbst nicht zurück und daher wurde der Thread nicht gefunden und daher konnte ich die Affinität nicht setzen .. Unity 2017.1.2https://forum.unity.com/threads/process-getcurrentprocess-threads-count-returns-zero-all-the-time.292069/ Hier ein ganz einfaches Beispiel, um den Fehler zu verdeutlichen. Auch wenn man selber einen Thread erzeugt, wird dieser nicht gelistet. using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Threading; using System.Diagnostics; using System.Runtime.InteropServices; public class MultiCoreTest : MonoBehaviour { void Start() { // Make sure there is an instance of Unity running. Process[] unityProcesses = Process.GetProcessesByName("Unity"); // Sollte 1 zurückgeben UnityEngine.Debug.Log("Number of Unity processes: " + unityProcesses.Length); ProcessThreadCollection threads; unityProcesses[0].Refresh(); // Sicherheitshalber noch einmal refreshen threads = unityProcesses[0].Threads; // Sollte > 0 zurückgeben UnityEngine.Debug.Log("Number of Unity threads: " + threads.Count); // Der Rest funktioniert leider nicht mehr, da keine Threads zurückgeben werden // Set the properties on the first ProcessThread in the collection // threads[0].IdealProcessor = 0; // threads[0].ProcessorAffinity = (IntPtr)1; } Siehe auch:https://msdn.microsoft.com/de-de/library/system.diagnostics.processthread.processoraffinity(v=vs.110).aspx Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 8. Dezember 2017 Autor Melden Share Geschrieben 8. Dezember 2017 Im Ressourcenmonitor von Windows kannst du nachsehen, wie viele Threads Unity verwendet, der Editor benutzt bei mir zwischen 124 und 127 Threads im Editromodus, im Gamemodus ca. 128 (Unity 2017.3.0f1) Ich denke, es ist wohl besser die Hände davon zu lassen, am Ende macht man alles nur schlimmer. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 8. Dezember 2017 Autor Melden Share Geschrieben 8. Dezember 2017 vor 8 Stunden schrieb Zer0Cool: Hier ein ganz einfaches Beispiel, um den Fehler zu verdeutlichen. Auch wenn man selber einen Thread erzeugt, wird dieser nicht gelistet. Nachtrag: Wenn man das Codebeispiel in einer einfachen .net Konsoleanwendung ausprobiert, listet er die Thread korrekt. Entweder ein Bug von Unity, oder Unity verhindert hier bewusst das manipulieren der Threads. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 8. Dezember 2017 Melden Share Geschrieben 8. Dezember 2017 vor 1 Stunde schrieb runner78: Nachtrag: Wenn man das Codebeispiel in einer einfachen .net Konsoleanwendung ausprobiert, listet er die Thread korrekt. Entweder ein Bug von Unity, oder Unity verhindert hier bewusst das manipulieren der Threads. Ja, vermutlich ein Bug:https://stackoverflow.com/questions/28014662/current-process-without-threads?noredirect=1#comment44416985_28014662 Zitat Im Ressourcenmonitor von Windows kannst du nachsehen, wie viele Threads Unity verwendet, der Editor benutzt bei mir zwischen 124 und 127 Threads im Editromodus, im Gamemodus ca. 128 (Unity 2017.3.0f1) Die interessante Frage ist aber, wie viele von diesen Threads laufen auf dem gleichen Core. Ich habe hier 12 Cores und Windows ist nicht in der Lage anzuzeigen, welche Threads auf welchem Core laufen. Ich vermute nämlich, daß sich eine große Anzahl der Unity Threads auf dem gleichen Core tummeln. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 8. Dezember 2017 Autor Melden Share Geschrieben 8. Dezember 2017 Windows kann Threads auch von Kern zu Kern schieben. In der Regel regelt das Betriebsystem es so, das die Threads optimial auf die Kerne verteilt werden. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 8. Dezember 2017 Melden Share Geschrieben 8. Dezember 2017 Sie sind leider nicht optimal verteilt, die Last verteilt sich auf die ersten 7 Kerne von insgesamt 12 Kernen. Scheinbar bevorzugt Unity auch die geraden Prozessorkerne. Am meisten sind der Kerne 2 und 4 "belagert". Dies kann natürlich von Betriebsystem zu Betriebssytem und von Unityversion zu Unityversion verschieden sein. Aber ich vermute trotzdem, daß die hinteren Cores oft frei sind... Die Kerne 3,5,7,9,11 sind beispielsweise fast komplett ohne Arbeit. Dies kann aber auch am Hyperthreading liegen, wobei das OS gerade Kerne bevorzugt. Wäre aber auch ein Ansatzpunkt, der dafür spricht, nebenläufige Tasks in Unity in die ungeraden hinteren Kerne zu packen, damit vom Hyperthreading profitiert wird. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 8. Dezember 2017 Autor Melden Share Geschrieben 8. Dezember 2017 Ich glaube das könnte wirklich Hyperthreading liegen. Wenn man jetzt aber anfängt manuell die Thread auf bestimmte Kerne zu beschränken, kann es aber auch dazukommen, dass man einen Kern erwischt, der vielleicht von einem anderen Prozess stärker Ausgelastet wird. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
runner78 Geschrieben 23. Juli 2018 Autor Melden Share Geschrieben 23. Juli 2018 Am 7.12.2017 um 23:26 schrieb Zer0Cool: Mit Kernel meinte ich den jeweiligen Prozessorkern. Wenn man Threads oder Tasks ohne Prozessorkernzuordnung startet, dann läuft man Gefahr, daß diese Threads oder Tasks ebenfalls auf dem 1 Core laufen und damit bremst man ja den Core aus, auf dem Unity ohnehin schon läuft. Wenn ich google finde ich auch sowas in der Richtung wss du meintest:https://stackoverflow.com/questions/6584397/how-to-start-a-thread-on-a-specific-core Aus heutiger Sicht sollte man nach meiner Meinung wenn möglich das neue Unity JobSystem benutzen. Das hat wenig Overhead, mit Burst sehr schnell, und Jobs laufen nie auf dem Selben Kern wie der Mainthread. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.