Häufige, abbrechbare Rechenanfragen



  • Hi,

    ich habe eine Anwendung, in welcher es eine Vielzahl von Parametern gibt, die der Benutzer ändern kann. Basierend auf diesen Parametern findet eine intensive Berechnung statt, die auch Sekunden bis Minuten dauern kann.

    Dass die Berechnung somit in einem anderen Thread laufen können soll, erscheint recht klar. Die Berechnung ist auch parallelisierbar, daher möchte ich natürlich mehrere Kerne ausnutzen, vermutlich werde ich also 2-8 Threads dafür nutzen.

    Nun ist es aber so, dass ich aus Usability-Gründen (die ich hier nicht diskutieren möchte) bei jeder Parameteränderung die Rechnung direkt anstoßen möchte. Der Benutzer klickt also nicht auf einen Button "berechnen", sondern die Rechnung findet von selbst statt.

    Die Implikation ist jedoch: Wenn sich Parameter ändern, muss die aktuelle Berechnung, falls laufend, gestoppt werden.

    Wie würdet ihr solch ein Verhalten möglichst performant implementieren?

    Viele Grüße
    Eisflamme



  • Das kommt etwas auf die Berechnung an, denke ich. Du kannst z.B. die Parameter zu Atomics machen und den berechnenden Threads eine nicht-atomare lokale Kopie von den Parametern geben. Sofern die Berechnung irgendwo Schleifen benutzt, kannst du bei der Gelegenheit die lokalen Kopien mit den globalen atomaren Parametern vergleichen. Ist das Ergebnis false, aktualisierst du die lokalen Parameter und beginnst die Berechnung von vorne.

    Z.B.

    std::atomic<int> parameter;
    
    int local_param = parameter.load(std::memory_order_relaxed);
    for(int foo = 0; foo < 100; ++foo) {
       auto new_param = parameter.load(std::memory_order_relaxed);
       if(new_param != local_param) {
          local_param = new;
          foo = 0;
       }
       else {
           // Berechnung mit foo und local_param ...
       }
    }
    

    Edit: Der Preis: Es wird oft einen load geben. Aber du kannst die Prüfung/Load ja z.B. auf alle 100 Durchläufe reduzieren, je nach dem, was das Profiling sagt bzw. wie responsive das ganze sein muss.



  • Im Prinzip gibt es nur eine Loesung: Deine Berechnung in kleine Teilschritte zerlegen und vor jedem Schritt schauen, ob es weitergehen soll oder von vorn begonnen werden muss. Wenn man es geschickt anstellt, kann diese Zerlegen gleichzeitig auch zum paralellisieren benutzt werden, womit du dann mit der Anzahl der Threads sehr flexibel wirst.


Log in to reply