Forum: PC-Programmierung Double gegen Integer


von J. V. (janvi)


Lesenswert?

Momentan wundere ich mich über GCC in zwei Punkten:

1) habe ich eine Rechnung in einer Schleife von double auf int 
umgestellt. Dabei erhöht sich die Rechenzeit von 220 auf 590 mSec. 
Eigentlich hätte ich eine Beschleunigung erwartet. int, uint32_t und 
uint_fast_t sind praktisch gleich. Gibt es für die Verlangsamung eine 
plausible Erklärung oder lohnt es sich da noch mal genauer nachzuschauen 
? GCC compiliert -o3

2) bei int = double gibt es beim Compilieren keine Typwarnung. Kann man 
die überhaupt abstellen oder muß da was oberfaul sein ?

von fop (Gast)


Lesenswert?

Gib doch mal
- die Zielhardware
- die 2...3 Programmversionen
- die Compileroptionen, insbesondere die zu Optimierung, aber auch 
Bibliotheken
- die Art der Zeitmessung
an.

Ansonsten lautet die Antwort : 42

von (prx) A. K. (prx)


Lesenswert?

Konkretes Beispiel schlägt allgemeine Prosa.

von Amateur (Gast)


Lesenswert?

Wie fop schon gesagt hat: Viel zu wenig Informationen.

Normalerweise sollte man davon ausgehen, dass die Integerrechnung 
schneller vonstatten geht als die mit double's, aber vielleicht muss 
dafür, an anderer Stelle, ständig von integer auf double konvertiert 
werden.

von (prx) A. K. (prx)


Lesenswert?

Amateur schrieb:
> Normalerweise sollte man davon ausgehen, dass die Integerrechnung
> schneller vonstatten geht als die mit double's

Der Thread steht in "PC Programmierung" und bei x86 aus diesem 
Jahrtausend gilt diese Regel nicht. Da ist Fliesskommaverarbeitung sehr 
schnell und z.B. bei AMD getrennt von der Integerverarbeitung.

Der Teufel kann allerdings im Detail stecken, weshalb man dafür 
minimalisierte aber funktionsfähige Testprogramme benötigt.

: Bearbeitet durch User
von J. V. (janvi)


Lesenswert?

Ok, es ist ein Ubuntu 18.04 LTS auf einer HP Z440 Workstation mit 8 
Kernen.
(deshalb auch unter PC Programmierung gepostet). GCC ist mit 7.4.0 schon 
etwas altbacken ist halt bei der LTS dabei und compiliert als Release 
mit -o3. Die Zeitmessung halte ich für seriös und mache ich mit dem 
Systemtimer wobei uS wegfallen und mS auf plusminus 1% reproduzierbar 
sind
1
auto t2 = std::chrono::high_resolution_clock::now();
2
    auto duration = (std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count())/1000;

Die Rechnung ist eine Parallelschaltung mit vielen Iterationen:
1
            tmp_result = 
2
            (  int_lut[j] * int_lut[i] ) /
3
            (  int_lut[j] + int_lut[i] ); 
4
            tmp_result -= intTargetR;
5
 if( abs( tmp_result ) < (abs( best4R ) )

Die 220mS double Version sieht so aus
1
         tmp_result = 
2
            (  comb_lut[j].e_value * comb_lut[i].e_value ) /      
3
            (  comb_lut[j].e_value + comb_lut[i].e_value ); 
4
            tmp_result -= TargetR;
5
6
            if( abs( tmp_result ) < (abs( best4R ) ) )

Der if Zweig trifft selten zu und trägt damit nicht zur Laufzeit bei.
Interessanterweise wird die Laufzeit bei double ähnlich schlecht wenn 
ich die 1/R=1/Ra+1/Rb Formel nehme.

: Bearbeitet durch User
von J. V. (janvi)


Lesenswert?

daneben hätte ich erwartet, dass ein Zugriff auf array of struct länger 
dauert als auf ein int_array aber es ist genau gleich was für einen 
guten Optimizer spricht.
1
struct r_data  {
2
                     bool        e_use;
3
                     std::string e_name;
4
                     double      e_value;
5
               };
6
7
std::array<r_data,MAX_COMB> comb_lut;
8
std::array<int_fast32_t,   MAX_COMB> int_lut;

von Sly_marbo (Gast)


Lesenswert?

Aber die Anzahl der Iterationen ist gleich? Ich nehm mal an du hast mit 
220ms/590ms nicht nur einen Schleifendurchgang gemessen. Feste Anzahl an 
Iterationen oder gibt es eine Abbruchbedingung die bedingt durch den 
Datentp  früher oder später abbricht?

von J. V. (janvi)


Lesenswert?

das ganze 8 mal:

>cat /proc/cpuinfo

processor  : 0
vendor_id  : GenuineIntel
cpu family  : 6
model    : 63
model name  : Intel(R) Xeon(R) CPU E5-1620 v3 @ 3.50GHz
stepping  : 2
microcode  : 0x43
cpu MHz    : 1197.228
cache size  : 10240 KB
physical id  : 0
siblings  : 8
core id    : 0
cpu cores  : 4
apicid    : 0
initial apicid  : 0
fpu    : yes
fpu_exception  : yes
cpuid level  : 15
wp    : yes
flags    : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov 
pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx 
pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl 
xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor 
ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 
sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand 
lahf_lm abm cpuid_fault epb invpcid_single pti intel_ppin ssbd ibrs ibpb 
stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust 
bmi1 avx2 smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc 
dtherm ida arat pln pts md_clear flush_l1d
bugs    : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds 
swapgs itlb_multihit
bogomips  : 6983.82
clflush size  : 64
cache_alignment  : 64
address sizes  : 46 bits physical, 48 bits virtual
power management:

processor  : 1
vendor_id  : GenuineIntel
cpu family  : 6
model    : 63
model name  : Intel(R) Xeon(R) CPU E5-1620 v3 @ 3.50GHz
stepping  : 2
microcode  : 0x43
cpu MHz    : 1197.264
cache size  : 10240 KB
physical id  : 0
siblings  : 8
core id    : 1
cpu cores  : 4
apicid    : 2
initial apicid  : 2
fpu    : yes
fpu_exception  : yes
cpuid level  : 15
wp    : yes
flags    : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov 
pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx 
pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl 
xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor 
ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 
sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand 
lahf_lm abm cpuid_fault epb invpcid_single pti intel_ppin ssbd ibrs ibpb 
stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust 
bmi1 avx2 smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc 
dtherm ida arat pln pts md_clear flush_l1d
bugs    : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds 
swapgs itlb_multihit
bogomips  : 6983.82
clflush size  : 64
cache_alignment  : 64
address sizes  : 46 bits physical, 48 bits virtual

von Pandur S. (jetztnicht)


Lesenswert?

Fliesskomma Rechnung ist in einer FPU schon sehr schnell, aber eben 
keine Integergeschwindigkeit. Da fehlt schon noch ein Stueck.
Vielleicht nicht ganz unwichtig... Eine gleich grosse Integer Zahl hat 
eine hoehere Genauigkeit wie eine Floatzahl.

: Bearbeitet durch User
von J. V. (janvi)


Lesenswert?

es sind in beiden Fälle etwa 26 Mio Iterationen mit einer herkömmlichen 
verschachtelten for Śchleife (index i,j), keine range based loop.

von ergo70 (Gast)


Lesenswert?

Was macht der denn da für Instruktionen draus? Vielleicht wird der 
double Code irgendwie autovektorisiert oder sowas.

Hier kann man sowas austesten:

https://godbolt.org/

von J. V. (janvi)


Lesenswert?

Danke für das hübsche Spielzeug. Damit brauch ich nicht an cmake 
rumbasteln. Ich muss mir noch etwas Zeit nehmen das ganze weiter zu 
isolieren. Wenn ich zwischen den Zeilen lese sollte sich eine nähere 
Betrachtung doch lohnen da auch andere hier erwarten daß int schneller 
als double sein sollte.

von Oliver S. (oliverso)


Lesenswert?

J. V. schrieb:
> Danke für das hübsche Spielzeug.

Ganz ehrlich: Wer Mikro-Optimierungen betrieben will, und über 
cache-misses schwadroniert, sollte in der Lage sein, seiner Toolchain 
Disassemblies zu entlocken, und die auch zu verstehen.

Oliver

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

macht gcc/cc von sich aus Gebrauch von AVX/SSEx ?
Ich würde gern mal das Compilat des Schnipsels sehen von beiden 
Versionen.

So ein Gedanke: Fliesskomma Richtung SSE auslagern und Integer auf dem 
Standardbefehlssatz.

von Oliver S. (oliverso)


Lesenswert?

Dennis H. schrieb:
> macht gcc/cc von sich aus Gebrauch von AVX/SSEx ?

Muss er halt nachschauen, wie sein gcc configuriert ist. Üblicherweise 
erstellt der generischen (ARM64)-Code.

Wer aber auf dem level optimiert, soellte -march=native und vielleicht 
auch noh ein paar weitere Optionen nutzen.

Oliver

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

J.V.:

Haste schonmal auf so einer Seite geschaut ?

https://docs.microsoft.com/de-de/cpp/intrinsics/x64-amd64-intrinsics-list?view=vs-2019

Da kann man noch einiges Rauskitzeln mit direkten SSE-Befehlen in C.
Erfreulicherweise gibt es dann Datentypen die das Handhaben 
vereinfachen.

In der Liste fehlen jetzt leider die AVX512-Befehle.

Ich habe das mal mit Anwendung auf ein Numpy-Array genutzt. Das 
Numpy-Eigene OR war mir zu langsam. Mit

  __m256i* pnt=PyArray_DATA(in_array);
  __m256i q0,q1,q2,q3;

  uint64_t t=PyArray_SIZE(in_array)/16/4/2;
  while(t--) {
    q0=*pnt;
    q1=*(pnt+1);
    q2=*(pnt+2);
    q3=*(pnt+3);
    *pnt++=_mm256_or_si256(q0,p);
    *pnt++=_mm256_or_si256(q1,p);
    *pnt++=_mm256_or_si256(q2,p);
    *pnt++=_mm256_or_si256(q3,p);
  }

gings direkt 4x so schnell.

von Le X. (lex_91)


Lesenswert?

Oliver S. schrieb:
> Wer aber auf dem level optimiert, soellte -march=native und vielleicht
> auch noh ein paar weitere Optionen nutzen.

Oliver S. schrieb:
> Ganz ehrlich: Wer Mikro-Optimierungen betrieben will, und über
> cache-misses schwadroniert,

Halt mal etwas den Ball flach.

Ich habe eher das Gefühl der TE interessiert sich einfach dafür was da 
genau los ist.
Er ist zufällig über eine Merkwürdigkeit gestolpert und will das nun 
genauer untersuchen.
Und auch die Mitleser (inklusive mir) scheinen das interessant zu finden 
weil das beobachtete Verhalten erstmal ungewöhnlich scheint.

Von einem zwingenden (Mikro-) Optimierungsbedarf lese ich da nichts.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Der TO ist ja nicht nur in dem Thread hier unterwegs...

Oliver

von Manfred M. (bittbeisser)


Lesenswert?

Mein erster Verdächtiger wäre die Division.

Übersetze das Programm mal mit den Optionen -g -S und schau dir mal den
Assembler Output an. Durch die -g Option ist im Assemblertext auch die 
ursprüngliche Zeilennummer enthalten, wonach du suchen kannst.

von (prx) A. K. (prx)


Lesenswert?

Joggel E. schrieb:
> Fliesskomma Rechnung ist in einer FPU schon sehr schnell, aber eben
> keine Integergeschwindigkeit.

Die Fliesskomma-Division ist heute wesentlich schneller als die 
Integer-Division (seit Intel Core 2 und AMD K7).

CPU ist Haswell, dafür gilt lt. Agner Fog als Latenz:
- Integer Division u32:  22-29 Takte
- SSE Fliesskomma 32/64: 10-13 Takte
Beim Durchsatz sind es 9-11 vs 7 Takte. Das ist der Wert, nach dem die 
nächste unabhängige Division gestartet werden kann.

: Bearbeitet durch User
von JV (Gast)


Lesenswert?

CPU ist Haswell, dafür gilt lt. Agner Fog als Latenz:
- Integer Division u32:  22-29 Takte
- SSE Fliesskomma 32/64: 10-13 Takte

Knapp Faktor 3 könnte sogar passen. Die Laufzeit verlängert sich von 
220mSec auf 580 mSec und das ist nicht von Pappe und hat wohl auch nix 
mit Mikrooptimierung zu tun. (Ein Mix-Listing habe ich leider noch immer 
nicht gekriegt)

von John Doe (Gast)


Lesenswert?

J. V. schrieb:
> Ok, es ist ein Ubuntu 18.04 LTS auf einer HP Z440 Workstation mit 8
> Kernen.
> (deshalb auch unter PC Programmierung gepostet). GCC ist mit 7.4.0 schon
> etwas altbacken ist halt bei der LTS dabei

Mach mal das Ubuntu nicht schlechter als es ist:
gcc in Version 8.3 ist auch bei der 18.04 LTS als Paket zu haben.

von JV (Gast)


Lesenswert?

hier mal die Integer Version
1
402:/home/jv/kicad/pcb_calculator/eseries.cpp ****             tmp_result = 
2
 403:/home/jv/kicad/pcb_calculator/eseries.cpp ****             (  int_lut[j] * int_lut[i] ) /      
3
 5980                           .loc 17 403 0
4
 5981 09c0 480FAFC3             imulq   %rbx, %rax
5
 402:/home/jv/kicad/pcb_calculator/eseries.cpp ****             (  int_lut[j] * int_lut[i] ) /      
6
 5982                           .loc 17 402 0
7
 5983 09c4 4899                 cqto
8
 5984 09c6 48F7FF               idivq   %rdi
9
 5985                   .LVL555:
10
 404:/home/jv/kicad/pcb_calculator/eseries.cpp ****             (  int_lut[j] + int_lut[i] );      // calculate 2R|2R parallel
11
 405:/home/jv/kicad/pcb_calculator/eseries.cpp ****             tmp_result -= intTargetR;                                   // calculate 4R deviation
12
 5986                           .loc 17 405 0
13
 5987 09c9 482B4424             subq    8(%rsp), %rax
14
 5987      08
15
 5988                   .LVL556:
16
 5989                   .LBB7424:
17
 5990                   .LBB7425:
18
 5991                   .LBB7426:
19
  56:/usr/include/c++/7/bits/std_abs.h **** #endif
20
 5992                           .loc 32 56 0
21
 5993 09ce 4889C2               movq    %rax, %rdx
22
 5994                   .LBE7426:
23
 5995                   .LBE7425:
24
 5996                   .LBE7424:
25
 5997                           .loc 17 405 0
26
 5998 09d1 4889C3               movq    %rax, %rbx
27
 5999                   .LVL557:
28
 6000                   .LBB7567:
29
 6001                   .LBB7428:
30
 6002                   .LBB7427:
31
  56:/usr/include/c++/7/bits/std_abs.h **** #endif
32
 6003                           .loc 32 56 0
33
 6004 09d4 48C1FA3F             sarq    $63, %rdx
34
 6005 09d8 4889D0               movq    %rdx, %rax
35
 6006                   .LVL558:
36
 6007 09db 4831D8               xorq    %rbx, %rax
37
 6008 09de 4829D0               subq    %rdx, %rax
38
 6009                   .LBE7427:
39
 6010                   .LBE7428:
40
 406:/home/jv/kicad/pcb_calculator/eseries.cpp **** 
41
 407:/home/jv/kicad/pcb_calculator/eseries.cpp ****             if( abs( tmp_result ) < (abs( best4R ) ) )                      // if new 4R is better
42
 6011                           .loc 17 407 0
43
 6012 09e1 4839C8               cmpq    %rcx, %rax
44
 6013 09e4 0F8CE601             jl      .L492
45
 6013      0000
46
 6014                   .LVL559:
47
 6015 09ea 4983C508             addq    $8, %r13
48
 6016 09ee 4883C530             addq    $48, %rbp
49
 6017                   .LBE7567:
50
 6018                   .LBE7579:
51
 382:/home/jv/kicad/pcb_calculator/eseries.cpp ****         {
52
 6019                           .loc 17 382 0 discriminator 2
53
 6020 09f2 48396C24             cmpq    %rbp, 40(%rsp)
54
 6020      28
55
 6021 09f7 0F845903             je      .L493
56
 6021      0000

von JV (Gast)


Lesenswert?

und hier die float Version
1
402:/home/jv/kicad/pcb_calculator/eseries.cpp ****             tmp_result = 
2
 403:/home/jv/kicad/pcb_calculator/eseries.cpp ****             (  int_lut[j] * int_lut[i] ) /      
3
 5980                           .loc 17 403 0
4
 5981 09c0 480FAFC3             imulq   %rbx, %rax
5
 402:/home/jv/kicad/pcb_calculator/eseries.cpp ****             (  int_lut[j] * int_lut[i] ) /      
6
 5982                           .loc 17 402 0
7
 5983 09c4 4899                 cqto
8
 5984 09c6 48F7FF               idivq   %rdi
9
 5985                   .LVL555:
10
 404:/home/jv/kicad/pcb_calculator/eseries.cpp ****             (  int_lut[j] + int_lut[i] );      // calculate 2R|2R parallel
11
 405:/home/jv/kicad/pcb_calculator/eseries.cpp ****             tmp_result -= intTargetR;                                   // calculate 4R deviation
12
 5986                           .loc 17 405 0
13
 5987 09c9 482B4424             subq    8(%rsp), %rax
14
 5987      08
15
 5988                   .LVL556:
16
 5989                   .LBB7424:
17
 5990                   .LBB7425:
18
 5991                   .LBB7426:
19
  56:/usr/include/c++/7/bits/std_abs.h **** #endif
20
 5992                           .loc 32 56 0
21
 5993 09ce 4889C2               movq    %rax, %rdx
22
 5994                   .LBE7426:
23
 5995                   .LBE7425:
24
 5996                   .LBE7424:
25
 5997                           .loc 17 405 0
26
 5998 09d1 4889C3               movq    %rax, %rbx
27
 5999                   .LVL557:
28
 6000                   .LBB7567:
29
 6001                   .LBB7428:
30
 6002                   .LBB7427:
31
  56:/usr/include/c++/7/bits/std_abs.h **** #endif
32
 6003                           .loc 32 56 0
33
 6004 09d4 48C1FA3F             sarq    $63, %rdx
34
 6005 09d8 4889D0               movq    %rdx, %rax
35
 6006                   .LVL558:
36
 6007 09db 4831D8               xorq    %rbx, %rax
37
 6008 09de 4829D0               subq    %rdx, %rax
38
 6009                   .LBE7427:
39
 6010                   .LBE7428:
40
 406:/home/jv/kicad/pcb_calculator/eseries.cpp **** 
41
 407:/home/jv/kicad/pcb_calculator/eseries.cpp ****             if( abs( tmp_result ) < (abs( best4R ) ) )                      // if new 4R is better
42
 6011                           .loc 17 407 0
43
 6012 09e1 4839C8               cmpq    %rcx, %rax
44
 6013 09e4 0F8CE601             jl      .L492
45
 6013      0000
46
 6014                   .LVL559:
47
 6015 09ea 4983C508             addq    $8, %r13
48
 6016 09ee 4883C530             addq    $48, %rbp
49
 6017                   .LBE7567:
50
 6018                   .LBE7579:
51
 382:/home/jv/kicad/pcb_calculator/eseries.cpp ****         {
52
 6019                           .loc 17 382 0 discriminator 2
53
 6020 09f2 48396C24             cmpq    %rbp, 40(%rsp)
54
 6020      28
55
 6021 09f7 0F845903             je      .L493

von JV (Gast)


Lesenswert?

Float ist beim Kopieren über die Zwischenablage falsch gelaufen
Hier also nochmal
[c]
 399:/home/jv/kicad/pcb_calculator/eseries.cpp **** 
tmp_result =
 400:/home/jv/kicad/pcb_calculator/eseries.cpp ****             ( 
comb_lut[j].e_value * comb_lut[i].e_value ) /
 6235                           .loc 17 400 0
 6236 0a40 F20F59C2             mulsd   %xmm2, %xmm0
 399:/home/jv/kicad/pcb_calculator/eseries.cpp ****             ( 
comb_lut[j].e_value * comb_lut[i].e_value ) /
 6237                           .loc 17 399 0
 6238 0a44 F20F5EC4             divsd   %xmm4, %xmm0
 6239                   .LVL584:
 401:/home/jv/kicad/pcb_calculator/eseries.cpp ****             ( 
comb_lut[j].e_value + comb_lut[i].e_value );      // calculate 2R|2R 
parallel
 402:/home/jv/kicad/pcb_calculator/eseries.cpp **** 
tmp_result -= targetR;                                      // calculate 
4R deviation
 6240                           .loc 17 402 0
 6241 0a48 F20F5CC3             subsd   %xmm3, %xmm0
 6242                   .LVL585:
 6243                   .LBB8220:
 6244                   .LBB8221:
 6245                   .LBB8222:
 6246                           .loc 32 71 0
 6247 0a4c 660F28D0             movapd  %xmm0, %xmm2
 6248 0a50 660F5415             andpd   .LC9(%rip), %xmm2
 6248      00000000
 6249                   .LBE8222:
 6250                   .LBE8221:
 403:/home/jv/kicad/pcb_calculator/eseries.cpp ****
 404:/home/jv/kicad/pcb_calculator/eseries.cpp ****             if( abs( 
tmp_result ) < abs( rslt_lut[S4R].e_value ) )      // if new 4R is 
better
 6251                           .loc 17 404 0
 6252 0a58 660F2ECA             ucomisd %xmm2, %xmm1
 6253 0a5c 0F87DE01             ja      .L513
 6253      0000
 6254                   .LVL586:
 6255                   .L471:
 6256 0a62 4883C330             addq    $48, %rbx
 6257                   .LBE8220:
 6258                   .LBE8365:
 380:/home/jv/kicad/pcb_calculator/eseries.cpp ****         {
 6259                           .loc 17 380 0 discriminator 2
 6260 0a66 483B5C24             cmpq    8(%rsp), %rbx
 6260      08
 6261 0a6b 0F843F03             je      .L514
 6261      0000
 6262                   .L479:
 6263                   .LBB8366:
 382:/home/jv/kicad/pcb_calculator/eseries.cpp **** 
tmp_result -= targetR;                                     // calculate 
4R deviation
 6264                           .loc 17 382 0
 6265 0a71 F20F1053             movsd   32(%rbx), %xmm2

von J. V. (janvi)


Lesenswert?

Kann leider nicht mehr editieren da ich über timeout ausgeloggt wurde.

Die Codeunterschiede sehen gar nicht soo arg aus alsda wären

mulsd und divsd für die double Version und
imulq und idivq für die interger Version

von (prx) A. K. (prx)


Lesenswert?

Das ist die 64-Bit Integer Version mit Vorzeichen. Die ist noch 
langsamer.
Latenz:
- Integer Division s64: 39-103 Takte
- SSE Fliesskomma 32/64: 10-13 Takte
Durchsatz:
- Integer Division s64:  24-81 Takte
- SSE Fliesskomma 32/64:     7 Takte

Gegenüber dem Haswell ist bei Integers sogar der Goldmont (Atom) in 
meinem Netbook schneller (s64: 13-43, double: 34).

Also Leute, von der Idee das bei den grossen x86 Integers schneller als 
Doubles seien, bitte ganz schnell abschwören. Nur bei den kleinen 
stimmts. ;-)

: Bearbeitet durch User
von cppbert (Gast)


Lesenswert?

J. V. schrieb:
> daneben hätte ich erwartet, dass ein Zugriff auf array of struct
> länger
> dauert als auf ein int_array aber es ist genau gleich was für einen
> guten Optimizer spricht.
> struct r_data  {
>                      bool        e_use;
>                      std::string e_name;
>                      double      e_value;
>                };
>
> std::array<r_data,MAX_COMB> comb_lut;
> std::array<int_fast32_t,   MAX_COMB> int_lut;

Keine Ahnung wo dein Wissen her kommt - nach Gefühl fühlt es sich an als 
wuerdest du 286/386 Erfahrungen auf aktuelle Hardware spiegeln, die 
meisten deiner Vermutungen (auch in anderen Posts) sind schlicht und 
einfach falsch, sorry

Deine Zeitmessung ist viel zu ungenau um diesen Unterschied zu erkennen, 
selbst wenn es einen geben würde

von cppbert (Gast)


Lesenswert?

Schau doch einfach auf den assemblercode, der Optimizer hatte da nur 
1982 probleme mit - deswegen finde ich deine Aussagen so verwirrent

von JV (Gast)


Lesenswert?

> Keine Ahnung wo dein Wissen her kommt

Habs ja eingesehen. Beim Anschauen von /proc/cpuinfo ist klar geworden 
daß bei den Cachegrößen sowieso die gesamte LUT reinpasst. Egal ob mit 
oder ohne struct. Ebenso habe ich mich halt auch mit den floats 
verpeilt. Auch wenn ich hier die Hocke vollkriege, war ich zumindest 
nicht der Einzige der danebengeschätzt hat.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.