Ergebnis 1 bis 13 von 13

Wahrscheindlichkeitsberechnung

  1. #1 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    @Jabu

    Ich habe ne Performancefrage:
    Folgende Objektstruktur:

    Code:
    Daten{
      R_List:[
        {
          S_List:[{Wahrscheindlichkeit:4(int/double),Schaden:2573000(int)}]
        }
      ]
    }
    Es muss über alle R die S addiert werden
    (R1S1 + R2S1 + R3S1)
    (R1S2 + R2S1 + R3S1)
    (R1S3 + R2S1 + R3S1)
    (R1S1 + R2S2 + R3S1)
    ...
    (R1S3 + R2S5 + R3S3)


    Am ende müssen die Resultate alle noch verrechnet werden, das ca. 1500 Schadensbereiche mit deren gesammelter Wahrscheindlichkeit rauskommen sollten.

    Wir haben schon was, welches Zufällig ausgewählte Einträge verrechnen kann.
    Wir kommen bei 1 CPU kern auf ca. 1 Million Verrechnungen Pro Sekunde, bei 10 Risiken
    Aber das muss doch irgendwie noch 10-100 mal schneller gehen.
    Ich habe schon Optimiert, was Ich konnte (z.B. der Wahrscheindlichkeiswert als BigInt, anstelle von decimal zur Berechnung (nur noch Multiplikation mit Ganzzahlen))
    Das ganze als Struct, da immer neue Werte


    Ich kann sonst schauen, ob Ich den richtigen Code posten darf.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  2. #2 Zitieren
    Legende Avatar von jabu
    Registriert seit
    Jul 2011
    Beiträge
    7.383
    @Multithread:

    Zu deiner Sache wollte ich gestern schon was sagen, aber meine Versuche, konkret nachzufragen, scheiterten, weil deine Darstellungen mir zu lückenhaft, von Flüchtigkeitsfehlern durchsetzt und mehrdeutig erschienen (womit ich nicht behaupte, dass sie es sind), um meine Fragen einigermaßen treffsicher zu formulieren. Teilweise kann es auch an meinem Unverständnis deiner Datenstruktur liegen, denn die kann ich nicht eindeutig parsen, weswegen es gut wäre, wenn du die nochmal kontrollieren und, falls nötig, korrigieren würdest und mir das Regelwerk, dem die folgen soll, mitteilen könntest. Wo es mehrere Einträge geben kann, z.B. Listen innerhalb von Listen, wäre es gut, wenn du das kenntlich machen könntest und natürlich auch, wofür die Anzahl überhaupt steht. Falls es nur einen Eintrag gibt, sehe ich den Sinn in der Verschachtelung nicht. Ich könnte mir anhand deines Textes einen zuammenreimen, aber das muss dann nicht stimmen. Die innen befindliche Struktur hätte ich gerne mal näher erklärt bekommen. Je nach Sprache kann ein Komma oder ein Doppelpunkt etwas anderes bedeuten. Und innerhalb einer Sprache kann es wegen Abstraktion oder Wiederverwendung von Symbolen verschiedene Interpretationen geben, wobei die Deklaration oder Definition, die das auflösen könnte, woanders steht. Ich könnte z.B. ein Array aus Tupeln hineindeuten oder, alternativ, eine große Struktur. Bezüglich Performance können sich solche Unterschiede, bezogen auf eine konkrete Lösung, dramatisch auswirken. Tupel stehen einem schnellstmöglichen Durchrattern eher im Weg, es kann aber im konkreten Einzelfall passieren, dass es keine effizientere Lösung als mit den Tupeln gibt (je nachdem, was wie verrechnet werden muss und wie groß der Aufwand zum Umsortieren wäre). Meistens sind lineare Arrays mit einem einzigen Typ, sodass ein einziger Pointer weitergeschubst werden kann (wobei manchmal sogar ein Teil dieses Geschubses wegoptimiert werden kann, ober damit der Vorteil nicht durch den dafür nötigen Overhead weggefressen wird, muss schon einiges berücksichtigt werden, und oftmals ist der Overhead einfach zu groß), im Vorteil. Aber man kann das, wie gesagt, nicht verallgemeinern.

    Also einige dumme Fragen in Kurzform und (notgedrungen) ziemlich allgemein gehalten:
    Warum gibt es im matrixartigen Gebilde diese Wiederholungen? Flüchtigkeitsfehler?
    Warum hat es ausgerechnet drei Spalten, ist das exemplarisch gemeint? Oder sollen es vier sein?
    Du verwendest die Buchstaben R und S im matrixartigen Gebilde sowie im Text dazu, aber wie beziehen sie sich auf die Datenstruktur (mir gelingt mehr als eine Interpretation, und wortwörtlich kommen sie nicht vor, und wenn ich sie für Listenelemente anwende, dann kommt mir trotzdem etwas komisch vor)?
    Welche Verrechnungen und Schadensbereiche meinst du? Soll das nachher verrechnet werden, oder steckt die Verrechnung (ich schätze mal, eine Multiplikation?) schon drin? Oder kann man sich die Reihenfolge aussuchen, sodass es nur um Tempo geht? Oder werden die Zwischenergebnisse gebraucht? Wie zeigen sich die Schadensbereiche innerhalb deiner Datenstruktur? Oder kommen die als Ordnung noch hinzu?

    Bevor ich mich sinnvoll mit deiner Sache beschäftigen kann (soweit meine knappe Zeit es erlaubt), müsste ich das also ausführlicher und genauer dargestellt haben. Versprechen kann ich natürlich nichts.

    Nur grundlegend und wenig konkret:
    Dieser Fall sieht mir so aus, als ließe er sich gut parallelisieren, aber wenn noch Abhängigkeiten, die ich noch nicht sehe, hineinkommen, dann kann sich das auch komplett zerschlagen. Auch über eine native Lösung könnte man, falls die in der Ausführungsumgebung problemlos ans Laufen zu bringen ist, mal nachdenken. Eventuell geht da was mit Partitionierung und Unrolling von Loops, eventuell auch unter Nutzung von SIMD-Befehlen, wobei die auch nach hinten losgehen können und die ganze Struktur dazu passen müsste, was einen ganz schönen Aufwand bedeuten kann.
    Also würde ich es erst mal ohne SIMDs versuchen und dem Compiler größtmögliche Freiheiten lassen, damit sein Optimierer nicht behindert wird. Mit etwas Glück ist das schneller als alles, was man händisch optimiert hätte. Das bedeutet natürlich nicht, dass man nichts tun müsste. Der Code sieht hinterher meistens bloß so aus, als hätte man nichts getan, aber wehe, man ändert was, dann wird er lahm.
    So verfahre ich meistens beim Optimieren. Moderne Compiler sind nämlich schon ziemlich gut im Optimieren. Aber man muss auch verstehen, welche Annahmen sie treffen und welche sie nicht treffen dürfen, z.B. wenn der Optimierer den Code anders anordnen soll, zum Beipiel zur parallellen Abarbeitung in SIMD-Registern, wozu er u.U. Sequenzpunkte missachten muss, obwohl die Sprache vorschreibt, alles von Sequenzpunkt zu Sequenzpunkt nacheinander abzuarbeiten. Zum Beispiel steht im Sprachstandard von C++, dass der Compiler (fast) alles machen kann, was er will, wenn es nichts am beobachtbaren Verhalten ändert. Und dort steht auch, was unter diesem beobachtbaren Verhalten zu verstehen ist. Man kann dieses Optimieren behindern, z.B. indem man nicht notwendige Abhängigkeiten einbringt, was es zu vermeiden gilt.
    Das Überschreiben eines Passwords nach dessen Gebrauch im RAM, z.B. mit Nullen, kann man, solange das Programm korrekt läuft und weiter nichts davon abhängt, von außen nicht nachvollziehen, also wird es, wenn du keine Vorkehrungen dagegen triffst, von den üblichen Compilern mit recht hoher Wahrscheinlichkeit gnadenlos wegoptimiert, was natürlich ein Sicherheitsproblem ist. Einerseits sind Compiler ziemlich clever, andererseits tun Programmierer viel Cleveres, um den Compiler daran zu hindern, seine Cleverness auszuspielen, eben indem der Optimierer auf eine Barriere trifft. Trifft er auf keine, so kann er ganz schön viel abschmelzen. Letztendlich kann er Instruktionen so geschickt kombinieren, wie man sie selber gar nicht in angemessener Zeit erlernen und kombinieren könnte.
    Somit kommt es darauf an, das günstigste Datenlayout zu finden und dem Compiler eine dezente Handreiche zu geben, damit er den Rest selber erledigen möge. Bei Wahrung einer solchen Flexibilität kann es gelingen, dass du nur ein anderes Compiler-Flag setzt oder einen anderen Compiler verwendest, vielleicht in einer neueren Generation, und schon ein halbes Prozent mehr Leistung erhältst, wogegen kleinteilig optimierter Code, ich nenne das "totoptimierter Code", bei dem du eben dem Compiler alles vorschreibst, möglicherweise gar nichts hinzugewinnt oder sogar langsamer werden kann, je nach Compiler und Hardware.
    Aber manchmal muss man die bittere Pille schlucken und "totoptimieren", was z.B. leicht passieren kann, wenn du SIMD- oder Assemblerbefehle verwenden willst. Wo sich das richtig lohnt, da darf es ruhig stehenbleiben. Allerdings lohnt sich ein einziger Befehl fast immer nicht, manchmal nicht mal im Zusammenwirken. Solche Optimierungsversuche gehen sogar meistens böse nach hinten los, indem es sich dabei um Barrieren für den Optimierer handelt. Der Compiler nimmt solche Stellen als Aussage, du hättest es genauso haben wollen, oder er kann deine Teillösung nicht in eine Lösung gemäß eigener Strategie integrieren, oder es wäre schlicht zu aufwendig, zu prüfen, ob noch dasselbe beobachtbare Verhalten herauskommt. Oder es ist schlicht nicht vorgesehen. Dann wird der Kram drumherum optimiert, und die Lösung ist nicht als Ganzes optimiert. Und du musst grundsätzlich damit rechnen, dass du bei derart kleinteiligem Optimieren zusätzlichen Aufwand erzeugst, indem du etwas in Register schiebst oder schieben lässt, also explizit oder implizit, was gar nicht nötig gewesen wäre, wenn du dem Compiler die Wahl gelassen hättest. Der kann sich oftmals ausrechnen, dass sein Umweg über ein bestimmtes Register, z.b. ein SIMD-Register, den Aufwand nicht wert ist, wogegen man es als Mensch vergleichsweise schwer hat, das richtig einzuschätzen.
    Optimierung ist schon ein interessantes Feld, aber sie kann, nachdem man sich Ziele gesetzt hat, ganz schön zermürbend sein. Und sie kann irritieren, z.B. wenn eine Optimierung, die sonst immer etwas bringt, an einer bestimmten Stelle sogar gegenteilige Effekte erzielt, z.B. beim Caching eines Pointers für eine Loop. Da hat ein bestimmtes Muster sonst immer funktioniert. Doch in einer nur etwas anderen Schleife bringt das, egal wie ich es anstelle, einen enormen Overhead (rund 2 % auf den Gesamtaufwand, lokal sicher noch etwas mehr) mit sich. Es drängt sich der Verdacht auf, dass keine Register mehr frei sind oder dass der Compiler sowieso ein ähnliches Caching eingebaut hat, nur dezent anders, sodass nicht beides zusammenfallen kann. Der Compiler weiß es hier vermutlich besser, oder er scheitert daran, eine Festlegung meinerseits optimal zu integrieren. Oder der CPU gelingt hier selber ein Caching, wodurch alles andere Overhead ist. Wenn du ungefähr weißt, was zu tun ist, hilft dir das zwar, aber es ist noch viel Probieren dabei, was ganz schön nerven kann.
    Am meisten lohnt sich daher, was du schon angefangen hast, nämlich erst mal die Datenstruktur sowie die Datentypen einer kritischen Überprüfung zu unterziehen. Man sollte nicht vernachlässigen, was es kostet, von Fließkommazahlen zu Ganzzahlen umzuwandeln und das Geschubse dazu, um diese schließlich im Zielregister verrechnen zu können. Wenn dir die Genauigkeit und der Wertebereich von double genügen, dann würde ich mal alles durchweg mit double versuchen, damit der Compiler den Kram durchweg in FPU- oder SIMD-Registern vorhalten kann. Irgendwelche unendlichen (Big-)Integer-Typen sind notgedrungen langsam, weil sie nicht ohne ständige Überprüfungen und Abzweigungen auskommen und sicher nicht endlos auf dem Stack wachsen können, sondern prinzipbedingt, zumindest ab einer gewissen Größe und Varianz, verstreut auf dem Heap liegen müssen, was ganz schön langsam im Zugriff ist. Bestenfalls Pointer auf diese können auf dem Stack liegen, was eine weitere und auch schon etwas teure Indirektionsebene ist.
    Falls die natürliche Wortbreite der CPU im genutzten Modus ganz sicher immer 64 Bit beträgt, bietet sich ein Typ, der dem natürlichen 64-Bit-Integer-Typ entspricht, natürlich an, wie immer unter dem Vorbehalt, dass der Wertebereich genügt und die Möglichkeit eines Überschreitens wenigstens vorab durch eine Plausibilitätsprüfung abgeprüft wird, also dass es zu keinem unbemerkten Overflow kommt. Wenn man den durchweg verwendet, sollte das ganz schön schnell sein. Langsamer, aber eine mögliche Lösung, falls der Wertebereich sonst nicht genügt, sind zusammengesetzte Typen von doppelter Breite, aber sie haben, wie auch andere Integer-Typen, gegenüber double den Vorteil der Exaktheit. Man muss also die Anforderungen kennen.
    Typen, die auf dem Heap (Freispeicher) liegen und dabei nicht gleichzeitig in einem echten Array angeordnet sind (notfalls, aber suboptimal (manchmal auch nicht, z.B. bei nicht allzu großen Typen, welche direkt verrechnet werden müssen), auch Structs im echten Array), kannst du performancemäßig vergessen. Typen sollten nicht zu komplex sein, damit ihre Werte möglichst direkt auf Register mappen. Wenn die Typen jedes Mal erst auf dem Stack gepusht und zerlegt und nach der Berechnung wieder zusammengesetzt werden müssen, dann wird das mit der Performance niemals was. Laden und Wegspeichern sollten möglichst direkt erfolgen, und Zwischenergebnisse sollten in Registern verbleiben können, der Umweg über den Stack sollte nur gegangen werden, um eine große Ladung an Werten auf einmal vom Heap vorzuladen (nur, wenn es was bringt, und bitte keinen Stack-Overflow riskieren, so viel auf einmal braucht man normalerweise nicht, und es brächte ab einem Punkt nichts mehr) oder wenn es unvermeidbar ist, z.B. mangels genügend Registern (was der Compiler dann schon weiß). Einen Umweg über den Heap bei vielen einzelnen Elementen gilt es unbedingt zu vermeiden.
    Einiges von dem, was ich hier geschrieben habe, lässt sich bei verwaltetem Code schwer oder gar nicht beeinflussen, das ist mir schon klar. Manches lässt sich aber beeinflussen, teils indirekt. Performancefehler sollte man in ähnlicher Weise wie unter nativem Code vermeiden können. Meistens geht es bei den ersten zig Prozent (falls möglich) gar nicht um besondere Kniffe, sondern eben darum, dem Compiler keine Steine in den Weg zu legen und den Registern die Daten passig zukommen zu lassen. Falls das alles schon beherzigt wurde, kann das Potenzial, um mit vertretbarem Aufwand oder sogar absolut weiterzukommen, gering ausfallen.
    jabu ist offline Geändert von Multithread (03.08.2020 um 17:55 Uhr)

  3. #3 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    Zitat Zitat von jabu Beitrag anzeigen
    @Multithread:
    Zu deiner Sache wollte ich gestern schon was sagen, aber meine Versuche, konkret nachzufragen, scheiterten, weil deine Darstellungen mir zu lückenhaft, von Flüchtigkeitsfehlern durchsetzt und mehrdeutig erschienen (womit ich nicht behaupte, dass sie es sind), um meine Fragen einigermaßen treffsicher zu formulieren.
    hmm, Datenstruktur in Eindeutig?

    JSON "export" von Theoretischen Daten:
    Code:
    {
       "R":[
          {
             "S":[
                {
                   "Wahrscheindlichkeit":17(int/double),
                   "Schaden":150000(int)
                },
                {
                   "Wahrscheindlichkeit":6(int/double),
                   "Schaden":158333(int)
                },
                {
                   "Wahrscheindlichkeit":9(int/double),
                   "Schaden":5000(int)
                }
             ]
          },
          {
             "S":[
                {
                   "Wahrscheindlichkeit":4(int/double),
                   "Schaden":150000(int)
                },
                {
                   "Wahrscheindlichkeit":2(int/double),
                   "Schaden":732903(int)
                }
             ]
          },
          {
             "S":[
                {
                   "Wahrscheindlichkeit":7(int/double),
                   "Schaden":2573000(int)
                },
                {
                   "Wahrscheindlichkeit":16(int/double),
                   "Schaden":1500(int)
                }
             ]
          }
       ]
    }
    Zitat Zitat von jabu Beitrag anzeigen
    Also einige dumme Fragen in Kurzform und (notgedrungen) ziemlich allgemein gehalten:
    1. Warum gibt es im matrixartigen Gebilde diese Wiederholungen? Flüchtigkeitsfehler?
    2. Warum hat es ausgerechnet drei Spalten, ist das exemplarisch gemeint? Oder sollen es vier sein?
    3. Du verwendest die Buchstaben R und S im matrixartigen Gebilde sowie im Text dazu, aber wie beziehen sie sich auf die Datenstruktur (mir gelingt mehr als eine Interpretation, und wortwörtlich kommen sie nicht vor, und wenn ich sie für Listenelemente anwende, dann kommt mir trotzdem etwas komisch vor)?
    4. Welche Verrechnungen und Schadensbereiche meinst du? Soll das nachher verrechnet werden, oder steckt die Verrechnung (ich schätze mal, eine Multiplikation?) schon drin?
    5. Oder kann man sich die Reihenfolge aussuchen, sodass es nur um Tempo geht?
    6. Oder werden die Zwischenergebnisse gebraucht? Wie zeigen sich die Schadensbereiche innerhalb deiner Datenstruktur? Oder kommen die als Ordnung noch hinzu?
    Ich habe es mal durchnummeriert:
    1. Nein, die "Wiederhohlung" muss so sein
    2. Die Anzahl der Elemente der Listen R und Der Liste S (in jedem einzelnen R-object eine eigene vorhanden) sind variable. Meist 3-5 S und zwischen 15 und 100 R
    3. Siehe JSON oberhalb
    4. Verrechnung der S miteinander erfolgt soS1_Schaden + S2_Schaden & S1_Wahrscheindlichkeit * S2_Wahrscheindlichkeit)
    5. Die Reihenfolge der R ist irrelevant. Es geht nur um das Tempo
    6. Nein, die Zwischenergebnisse sind nicht relevant, nur das Endergebniss zählt

    Zitat Zitat von jabu Beitrag anzeigen
    Bevor ich mich sinnvoll mit deiner Sache beschäftigen kann (soweit meine knappe Zeit es erlaubt), müsste ich das also ausführlicher und genauer dargestellt haben. Versprechen kann ich natürlich nichts.
    Kein Thema.


    Zitat Zitat von jabu Beitrag anzeigen
    Nur grundlegend und wenig konkret:
    Dieser Fall sieht mir so aus, als ließe er sich gut parallelisieren, aber wenn noch Abhängigkeiten, die ich noch nicht sehe, hineinkommen, dann kann sich das auch komplett zerschlagen. Auch über eine native Lösung könnte man, falls die in der Ausführungsumgebung problemlos ans Laufen zu bringen ist, mal nachdenken. Eventuell geht da was mit Partitionierung und Unrolling von Loops, eventuell auch unter Nutzung von SIMD-Befehlen, wobei die auch nach hinten losgehen können und die ganze Struktur dazu passen müsste, was einen ganz schönen Aufwand bedeuten kann.
    Ja, lässt sich nahezu "Perfekt" Skalieren. Auf einem Web-Server, welcher nur 2 oder 4 CPU Kerne hat, bringt das leider sehr wenig.

    Zitat Zitat von jabu Beitrag anzeigen
    Am meisten lohnt sich daher, was du schon angefangen hast, nämlich erst mal die Datenstruktur sowie die Datentypen einer kritischen Überprüfung zu unterziehen. Man sollte nicht vernachlässigen, was es kostet, von Fließkommazahlen zu Ganzzahlen umzuwandeln und das Geschubse dazu, um diese schließlich im Zielregister verrechnen zu können. Wenn dir die Genauigkeit und der Wertebereich von double genügen, dann würde ich mal alles durchweg mit double versuchen, damit der Compiler den Kram durchweg in FPU- oder SIMD-Registern vorhalten kann. Irgendwelche unendlichen (Big-)Integer-Typen sind notgedrungen langsam.
    Ja, das mit Bigint vs double/decimal habe Ich mir auch überlegt, am ende hat Bigint gewonnen, wegen den Genauigkeitsverlusten.
    Eventuell kann man da aber auch was drehen mit einer anderen Art der Rechnung.

    Zitat Zitat von jabu Beitrag anzeigen
    Falls die natürliche Wortbreite der CPU im genutzten Modus ganz sicher immer 64 Bit beträgt, bietet sich ein Typ, der dem natürlichen 64-Bit-Integer-Typ entspricht, natürlich an, wie immer unter dem Vorbehalt,
    ....
    Einiges von dem, was ich hier geschrieben habe, lässt sich bei verwaltetem Code schwer oder gar nicht beeinflussen, das ist mir schon klar. Manches lässt sich aber beeinflussen, teils indirekt. Performancefehler sollte man in ähnlicher Weise wie unter nativem Code vermeiden können. Meistens geht es bei den ersten zig Prozent (falls möglich) gar nicht um besondere Kniffe, sondern eben darum, dem Compiler keine Steine in den Weg zu legen und den Registern die Daten passig zukommen zu lassen. Falls das alles schon beherzigt wurde, kann das Potenzial, um mit vertretbarem Aufwand oder sogar absolut weiterzukommen, gering ausfallen.
    Also wäre dein Vorschlag Bigint soweit möglich zu "Entfernen" und Die Multiplikation via long durchzuführen, bis zur grenze. Die Wahrscheindlichkeit kann maximal 100 sein, ergo weiss Ich wie viele Ich pro long maximal Multiplizieren kann ohne Overflow, und Ich kann am ende die Long mit BigInt Multiplizieren.
    Sollte es stimmen das BIgInt ziermlich langsam ist, würde das schon einiges bringen.

    Und dazu noch einen Schnelleren RND Generator und dann könnte die Performance massiv ansteigen....
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  4. #4 Zitieren
    Moderator Avatar von MadFaTal
    Registriert seit
    May 2010
    Beiträge
    3.632
    Zitat Zitat von Multithread Beitrag anzeigen
    hmm, Datenstruktur in Eindeutig?
    Ich kann jabu zustimmen, das deine Ausführungen wenig hilfreich sind, Hilfe zu leisten.
    Es wäre nützlich zu wissen, wie dieser R x S Datenberg entsteht bzw. wie Teile davon aktualisiert werden.

    Wenn du unumgänglich einen zufälligen R x S Datenberg bekommst und neu kalkulieren musst, dann hast du verloren.
    Dann musst du in die Zitrone beißen und bei jedem Update diesen kompletten Datenberg kalkulieren.
    Da hilft es nur geringfügig, wie jabu bereits beschrieben hat, "lokale"Berechnungen zu optimieren.

    Aber üblicherweise wird oft nur ein Teil eines Datensatzes aktualisiert.
    Ein üblicher Ansatz um Rechenleistung zu sparen, ist es Hilfsvariablen einzuführen.
    Diese benötigen mehr Speicher, aber der Rechenaufwand in Summe lässt sich so oft zigfach reduzieren.

    z.B.: Jedem deiner S-Datensätze fügst du zwei zusätzliche Datenspeicher hinzu:
    sum_damage
    sum_propability

    S
    {
    sum_damage: int
    sum_propability : int
    damage_array[x] : int
    propability_array[x] : int
    }

    Wenn jetzt ein S damage_array[x] element aktualisiert wird, dann wird sum_damage = sum_damage - damage_array[x] + new_damage[x] u.s.w
    Die "R" Aktualisierung muss entsprechend mathematisch nachgezogen werden.
    Ich hoffe, das dies grob verständlich war.
    Aufgrund fehlender Infos, wozu tatsächlich eine Lösung gesucht wird, kann ich speziell nicht weiterhelfen.

    Also auf den Punkt gebracht finden Berechnungen nur statt, wenn Werte der Berechnung verändert werden.
    Solange nur das Ergebnis abgefragt wird, findet gar keine Berechnung statt, da nur auf die Werte der Hilfsvariablen lesend zugegriffen wird.

    PS:
    Die Hilfsvariablen gelten auch für die übergeordneten R Datenspeicher, aber je komplexer die Rechenoperatoren werden, um so schwieriger oder gar unmöglich kann es sein einen mathematischen (Umkehr-)Ansatz zu finden.

    PPS:
    Hoffe es hilft dir weiter.
    MadFaTal ist offline

  5. #5 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    Zitat Zitat von MadFaTal Beitrag anzeigen
    z.B.: Jedem deiner S-Datensätze fügst du zwei zusätzliche Datenspeicher hinzu:
    sum_damage
    sum_propability

    S
    {
    sum_damage: int
    sum_propability : int
    damage_array[x] : int
    propability_array[x] : int
    }

    Wenn jetzt ein S damage_array[x] element aktualisiert wird, dann wird sum_damage = sum_damage - damage_array[x] + new_damage[x] u.s.w
    Die "R" Aktualisierung muss entsprechend mathematisch nachgezogen werden.
    Das hilft in meinem Fall nicht weiter.
    Wir reden da von irgendwas von 20^3 - 50^5 möglichen Kombinationen.

    Die kleinste Änderung ändert 20-33% aller Kombinationen, jede andere sogar 100% garantiert.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  6. #6 Zitieren
    Moderator Avatar von MadFaTal
    Registriert seit
    May 2010
    Beiträge
    3.632
    Zitat Zitat von Multithread Beitrag anzeigen
    Wir reden da von irgendwas von 20^3 - 50^5 möglichen Kombinationen.

    Die kleinste Änderung ändert 20-33% aller Kombinationen, jede andere sogar 100% garantiert.
    Kannst du genauer beschreiben wie sich die Daten verändern.
    Die Datenstruktur ist eine Sache, wie oft sich diese Daten dynamisch verändern habe ich noch nicht verstanden.

    Was hat die Anzahl der Kombinationen mit dem Update der Datensätze zu tun?
    Du hast geschrieben das es ein dynamisches Array R mit bis zu 100 Elementen gibt.
    Jedes Element von R enthält ebenfalls wieder ein dynamisches Array S mit bis zu 5 Elementen.
    Das sind maximal 500 Wertepaare. Ändern sich meistens tatsächlich die Werte von allen R und S?

    Bei so vielen Updates wird sich kaum ein anderer Algorithmus finden, als über alle Daten zu laufen und zu Berechnen.
    Als Ergebnis ergibt sich eine Summe (Schaden) und ein Produkt (Wahrscheinlichkeit) aus den bis zu 500 Wertepaaren?
    Wenn noch weitere Ergebnisse notwendig sind, dann habe ich noch nicht verstanden wie diese zu ermitteln sind.

    Vermutlich hilft es wenn du den Code bereitstellst.
    MadFaTal ist offline

  7. #7 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    Ändern kann sich sowohl die Anzahl der R, die Anzahl der S eines R und die Werte eines S können ändern (Wahrscheindlichkeit und/oder Wert).

    Es sind nicht 100*5 Möglichkeiten, es sind 100⁵ Möglichkeiten.

    Ein Resultat besteht aus einem S pro R.
    Und am Ende sollten Theoretisch alle diese Möglichkeiten verrechnet werden. Theoretisch, da es unmöglich ist dies zu tun.

    Ich glaube auch nicht das es eine Möglichkeit gibt die Daten zu verrechnet als jedesmal alle Daten zu verrechnen.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  8. #8 Zitieren
    Legende Avatar von jabu
    Registriert seit
    Jul 2011
    Beiträge
    7.383
    Dass ich erst so spät antworten konnte, liegt daran, dass ich mit diesem Kram, mangels klarer und vollständiger Definitionen (nun ist es besser, aber es fehlt noch etwas) schon viel Zeit verbraten und trotzdem etwas mit C++ gebastelt habe (meine Schuld, es war sozusagen eine Zwangshandlung), unter der Gefahr, dass ich wegen Definitionslücken (kann ich nichts dafür) in falsche Richtungen galoppiert sein könnte (meine Schuld, das Pferd zu reiten ).

    Zitat Zitat von Multithread Beitrag anzeigen
    hmm, Datenstruktur in Eindeutig?

    JSON "export" von Theoretischen Daten:
    [...]
    Das ist schon viel besser, und danke dafür, aber es war auch nötig, denn JSON (worauf ich nicht gekommen war) ist so offen ausgelegt, dass man nur werten kann, was da ist und nicht, was noch kommen könnte. Ich habe die unterschiedlich langen Listen erst mal für bare Münze genommen (und nicht als Abkürzung deinerseits) und auch eine Implementierung, die damit umgehen kann, vorgenommen. Also frage ich doch einfach mal:
    Ist das eine Anforderung?
    Wie ist sie begründet?
    Wie soll mit den Längenunterschieden umgegangen werden?

    Meine Arbeitshypothese (wegen Längenunterschieden) fügt keine neutralen Elemente hinzu, denn dazu müsste man erst mal wissen, wie sie sich neutral auswirken (0 für Summen und 1 für Produkte? Oder 100 für 100 % oder nach einer obskuren Gewichtung, die wir hier nicht sehen können? Oder nach einer praktisch unlösbaren Gleichung?) und ob sie neutral sein sollen. Es gibt also nur solche Kombinationen, die über alle R gehen, wobei aus jedem R ein S verwendet wird, ohne dass es zu Doppelungen käme. Gut, Doppelungen könnte man nachher umständlich rausschmeißen, aber das kann ganz schön dauern. Ob man sie rausschmeißen darf, liegt natürlich daran, wie die Ergebnismenge auszusehen hat, weswegen das gar nicht so selbstverständlich ist.

    Vielleicht kannst du dir jetzt denken, wie man mit dem Berücksichtigen des ganzen Variantenreichtums seine Freizeit, teils sinnlos, verplempern kann? Da ist dann schon mal schnell die Restenergie, die man besser auf das eigentliche Problem verwendet hätte, aufgebraucht. Dieses ist kein Vorwurf, sondern eine Erklärung, warum ich es nicht geschafft habe, schneller einigermaßen brauchbare Antworten zu geben.

    Man möchte das Problem zuerst auf den Punkt gebracht haben, mitsamt Randbedingungen, da fehlt noch einiges. Code ist erst mal egal. Meiner ist nicht schön (aber praktisch, da Typen leicht an zentraler Stelle ausgetauscht werden können) und auch nur dazu da, um die Sache etwas griffiger zu bekommen und um dir mal ein paar gemessene Zeiten anbieten zu können. Aber dazu sollte der auch nicht einfach hingeschludert sein, damit die Ergebnisse aussagekräftig sind, was mindestens bedeutet, dass sie korrekt sein müssen (Es fehlen doch wohl keine Berechnungen? Es wurde doch wohl nichts Nötiges wegoptimiert (wäre erlaubt, wo Ergebnisse keine beobachtbaren Effekte bringen)? Was messe ich da eigentlich?) und dass der Kram bereits einigermaßen effizient ist (um das Potenzial zu sehen). Das alles zusammen, auch wenn das eigentliche Problem nicht so schwierig ist, kann einen, erst recht, wenn es auch noch komfortabel benutzbar sein soll, ganz schön lange beschäftigen.

    Schon die normalen 64-Bit-Typen können bekanntlich, je nach gesetzten Parametern, die RAM-Grenzen sprengen. Diese gewöhnliche Erkenntnis kann leicht davon ablenken, dass es schon innerhalb von Grenzen, wie du sie hier am Anfang genannt hast, leicht passieren kann, dass die Erde weniger Atome hat, als du Bits zum Speichern bräuchtest. Ich habe mir erspart, extra auszurechnen, ob die Sonne verglüht ist, bevor ein ganz normaler Computer mit den Berechnungen fertig wäre.

    Man braucht also sehr eng gesteckte Grenzen. Die Anzahl der Möglichkeiten kann man vorher schnell ausrechnen lassen, um die Sache notfalls, z.B. damit die Kiste nicht endlos in der Auslagerungsdatei herumrödelt, vorher abbrechen zu können. Harte Allokationsfehler lassen sich über Exceptions abfangen und sind daher eher leicht zu handhaben und eher kein Problem, wenn man sich darum kümmert. Aber wehe, der Speicher wird zugesichert, obwohl der RAM nicht genügt, dann kann es passieren, dass die Kiste lange nicht mehr antwortet. Ob der RAM aktuell genügen würde, ist gar nicht so leicht herauszufinden. Man bräuchte dazu schon probeweise Allokationen, evtl. Preallokation, und auch damit kann man noch auf die Fresse fallen.

    Nach meiner derzeitigen Arbeitshypothese, welche die Regelmäßigkeit bei deinem matrixartigen Gebilde (die ich vor ein paar Tagen wegen des sich abzeichnenden Wahnsinns so nicht wahrhaben wollte) befolgt, könnte man sagen, dass man sich dazu ein Zahlenschloss mit Ziffernrädchen vorstellen kann, bei dem aber unterschiedlich viele Ziffern je Rädchen erlaubt sind. Vielleicht kannst du mir bestätigen, ob ich damit richtig liege. Nicht dass mein Modell da schon hinkt. Es sollte leicht sein, das zu überprüfen, Zahlenschlösser, wie z.B. an Koffern oder Fahrradschlössern gebräuchlich, nehme ich mal als bekannt an.

    Also dreht in meiner Anwendung das erste "Rädchen" immer eine Position weiter, wobei es bei jedem Überlauf in die Anfangsposition zurückgesetzt wird und einen Übertrag generiert und damit das nächste Rädchen um eine Position weiterdreht, und so setzt sich das über alle Rädchen fort. Dabei stehen die S-Listen (je R eine) für ein Rädchen und die Einträge der S-Listen für die Ziffern darauf. Vielleicht kannst du mir kurz bestätigen, ob das passt.

    Das spuckt meine Anwendung dazu z.B. aus (speziell bei Zufallsgenerierung haben die Listen immer dieselbe Länge, funktioniert aber auch variabel):
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    Eingabe Ihrer Vorgaben:
            Simulation mit Zufallszahlen [j|n] : j
            Eigene Parameter verwenden [j|n] : n
    
    Ihre Vorgaben:
            Simulation mit Zufallszahlen: j
            Eigene Parameter verwenden: n
            Anzahl Risiken: 10
            Anzahl Schaeden: 4
            Minimale Schadenswahrscheinlichkeit: 0
            Maximale Schadenswahrscheinlichkeit: 100
            Minimale Schadenshoehe: 1500
            Maximale Schadenshoehe: 2573000
    
    Erzeuge Datenstruktur mit Zufallszahlen...
            ...fertig, Erzeugungsdauer: 2.608 ms
            Anzahl der Risiken: 10
            Anzahl der Schaeden je Risiko: 4
            Anzahl der Schaeden insgesamt: 40
            Plausibilitaetstest: Bestanden, weiter...
    
    1048576 Summen sollen aus 10 Risiken berechnet werden, fortfahren [j|n] ? : j
    
    >>> OK, berechne (bitte warten)...
            ...fertig! Berechnungszeit: 37.128 ms <<<
            Zur Berechnungszeit:
                    exkl. Einmal-Initialisierung,
                    inkl. Re-Initialisierung fuer aufeinanderfolgenden Gebrauch
                    (TODO:Abspecken)
    
    Zusammenfassung (Ist-Werte waehrend Berechnungen ausgezaehlt):
            Groesstes Produkt der Schadenswahrsch.: 2621469767554638000
            Groesste Summe der Schaeden: 23666745
            Summe aller Schaeden: 14110972968960
            Anzahl der berechneten Kombinationen (Summe u. Produkt zusammen: 1 Kombi):
                    Ist  : 1048576
                    Soll : 1048576
            Anzahl der Operanden aus allen Kombinationen (Summand u. Faktor zusammen: 1 Operand):
                    Ist  : 10485760
                    Soll : 10485760
            Plausibilitaetstest (TODO:Vervollstaendigen), Ergebnis (vorlaufig): Bestanden.
    
    Beenden mit Eingabe/Enter

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    Eingabe Ihrer Vorgaben:
            Simulation mit Zufallszahlen [j|n] : j
            Eigene Parameter verwenden [j|n] : j
            Anzahl der Risiken (Gruppen) [0;18446744073709551615] : 10
            Anzahl der Schaeden (je Gruppe) [0;18446744073709551615] : 5
            Minimale Schadenswahrscheinlichkeit [0;100] : 99
            Maximale Schadenswahrscheinlichkeit [0;100] : 100
            Minimale Schadenshoehe [0;18446744073709551615] : 1500
            Maximale Schadenshoehe [0;18446744073709551615] : 99999999
    
    Ihre Vorgaben:
            Simulation mit Zufallszahlen: j
            Eigene Parameter verwenden: j
            Anzahl Risiken: 10
            Anzahl Schaeden: 5
            Minimale Schadenswahrscheinlichkeit: 99
            Maximale Schadenswahrscheinlichkeit: 100
            Minimale Schadenshoehe: 1500
            Maximale Schadenshoehe: 99999999
    
    Erzeuge Datenstruktur mit Zufallszahlen...
            ...fertig, Erzeugungsdauer: 2.612 ms
            Anzahl der Risiken: 10
            Anzahl der Schaeden je Risiko: 5
            Anzahl der Schaeden insgesamt: 50
            Plausibilitaetstest: Bestanden, weiter...
    
    9765625 Summen sollen aus 10 Risiken berechnet werden, fortfahren [j|n] ? : j
    
    >>> OK, berechne (bitte warten)...
            ...fertig! Berechnungszeit: 355.596 ms <<<
            Zur Berechnungszeit:
                    exkl. Einmal-Initialisierung,
                    inkl. Re-Initialisierung fuer aufeinanderfolgenden Gebrauch
                    (TODO:Abspecken)
    
    Zusammenfassung (Ist-Werte waehrend Berechnungen ausgezaehlt):
            Groesstes Produkt der Schadenswahrsch.: 17564748453525883436
            Groesste Summe der Schaeden: 815682851
            Summe aller Schaeden: 4792976029296875
            Anzahl der berechneten Kombinationen (Summe u. Produkt zusammen: 1 Kombi):
                    Ist  : 9765625
                    Soll : 9765625
            Anzahl der Operanden aus allen Kombinationen (Summand u. Faktor zusammen: 1 Operand):
                    Ist  : 97656250
                    Soll : 97656250
            Plausibilitaetstest (TODO:Vervollstaendigen), Ergebnis (vorlaufig): Bestanden.
    
    Beenden mit Eingabe/Enter

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    Eingabe Ihrer Vorgaben:
            Simulation mit Zufallszahlen [j|n] : j
            Eigene Parameter verwenden [j|n] : j
            Anzahl der Risiken (Gruppen) [0;18446744073709551615] : 10
            Anzahl der Schaeden (je Gruppe) [0;18446744073709551615] : 6
            Minimale Schadenswahrscheinlichkeit [0;100] : 99
            Maximale Schadenswahrscheinlichkeit [0;100] : 100
            Minimale Schadenshoehe [0;18446744073709551615] : 1500
            Maximale Schadenshoehe [0;18446744073709551615] : 99999999
    
    Ihre Vorgaben:
            Simulation mit Zufallszahlen: j
            Eigene Parameter verwenden: j
            Anzahl Risiken: 10
            Anzahl Schaeden: 6
            Minimale Schadenswahrscheinlichkeit: 99
            Maximale Schadenswahrscheinlichkeit: 100
            Minimale Schadenshoehe: 1500
            Maximale Schadenshoehe: 99999999
    
    Erzeuge Datenstruktur mit Zufallszahlen...
            ...fertig, Erzeugungsdauer: 2.595 ms
            Anzahl der Risiken: 10
            Anzahl der Schaeden je Risiko: 6
            Anzahl der Schaeden insgesamt: 60
            Plausibilitaetstest: Bestanden, weiter...
    
    60466176 Summen sollen aus 10 Risiken berechnet werden, fortfahren [j|n] ? : j
    
    >>> OK, berechne (bitte warten)...
            ...fertig! Berechnungszeit: 2016.05 ms <<<
            Zur Berechnungszeit:
                    exkl. Einmal-Initialisierung,
                    inkl. Re-Initialisierung fuer aufeinanderfolgenden Gebrauch
                    (TODO:Abspecken)
    
    Zusammenfassung (Ist-Werte waehrend Berechnungen ausgezaehlt):
            Groesstes Produkt der Schadenswahrsch.: 17564748453525883436
            Groesste Summe der Schaeden: 884493459
            Summe aller Schaeden: 30822315748420608
            Anzahl der berechneten Kombinationen (Summe u. Produkt zusammen: 1 Kombi):
                    Ist  : 60466176
                    Soll : 60466176
            Anzahl der Operanden aus allen Kombinationen (Summand u. Faktor zusammen: 1 Operand):
                    Ist  : 604661760
                    Soll : 604661760
            Plausibilitaetstest (TODO:Vervollstaendigen), Ergebnis (vorlaufig): Bestanden.
    
    Beenden mit Eingabe/Enter

    Das Programm ist sozusagen sein eigener Test, um alles beieinander zu dokumentieren (ein Überlauftest ist jedoch nicht implementiert). Die Produkte fehlen nicht, sie werden bloß in einer alten Textzeile nicht miterwähnt. Während der Ausführung war noch der Editor im FF offen, mitsamt zappelnden GIFs. Es war also kein ganz ruhiges System, aber ich denke, dass das für einen Ersteindruck hier noch vertretbar gewesen ist.

    Die Cache-Misses sind mal so und mal so (Zeiten schwanken, nach einigen Bemühungen, bei kleinen Datensätzen fast gar nicht mehr, wogegen man bei großen, wie z.B. beim letzten, mit etwas Pech, schon mal sporadisch ungefähr ein Drittel an Ausführungszeit hinzurechnen darf, was immer noch ein guter Wert ist, wenn man mitberücksichtigt, dass das verwendete System kurz vorm Anschlag ist und einiges vermutlich eher daran liegt), und ich habe nicht extra herumprobiert, um das schönzubiegen, das ist schon typisch.

    Es kommt hier, wie man leicht erahnen kann, bereits zum Überlauf bei der Multiplikation mit 64-Bit-Werten. Varianten mit 128, 256, 512 sowie 1024 Bit lassen sich, da sie an zentraler Stelle verwaltet werden, im Handumdrehen (aber nicht ganz ohne Überlegung bezüglich der anderen, mit ihnen zu verrechnenden, Typen, da feine Anpassungen möglich, aber normalerweise nicht unbedingt erforderlich, sind) einkompilieren.

    Nur kurz zur Implementierung, (weiter die Zahlenschlossanalogie bemühend):
    Die richtigen Ziffern auf den Rädchen werden ermittelt, indem in so etwas wie einem dynamischen Array je Rädchen ("R" hihi) ein Positionsidex abgelegt ist, welcher für jedes Ergebnis um 1 inkrementiert wird und am Schluss (der durch ebenso zwischengespeicherte Listengrößen ermittelt wird) wieder auf 0 zurückgesetzt wird, wobei ein Übertrag in das nächste Rädchen entsteht, sodass auch dieses um 1 inkrementiert wird, was natürlich nur bei Überträgen passiert. Anhand dieser, während der Abarbeitung je Ergebnis berechneten, Indizesfolge wird auf die Summanden und auch auf die Faktoren zugegriffen, um diese sofort aufzusummieren bzw. auszumultiplizieren. Obwohl das im Prinzip einfach ist und der Code einfach aussieht, war der Vorgang, um das gutqualitativ zu erreichen, doch nicht ganz so einfach.

    Ganzzahlen von unendlicher Genauigkeit gibt es unter C++ nicht (und woanders muss man aufpassen, dass sie kein Fake sind oder etwas anderes bezeichnen, JavaScript hat, wie ich gesehen habe, neuerdings wohl echte BigInts, wogegen "BigInt" unter C#-SQL nur eine 64-Bit-Struktur ist), weswegen ich Libs probiert habe. Damit bin ich vorerst gescheitert, weil ich wegen zu langer Ausführungs- und Wartezeiten die Geduld verloren habe. Letztendlich bin ich bei der Boost-Library für C++ und deren Typen mit fester Genauigkeit gelandet, was mir als ein sinnvoller Kompromiss erscheint, wenn man sowieso an Machbarkeitsgrenzen ankommt, z.B. uint128_t, mit dem ich gute Erfahrungen gemacht habe, wobei sich, falls nur zum Multiplizieren gebraucht (was der teuerste Teil ist), nur ungefähr eine Verdreifachung der Ausführungszeiten ergibt. Zeiten für verschiedene Typen, auch größere, könnte ich später mal posten, aber heute wohl eher nicht mehr.

    Die für alles verwendete CPU ist ein Mobile Core2Duo @1,8 GHz konstant, also ein schwachbrüstiger Zeitzeuge aus der Steinzeit (sollte man trotzdem nicht unterschätzen, übliche aktuelle CPU-Cores sind bei solchen Sachen nur ungefähr dreimal so schnell, taktbereinigt eher weniger) und das mit eher langsamem RAM.

    1. Nein, die "Wiederhohlung" muss so sein
    Dann ist das wirklich wie bei einem Zahlenschloss, richtig? So habe ich es implementiert.

    2. Die Anzahl der Elemente der Listen R und Der Liste S (in jedem einzelnen R-object eine eigene vorhanden) sind variable. Meist 3-5 S und zwischen 15 und 100 R
    Mal beim absoluten Minimum angesetzt (natürlich wieder mit Überlauf bei der Multiplikation, ließe sich aber ganz leicht ändern, nur eben mit Vervielfachung der Ausführungszeit):
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    Eingabe Ihrer Vorgaben:
            Simulation mit Zufallszahlen [j|n] : j
            Eigene Parameter verwenden [j|n] : j
            Anzahl der Risiken (Gruppen) [0;18446744073709551615] : 15
            Anzahl der Schaeden (je Gruppe) [0;18446744073709551615] : 3
            Minimale Schadenswahrscheinlichkeit [0;100] : 100
            Maximale Schadenswahrscheinlichkeit [0;100] : 100
            Minimale Schadenshoehe [0;18446744073709551615] : 1500
            Maximale Schadenshoehe [0;18446744073709551615] : 100000000
    
    Ihre Vorgaben:
            Simulation mit Zufallszahlen: j
            Eigene Parameter verwenden: j
            Anzahl Risiken: 15
            Anzahl Schaeden: 3
            Minimale Schadenswahrscheinlichkeit: 100
            Maximale Schadenswahrscheinlichkeit: 100
            Minimale Schadenshoehe: 1500
            Maximale Schadenshoehe: 100000000
    
    Erzeuge Datenstruktur mit Zufallszahlen...
            ...fertig, Erzeugungsdauer: 2.625 ms
            Anzahl der Risiken: 15
            Anzahl der Schaeden je Risiko: 3
            Anzahl der Schaeden insgesamt: 45
            Plausibilitaetstest: Bestanden, weiter...
    
    14348907 Summen sollen aus 15 Risiken berechnet werden, fortfahren [j|n] ? : j
    
    >>> OK, berechne (bitte warten)...
            ...fertig! Berechnungszeit: 843.297 ms <<<
            Zur Berechnungszeit:
                    exkl. Einmal-Initialisierung,
                    inkl. Re-Initialisierung fuer aufeinanderfolgenden Gebrauch
                    (TODO:Abspecken)
    
    Zusammenfassung (Ist-Werte waehrend Berechnungen ausgezaehlt):
            Groesstes Produkt der Schadenswahrsch.: 5076944270305263616
            Groesste Summe der Schaeden: 1125557153
            Summe aller Schaeden: 10718986072079052
            Anzahl der berechneten Kombinationen (Summe u. Produkt zusammen: 1 Kombi):
                    Ist  : 14348907
                    Soll : 14348907
            Anzahl der Operanden aus allen Kombinationen (Summand u. Faktor zusammen: 1 Operand):
                    Ist  : 215233605
                    Soll : 215233605
            Plausibilitaetstest (TODO:Vervollstaendigen), Ergebnis (vorlaufig): Bestanden.
    
    Beenden mit Eingabe/Enter

    Ja, das mit Bigint vs double/decimal habe Ich mir auch überlegt, am ende hat Bigint gewonnen, wegen den Genauigkeitsverlusten.
    Bist du sicher, dass die, speziell hier, wirklich relevant sind? Welches Bigint meinst du jetzt genau? Mich wundert etwas, dass das bei dir nicht so lahm ist, dass du den Typ aufgegeben hast. double (was man darunter landläufig versteht) währe echt toll, dann bliebe es, zumindest bei mir, bei der Größenordnung wie in meinen hier gezeigten Durchläufen, aber das könnte ich auch mal in einem Vergleich zeigen.

    Eventuell kann man da aber auch was drehen mit einer anderen Art der Rechnung.
    Ja, wobei ich mich die ganze Zeit über schon frage, ob die Mathematik so richtig ist. Was passiert denn, wenn eine Wahrscheinlichkeit 0 ist? Dann ist das gesamte Produkt 0. Bei allen meinen Arbeitshypothesen bezüglich des eigentlichen Problems ergibt das keinen Sinn (sondern etwas andere Verfahrensweisen, bei denen die Bezüge anders sind, sodass eher eine Summe aus Produkten entstünde, wobei verschiedene Varianten denkbar sind, mit verschiedener Aussagekraft), aber ich weiß natürlich nicht, was ausgerechnet werden soll, und ihr werdet schon eure Gründe haben. Ich will meinen Mund also nicht zu voll nehmen.

    Also wäre dein Vorschlag Bigint soweit möglich zu "Entfernen" und Die Multiplikation via long durchzuführen, bis zur grenze. Die Wahrscheindlichkeit kann maximal 100 sein, ergo weiss Ich wie viele Ich pro long maximal Multiplizieren kann ohne Overflow, und Ich kann am ende die Long mit BigInt Multiplizieren.
    Sollte es stimmen das BIgInt ziermlich langsam ist, würde das schon einiges bringen.
    Ich habe noch mittlere Zweifel (zumindest bin ich neugierig), dass dein BigInt das ist, was es sein soll, wenn du damit zurechtkommst. Oder man hätte bei dessen Konstruktion einen verdammt guten Job gemacht (evtl. sogar unter Ausnutzung hardwarespezifischer Features?).

    Und dazu noch einen Schnelleren RND Generator und dann könnte die Performance massiv ansteigen....
    Sind diese Zufallszahlen denn sicherheitskritisch? Sonst dürfte man eigentlich nicht viel von deren Generierung merken. Bei mir sind die sogar gleichverteilt und fallen trotzdem kaum ins Gewicht. Notfalls ließen sie sich bevorraten (in sicherheitskritischen Bereichen eher nicht, aber dazu müsste man Details wissen). Oder geht es nur, wie bei mir, um das Generieren von Testdaten? Dann sollte das echt kein Problem sein. Falls die Zufallsdaten relevant sind, wäre das mal ein interessanter Ansatzpunkt für eine Erklärung.

    Ich kann immer noch nicht ganz glauben, was da berechnet werden soll (bzw. warum ausgerechnet das, um zu brauchbaren Aussagen zu gelangen). Vielleicht liegt dort schon das größte Problem.

    Hoffentlich habe ich jetzt nicht allzu viel übergangen, sorry dafür.
    jabu ist offline Geändert von jabu (30.07.2020 um 18:31 Uhr)

  9. #9 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    Schon mal danke im voraus für deinen Input.
    Die Analogie mit dem Fahrradzahlenschloss ist eigentlich ziemlich gut, es muss theoretisch jede Kombination davon durchprobiert werden. Praktisch können wir das Resultat annähern indem wir zufällige Kombinationen ausprobieren.

    Ganz Interessant finde Ich, das BigInt wohl extrem langsam ist, und es schneller wäre jeweils zuerst 9 oder 10 Elemente davon zusammen zu Multiplizieren, und erst am ende Bigint zu verwenden.
    Das könnte sehr viel bringen was die Performance angeht.

    double/decimal geht nicht, deren Genauigkeit reicht vermutlich nicht aus um an ende akturate Ergebnisse zu erhalten (zumindest wenn jeder wert Multipliziert/dividiert wird), wobei eventuell als Ganzzahl Multiplikation könnte das klappen. 10^308 klingt eigentlich ganz gut und reicht für mindestens 150R
    Alles über 200 klappt dann aber nicht mehr. ka. wie viele wir maximal haben

    Zufallsazahlen:
    Diese sind nicht Sicherheitsrelevant und werden im Breich von ca. 1-8 benötigt.

    Bigint:
    Ist ein C# Typ, welcher von M$ angeboten wird.
    Vielleicht war deren Verwendung ein Fehler. Wichtig war uns damals erstmal das die Werte, welche wir berechnen auch sinnvoll sind.

    Gerade was Mathematische CPU Berechnungen angeht, habe Ich mich bisher noch nicht um die Geschwindigkeit gekümmert, da Ich auch noch nie einen Algorithmus hatte, welcher CPU-Bound war, sonder fast alle, welche Ich bishr geschrieben habe waren/sind Cache-bound.
    Ich habe definitiv was gelernt beim Lesen deiner beiden Beiträge.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  10. #10 Zitieren
    Moderator Avatar von MadFaTal
    Registriert seit
    May 2010
    Beiträge
    3.632
    Zitat Zitat von Multithread Beitrag anzeigen
    double/decimal geht nicht, deren Genauigkeit reicht vermutlich nicht aus um an ende akturate Ergebnisse zu erhalten (zumindest wenn jeder wert Multipliziert/dividiert wird), wobei eventuell als Ganzzahl Multiplikation könnte das klappen. 10^308 klingt eigentlich ganz gut und reicht für mindestens 150R
    Alles über 200 klappt dann aber nicht mehr. ka. wie viele wir maximal haben

    Zufallsazahlen:
    Diese sind nicht Sicherheitsrelevant und werden im Breich von ca. 1-8 benötigt.
    Ich werde hier aussteigen, da ich nach wie vor nicht verstehe was für ein Algorithmus gesucht wird bzw. was Input und Output dieses Algorithmus sein soll.
    Vermutlich verstehe ich es nicht, weil es um ein Themenbereich geht, dessen Begrifflichkeiten ich nicht kenne.
    Wenn ich jetzt lese das akkurate Ergebnisse notwendig sind, in Zalhlenbereichen die für Menschen nicht mehr erfassbar sind, verstehe ich die Ausführungen auf den beiden vorherigen Themenseiten noch weniger. Möglicherweise ist dieses Thema schon älter und ich bin nur zufällig hineingestolpert.
    MadFaTal ist offline

  11. #11 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    Kein Thema.

    Vielleicht bin Ich auch einfach nur schlecht beim erklären des Problems

    Das Problem mit "Unmenschlicher genauigkeit" ist, das alle werte Sich danach in dem Wertbereich gruppieren :/
    Das Thema selbst ist ziemlich neu/aktuell, aber eher ein Nischenproblem.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  12. #12 Zitieren
    Legende Avatar von jabu
    Registriert seit
    Jul 2011
    Beiträge
    7.383
    Zitat Zitat von MadFaTal Beitrag anzeigen
    Ich werde hier aussteigen, da ich nach wie vor nicht verstehe was für ein Algorithmus gesucht wird bzw. was Input und Output dieses Algorithmus sein soll.
    Vermutlich verstehe ich es nicht, weil es um ein Themenbereich geht, dessen Begrifflichkeiten ich nicht kenne.
    Wenn ich jetzt lese das akkurate Ergebnisse notwendig sind, in Zalhlenbereichen die für Menschen nicht mehr erfassbar sind, verstehe ich die Ausführungen auf den beiden vorherigen Themenseiten noch weniger. Möglicherweise ist dieses Thema schon älter und ich bin nur zufällig hineingestolpert.
    Bist du nicht! Für ihn ist es wohl schon (evtl. doch nur etwas, siehe seinen Beitrag, "ziemlich neu") älter, wogegen es auch für mich neu ist. Ich muss genauso raten wie du, war nur so bekloppt, etwas zu basteln (muss mich manchmal zwingen, über den Tellerrand des Alltäglichen hinauszuschauen, um nicht völlig zu degenerieren). Was du geschrieben hast, greift doch gut die grundsätzlichen Problematiken solcher Berechnungen auf. Vielleicht braucht die Sache einfach etwas mehr Zeit, damit er sich mal wegen der konkreten, natürlich nur mathematischen (es sollte nicht noch mehr verraten werden), Anforderungen erkundigen kann. Falls du dir nicht länger auf der Grundlage unsicherer Annahmen die Haare raufen willst, verstehe ich das natürlich. Das Leben ist so schon anstrengend genug (natürlich frei von Hintergedanken gemeint).

    @Multithread:
    Heute schaffe ich nichts mehr, Antwort kommt später.
    jabu ist offline

  13. #13 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.231
    Zitat Zitat von jabu Beitrag anzeigen
    @Multithread:
    Heute schaffe ich nichts mehr, Antwort kommt später.
    Einfach nichts all zu grosses

    Deine Berechnung ist schon korrekt, zumindest soweit Ich das beurteilen kann.
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •