Jump to content
Unity Insider Forum
  • Announcements

    • Lars

      Allgemeine Forenregeln   03/13/2017

      Forenregeln Nimm dir bitte einen Moment um die nachfolgenden Regeln durchzulesen. Wenn du diese Regeln akzeptierst und die Registration fortsetzen willst, klick einfach auf den "Mit der Registrierung fortfahren"-Button. Um diese Registration abzubrechen, klick bitte einfach auf den "Zurück" Button deines Browsers. Wir garantieren nicht für die Richtigkeit, Vollständigkeit und Brauchbarkeit der Nachrichten und sind auch nicht dafür verantwortlich. Die Beiträge drücken die Meinung des Autors des Beitrags aus, nicht zwangsläufig das, wofür die Forensoftware steht. Jeder Nutzer, der denkt, dass ein veröffentlichter Beitrag unzulässig bzw. störend ist, ist aufgefordert uns unverzüglich per E-Mail zu kontaktieren. Wir haben das Recht störende Beiträge zu löschen und bemühen uns, das in einem realistischem Zeitraum zu erledigen (sofern wir beschlossen haben, dass die Löschung notwendig ist). Du akzeptierst, durchgehend während der Nutzung dieses Services, dass du dieses Forum nicht dazu missbrauchen wirst, Inhalte zu veröffentlichen, welche bewusst falsch und/oder verleumderisch, ungenau, beleidigend, vulgär, hasserfüllt, belästigend, obszön, sexuell belästigend, bedrohlich, die Privatsphäre einer Person verletzend oder in irgend einer Art und Weise das Gesetz verletzen. Des Weiteren akzeptierst du, dass du keine urheberrechtlich geschützte Inhalte ohne Erlaubnis des Besitzers in diesem Forum veröffentlichst. Mit dem Klick auf den "Mit der Registrierung fortfahren"-Button, akzeptierst du zudem unsere Datenschutzerklärung und stimmst der Speicherung deiner IP-Adresse und personenbezogenen Daten zu, die dafür benötigt werden, um dich im Falle einer rechtswidrigen Tat zurückverfolgen zu können bzw. permanent oder temporär aus dem Forum ausschließen zu können. Es besteht keine Pflicht zur Abgabe der Einwilligung, dies erfolgt alles auf freiwilliger Basis.   Zusatzinformationen Der Forenbetreiber hat das Recht, Nutzer ohne Angabe von Gründen permanent aus dem Forum auszuschließen. Des Weiteren hat er das Recht, Beiträge, Dateianhänge, Umfrage, Blogeinträge, Galleriebilder oder Signaturen ohne Angabe von Gründen zu entfernen. Mit der Registrierung verzichtest du auf alle Rechte an den von dir erstellten Inhalten, bzw. treten diese an das Unity-Insider.de und Unity-Community.de ab. Dies bedeutet im Klartext, dass das Unity-Insider.de und Unity-Community.de frei über deine Texte verfügen kann, sofern diese nicht wiederum die Rechte anderer verletzen. Es besteht weiterhin kein Anspruch von registrierten Nutzern bzw. ehemaligen registrierten Nutzern darauf, dass erstellte Inhalte und/oder die Mitgliedschaft (User) wieder gelöscht werden (Erhaltung der Konsistenz dieses Forums).   Einwilligungserklärung Wenn du mit der Speicherung deiner personenbezogenen Daten sowie den vorstehenden Regeln und Bestimmungen einverstanden bist, kannst du mit einem Klick auf den Mit der Registrierung fortfahren-Button unten fortfahren. Ansonsten drücke bitte Zurück. Stand: 07.03.2011
Sign in to follow this  
Life Is Good

Identischer Code deutlich langsamer in Unity

Recommended Posts

Hey

Ich bin gerade ein bisschen ratlos.
Ich hab bei mir in Unity die Fast Marching methode implementiert - und musste feststellen, dass sie wahnsinnig langsam ist (Etwa 15 Sekunden). Eigentlich so langsam das etwas nicht stimmen kann.
Ich hab dann testweise einfach mal den Code gepackt und den in eine leere C# Konsolenanwendung geschmissen. (heißt natürlich auch .Net 4.5.2) und der selbe Code braucht da bloß etwa 3 Sekunden (VS im Debug Mode, Release nochmal etwas schneller)

Meine Frage ist also, ob jemand eine Idee haben könnte warum das in Unity so langsam läuft.
Hier der Code:

    // Der Einfachheit halber ist die Methode statisch und nimmt Group direkt als Parameter an.
    // Eigentlich würde die Methode über eine Anzahl an Gruppen in der 1. for schleife iterieren.
    private static void FastMarching(Group group)
    {
        // for each group
        for (int i = 0; i < 1; i++)
        {
            group.unknown = new List<GroupCell>();
            group.known = new List<GroupCell>();
            group.candidate = new List<GroupCell>();
			
            // GridCells enthält 10.000 Elemente.
            for (int j = 0; j < group.gridCells.Length; j++)
            {
                var cell = group.gridCells[j];
              
              	// Zu Beginn sind alle Zellen in der unknown liste.
                group.unknown.Add(cell);
                cell.isCandidate = false;
				
              	// 100 Elemente in gridCells sind hier mit isGoal = true markiert.
                if (cell.isGoal)
                {
                    cell.isKnown = true;
                    cell.isUnknown = false;

                    group.known.Add(cell);
                    group.unknown.Remove(cell);
                }
              	// 9.900 demnach nicht.
                else
                {
                    cell.isKnown = false;
                    cell.isUnknown = true;
                }
            }

	    // Ziel erreicht, wenn keine Zellen mehr in der unbekannten Liste liegen.
            while (group.unknown.Count > 0)
            {
                // Diese For schleife ist auch zugleich die lastigste (logischerweise)
                for (int j = 0; j < group.known.Count; j++)
                {
                    var cell = group.known[j];
                    // Holt sich einfach die 4 direkt angrenzenden Zellen einer gegebenen Zelle (cell)
		    // Das Grid ist also 2 dimensional.
                    var neighbours = Grid.GetNeighbourCells(width, length, group.gridCells, cell);
					
                    for (int k = 0; k < 4; k++)
                    {
                        var neighbour = neighbours[k];
                        if (neighbour != null && neighbour.isUnknown)
                        {
                            neighbour.isCandidate = true;
                            neighbour.isUnknown = false;

                            group.candidate.Add(neighbour);
                            group.unknown.Remove(neighbour);
                        }
                    }
                }

                for (int j = 0; j < group.candidate.Count; j++)
                {
                    // Nichts wichtiges hier.
                }

                GroupCell bestCell = null;
                for (int j = 0; j < group.candidate.Count; j++)
                {
                  // Nichts wichtiges hier, liefert einfach die beste Zelle zurück.
                }

                bestCell.isCandidate = false;
                bestCell.isKnown = true;

                group.known.Add(bestCell);
                group.candidate.Remove(bestCell);
            }
        }
    }

 

Edit:
Ich hab die Konsolenanwendung mal auf .Net 2.0 geändert und der Code läuft auch bloß minimal langsamer, also weit von den Werten in Unity entfernt.

Edit 2:
Unwichtige Codestellen entfernt.

Share this post


Link to post
Share on other sites

Ich vermute mal, dass Unity selber eben parallel auch was macht. Vorallem wenn du im Editor bist.

Haste mal ein ganz einfaches Build gemacht, wo nur dieser Code ausgeführt wird?
Ich könnte wetten, dass der Code dann viel schneller abläuft.

  • Like 1

Share this post


Link to post
Share on other sites

Ohhh tatsächlich !
Im Build sind es immerhin nur noch etwa 6-7 Sekunden. Zwar immer noch deutlich langsamer aber immerhin.

Ich glaub ich muss allgemein versuchen meine Implementation performanter zu kriegen...
Eigentlich sollte die methode alle 2-3 Frames durchlaufen können :D

Share this post


Link to post
Share on other sites

Ich denke dieser Algorithmus eignet sich hervorragend, um die Berechnung auf mehrere Prozessorkerne zu verteilen, Unity läuft ja nur auf einem Kern und auf diesem Kern laufen eben auch noch die Kernelfunktionen von Unity, soll heißen, wenn du den Code z.b. auf dem 2. Kern einer CPU (parallel) ausführst, könnte ich wetten du bist wieder bei 4 Sekunden. Noch mehr Performance kann man denke ich herausholen, wenn du den Algorithmus auf die PUs der GPU verteilst.

Share this post


Link to post
Share on other sites

Jo, ich hab auch schon daran gedacht das zu parallelisieren.
Im Paper das ich lese wird aber leider nicht klar ausgedrückt, ob der Algorithmus tatsächlich parallelisiert wurde. Deswegen bin ich mir gerade verdammt unsicher, ob ich nicht einfach blödsinn gemacht habe :D

Ich übersetz den Code gerade noch in C++, einfach um mal zuschauen was das nochmal für einen Unterschied ausmachen würde.

Share this post


Link to post
Share on other sites

Ich denke auch je höher die Auflösung bei der Berechnung sein soll, desto mehr Zeit wird der Algorithmus vermutlich auch benötigen (und je grösser die 3d Raw files sind). Aber laut dem Artikel den ich kurz überflogen habe lässt er sich sehr gut parallelisieren.
Hier ist sogar der Quellcode für eine GPU Implementierung bei:
https://www.eriksmistad.no/marching-cubes-implementation-using-opencl-and-opengl/

Share this post


Link to post
Share on other sites

Danke, ich weiß, dass es relativ einfach sein sollte das zu parallelisieren. Ich will's aktuell bloß nicht tun.
Marching Cubes haben übrigens aber auch nicht viel mit Fast Marching zu tun ;)

Share this post


Link to post
Share on other sites
vor 3 Stunden schrieb Zer0Cool:

Unity läuft ja nur auf einem Kern...

Stimmt so eigentlich gar nicht mehr, beim Rendering werden zum Teil mehrere Kerne benutzt.

Share this post


Link to post
Share on other sites
vor 59 Minuten schrieb Torigas:

Arbeitest du gerade an Continuum Crowds?

Ja, besser gesagt ich versuch's zumindest :)

Ich bin vor ein paar Tagen auf die Info gestoßen, dass die original Implementation mit OpenCL war, also doch auf der GPU lief.

Danke für den Link ! Ich denke ich werd sowohl GPU durch Compute Shader als auch Multithreading auf der CPU unterstützen.

Share this post


Link to post
Share on other sites
Zitat

Spannend, dass ich nicht der einzige hier bin. 

Ja ! Ich hab wirklich nicht erwartet so schnell jemand anderen zu finden. Es gibt ja auch kaum Material dazu.
Die Seite kenn ich, ist glaub ich auch das einzige praktische was man zu Continuum Crowds findet. Ist eigentlich ein bisschen komisch, da CC ja anscheinend in größeren Spielen schon relativ oft Anwendung gefunden hat (bzw. eine abgeänderte Version)

Wie zufrieden bist du denn mit deinen Ergebnissen ?
Discomfort und Höhen werden bei mir auch passend behandelt, aber irgendwie passt das mit der gegenseitigen Erkennung bei mir noch nicht, die Personen laufen einfach ineinander, sogar in der selben Gruppe.
Ich glaube ich hab bei der Berechnung der Dichte Werte noch irgendwo einen Fehler drin...

Share this post


Link to post
Share on other sites

Joa also die vermeiden sich schon. Da musst du mal in der Gewichtung gucken. Ganz zufrieden bin ich aber auch nicht.

https://howtorts.github.io/2014/01/09/continuum-crowds.html

http://www.derivativesinvesting.net/article/482547368/implementing-continuum-crowds-part-1-writing-an-eikonal-equation-solver/

Gibt so ein paar Resourcen ja.

Ich hab bei mir viel mit OnDrawGizmos gearbeitet und jede Grid Cell je nach Dichte eingefärbt und so. Hilft ziemlich beim Debuggen.

Share this post


Link to post
Share on other sites

Ohh ja ich hab zum "schnellen" debuggen einfach zellen mit unterschiedlichen Farben instantiert. Mal schauen.

Danke für die Links, den 2. kannte ich noch nicht.

Share this post


Link to post
Share on other sites

Leider noch nicht dazu gekommen meine CC Implementation zu multithreaden.

Bin allerdings sowieso noch mit Problemen am kämpfen.


@Torigas
Bist du auch auf solch ein komisches "Gestotter" gestoßen ? Das mit dem Teleportieren ist auch irgendwie merkwürdig, löst sich aber vielleicht auch einfach auf wenn ich den Vektor auf eine bestimmte Größe beschränke...
Ansonsten tendieren die halt aus irgendeinem Grund dazu seeehr nah aneinander zu laufen.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×