Berechnung von "(id - (id % width)) / width" beschleunigen?

Gast
hast du mal den ASM code verglichen - ich kann mir kaum vorstellen das 
der compiler das versteht.

Nicht das du irgendwo anders ein zeitproblem hast.
Gast
Jo, habe woanders noch eine Größe zweimal berechnet. Vorberechnen hat 
nochmal ca. 10% Geschwindigkeit gebracht.

Es geht darum, Indices für die Ausgabe der berechneten Werte zu 
bestimmen (FFT). Diese Prozedur verschlingt bei Radix-2 FFT ca. die 
Hälfte der Zeit, wenn man das out-of-place macht (was ich machen muss, 
da ich OpenCL nutze und in-place wegen der Synchronisierung nicht für 
große FFTs geht).
1
    int id = get_global_id(0);  // thread index
2

3
    // width of each FFT block in the current stage
4
    int width = (int)exp2((float)(stage - 1));
5
    
6
    // the offset for a certain FFT block in the output index
7
    int offset = id / width;
8
    
9
    // input and output indices
10
    int inA = id;
11
    int inB = id + NThread;
12
    int outA = id % width + offset * 2 * width;
13
    int outB = outA + width;

inA, inB sind die Indices der beiden Eingänge und outA, outB der 
Ausgänge. Ich habe schon einiges optimiert und dadurch ca. doppelte 
Geschwindigkeit erreicht. Aber vielleicht gibt es noch weitere 
Möglichkeiten, die ich nicht sehe?

(Für Skizze siehe http://cnx.org/content/m12012/latest/#fig:inplace )
1
int offset = id / width;
2
int outA = id % width + offset * 2 * width;

könnte man, wenn ich mich nicht vertan habe auch so lösen:
1
int frc = id % width;
2
int outA = frc + (id-frc)<<1;

vorausgesetzt du benötigst offset nicht nochmal, sollte das auch 
schneller sein
Maik M. schrieb:
> was mir gerade aufgefallen ist, so könnte es auch gehen:
> int outA = id<<1 - id%width;

wo kommt das minus her

*2 durch shifts optimieren macht der Compiler.
Zumal es auch nicht immer sinn macht.
"x*8" rechnet zB ein Avr schneller als "x<<3"

Maik M. schrieb:
> int offset = id / width;
> int outA = id % width + offset  2  width;

-->

outA = id % width + (id / width)* 2 * width;
     = id % width + id * 2 ;
Vlad Tepesch schrieb:
> outA = id % width + (id / width)* 2 * width;
>      = id % width + id * 2 ;

bei ganzzahliger Division verschwinden die Nachkommastellen
1
outA = 3 % 2 + (3 / 2) * 2 * 2 = 1 + 4;
2
outA = 3 % 2 + 3 * 2 = 1 + 6;

zu deiner Frage mit dem Minus:
1
Ausgangsgleichung:
2
int outA = (id % width) + (id / width) * 2 * width;
3

4
(id/width)*width = id - (id % width)
5

6
daraus ergibt sich:
7
int outA = (id % width) + (id - (id % width)) * 2;
8
int outA = (id % width) + 2*id - 2*(id % width);
9
int outA = 2*id - (id % width);
10
int outA = id<<1 - (id % width);
Gast
Vlad Tepesch schrieb:
> daraus ergibt sich:
> int outA = (id % width) + (id - (id % width)) * 2;
> int outA = (id % width) + 2*id - 2*(id % width);
> int outA = 2*id - (id % width);
> int outA = id<<1 - (id % width);

Weitere 10%, danke! ;)
Wobei 2*id und id<<1 gleich schnell sind.
Maxim schrieb:
> Weitere 10%, danke! ;)

aber achtung
Das verändert das Ergebnis.

Maik M. schrieb:
> bei ganzzahliger Division verschwinden die Nachkommastellen


Es treten bei meiner Rechnung weniger Rundungsfehler auf - kann ja aber 
sein, dass das gewollt war

Maxim schrieb:
> Wobei 2*id und id<<1 gleich schnell sind.

das schrieb ich ja: solche optimierungen sollte man dem Compiler 
überlassen.
wenn man Multiplikation meint, schreibt man das was mein meint, nämlich 
*
und wenn man die bitschiebeoperation will, schreibt man <<
Der Compilier weiß schon ganz gut, wie das optimal umgesetzt wird.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.