AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Random(2) in schnell

Ein Thema von glkgereon · begonnen am 30. Mär 2007 · letzter Beitrag vom 11. Mai 2007
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    
Benutzerbild von Nikolas
Nikolas

Registriert seit: 28. Jul 2003
1.528 Beiträge
 
Delphi 2005 Personal
 
#11

Re: Random(2) in schnell

  Alt 31. Mär 2007, 09:09
Was machst du denn überhaupt mit den Zahlen? Vielleicht gibt es eine Möglichkeit, das Ganze anders anzusetzen.
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
Amateurprofi
Online

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.041 Beiträge
 
Delphi XE2 Professional
 
#12

Re: Random(2) in schnell

  Alt 31. Mär 2007, 09:57
Vielleicht liege ich jetzt völlig falsch, aber ich versuche es mal.

Du bist der Auffassung, die Nutzung der Random Funktion nähme zuviel Zeit in Anspruch.
Wenn das so sein sollte : Was macht Dein Programm, außer ausschließlich die Random-Funktion aufzurufen ?
Ein Aufruf Random(2) benötigt 24 CPU-Ticks (GetTickCount=16 CPU-Ticks)

QueryPerformanceFrequency ist als Alternative natürlich nicht tauglich, denn die liefert dir die Frequenz von QueryPerfomanceCounter, sollte also ein konstanter Wert sein.

Das Ergebnis von QueryPerformanceCounter wäre eine Alternative, allerdings braucht das ca. 2900 Ticks also mehr als 100 mal so viel wir Random(2).

Statt des lahmen QPC könntest Du den Time Stamp Counter direkt abfragen, aber auch das braucht 88 CPU-Ticks, also fast 4 mal so viel wie Random(2).

Delphi-Quellcode:
FUNCTION TimeStamp:Int64;
asm
   rdtsc
end;
Wenn du, was das Beitrag vermuten läßt, eine Zufallszahl im Bereich 0..1 haben möchtest könntest du das so realisieren

Delphi-Quellcode:
FUNCTION Random2:integer;
asm
   rdtsc
   and eax,1
end;
Wenn ich das alles völllig falsch verstanden habe, dann ignoriere das Obige bitte.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#13

Re: Random(2) in schnell

  Alt 31. Mär 2007, 10:09
Zitat von Der_Unwissende:
Zitat von glkgereon:
Leider scheint Random kein Int64 zu unterstützen
Hi,
dafür unterstützt es als Ausgabe 80Bit-Extended Werte
Man sollte aber wahrscheinlich nur die Mantisse verwenden. Das Zero-Bit wird meißtens 1 sein und das Sign-Bit immer 0. Der Exponent wird denke ich auch nicht stark genug schwanken.
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#14

Re: Random(2) in schnell

  Alt 31. Mär 2007, 10:28
der Zufallsgenerator von Delphi mal in Assembler und für 1/0 optimiert:
Delphi-Quellcode:

  asm
    @@nochma:
    imul ecx, ecx, $8088405 // vielleicht hier mal experimentieren
    inc ecx
    //mov edx, ecx

    js @@ist1
// wenn 0 mache:
    nop

    jmp @@nochma
    @@ist1:
// wenn 1 mache:
    nop

    jmp @@nochma
  end;
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#15

Re: Random(2) in schnell

  Alt 31. Mär 2007, 10:36
Mersenne Twister kanste vergessen, zu langsam.

Aber zum Angang machst du mal was anders

Erzeuge eine 323Bit Zufallszahl. Diese global speichern. Bei der Berechnung in deinen Funktionen dann diese Funktion

Delphi-Quellcode:
var
  Zufall: Caridnal = 0;

function RandomBit: Boolean;
begin
  Zufall := Zufall shr 1 or Zufall shl 31;
  Result := Odd(Zufall);
end;

initialization
  Randomize;
  Zufall := Random(MaxInt);
end.
Dies produziert zwar immer die gleiche Sequenz aus 32 Bits, aber dies spielt zur Einschätzung, um wieviel du durch die Optimierung deines RNGs an Zeit einsparen könntest, keine Rolle.

Im alten DEC war ein TRandom_LFSR mit Perioden von 2^32-1 bis 2^2032-1 bei dem der LFSR 128 mit Periode 2^128-1 ungefähr 43Mb/Sec auf einem P4 1.5GHz lief. Du könntest dir aus dem Source dieses LFSR extrahieren.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#16

Re: Random(2) in schnell

  Alt 31. Mär 2007, 11:28
Ok, ich denke es ist an der Zeit mal genauer den "Sinn" des Projektes zu erläutern.

Im Prinzip geht es um ein OnlineGame.
Bei diesem Spiel ist es möglich Waffen mithilfe von Edelsteinen zu veredeln. (Um Schaden zu erhöhen...)
Hierbei gibt es Waffenstufen von 0 bis 15.
Für jeden Up-Versuch wird ein Stein benötigt.
Es besteht eine 50%-Chance dass der Versuch erfolgreich ist (Stufe wird um eins erhöht)
Schlägt der Versuch fehl, wird die Stufe verringert (Allerdings nur falls die neue Stufe nicht unter 3 liegt...d.h. bei einem Fehlschlag bei Stufe 0,1,2 oder 3 bleibt alles wie es ist).

Ziel ist es einen Simulator dazu zu schreiben, welcher die Steine zählt die man braucht um eine Waffe von 0 auf 15 zu bringen.
Quelltext ist folgender:
Delphi-Quellcode:
while Akt<>Config.Ziel do //Akt = Aktuelle Stufe
begin
  if Rnd>31 then begin R:=Random(MaxInt); Rnd:=0; end; //Letztes Bit meines 32Bit Random-Werts => Neue Zahl
  if (R and (1 shl Rnd))<>0 then //Aktuelles Bit true?
    Inc(Akt) //Eins Hoch
  else if Akt>3 then Dec(Akt); //Sonst wenn Stufe>3 dann runter
  Inc(C); //Versuch zählen
  Inc(Rnd); //Nächstes Bit
end;
Ich hoffe es ist klar dass ein "nicht zufälliger zufallsgenerator" mir nicht weiterhilft

Ein weiteres Problem, welches mir soeben aufgefallen ist ist der Array den ich für meine Ergebnisse nutze...
insgesamt sieht das so aus:
Delphi-Quellcode:
TUpper = class
// ...
  FRes64: array of Int64;
end;

procedure TUpper.Generate(Cnt: Int64);
var Akt, Rnd: Byte;
    C, Len: Int64;
    R: Integer;
begin
  Len:=Length(FRes64);
  Rnd:=255;
  R:=0;
  while Cnt>0 do
  begin
    Akt:=Config.Start;
    C:=0;
    while Akt<>Config.Ziel do
    begin
      if Rnd>31 then begin R:=Random(MaxInt); Rnd:=0; end;
      if (R and (1 shl Rnd))<>0 then
        Inc(Akt)
      else if Akt>3 then Dec(Akt);
      Inc(C);
      Inc(Rnd);
    end;
    if C>=Len then
    begin
      Len:=C+1;
      SetLength(FRes64,Len);
    end;
    Inc(FRes64[C]);
    Dec(Cnt);
  end;
end;
in anbetracht der Tatsache dass Random nur 22 Cycles benötigt, liegt es vielleicht doch eher am SetLength?
(Wie) kann man das optimieren?

Daher stellt sich mir nun die Frage ob man hier überhaupt noch groß optimieren kann...(Aber da vertrau ich ganz auf euch )
Im Moment braucht diese Funktion so wie sie da steht für 100.000.000 Durchläufe 386 Sekunden auf einem AMD 3000+ (seperater Thread, tpLower, Opera,Miranda usw im Hintergrund laufend)
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

Registriert seit: 28. Jul 2003
1.528 Beiträge
 
Delphi 2005 Personal
 
#17

Re: Random(2) in schnell

  Alt 31. Mär 2007, 12:04
Bei so einem Problem solltest du dich eher an einem Stochastiker wenden. Gut Möglich, dass du im Matheboard.de jemanden mit einer Lösung finden kannst. Du hast hier einen Random-Walk in einem beschränkten Intervall, vielleicht hat schon jemand eine analytische Lösung gefunden.
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#18

Re: Random(2) in schnell

  Alt 31. Mär 2007, 13:13
Zitat von 3_of_8:
Man sollte aber wahrscheinlich nur die Mantisse verwenden. Das Zero-Bit wird meißtens 1 sein und das Sign-Bit immer 0. Der Exponent wird denke ich auch nicht stark genug schwanken.
Warum sollte denn der Exponent nicht stark genug schwanken? Ich meine die Random-Funktion erzeugt recht gleichverteilt Zahlen zwischen 0 und 1 (idealerweise). Das wiederum heißt, dass alle negativen Exponenten recht gleichmässig verwendet werden können (oder übersehe ich etwas?), was wohl wieder ein Bit weniger bedeutet. Bleiben von den 80 Bit eines Extended immer noch 77 übrig. Das sind immer noch mehr Bits als bei einem Int64 nötig währen, die schwanken (Sinn und Nutzen mal außen vor)


Gruß Der Unwissende
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#19

Re: Random(2) in schnell

  Alt 31. Mär 2007, 13:46
Stimmt, wenn man das Sign-Bit des Exponenten rauslässt, könnte es gehen. Und man spart sich auch die Multiplikation, die man hat, wenn man das ganze in einen Integer umrechnet.
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#20

Re: Random(2) in schnell

  Alt 31. Mär 2007, 20:37
sag mal, was machst du eigentlich da?
Delphi-Quellcode:
if C>=Len then
    begin
      Len:=C+1;
      SetLength(FRes64,Len);
    end;
    Inc(FRes64[C]);
ich kann mir nicht vorstllen, dass du 2^32 ergebnisse auf dem bildschirm sehen möchtest. schränk das doch mal ein und bau dir eine vernünftige datenstruktur auf, anstatt immer den speicher umzumodeln...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz