2020-01-14, 13:14
  #13
Medlem
kaks avatar
Citat:
Ursprungligen postat av grabb1948
Utan optimering i kompilatorn så är det ju CPUn som bestämmer.
Nja, CPU:n bestämmer väl alltid. Den vet ju inte vilka flaggor som kompilatorn har körts med.
Vad några tidigare har försökt utrycka är att varken kompilatorns optimeringar eller processorns val av ordning av operationer får ha någon observerbar effekt på ett korrekt program. Förutom prestanda förstås.

OP:s program är dock ej korrekt, så kompilatorn är fri att göra vad den vill.
Citera
2020-01-14, 15:14
  #14
Medlem
Eftersom timern mäter något annat så tar jag något enklare:

Kod:
 #include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
 {
   int a = 3, b, c, d, e, f, g, h, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, z1, z2, z3, z4, z5, z6 ;
   
  // for (int i = 0; i < 2; i++)
   {
    t= r/a;
    s= o/a;
    r= a/a;
    p= 2*a;
    o= b/a;
    h = b/a;
    g= h%a;
    f= b/a;
    e= c%a;
    d= c/a;
    b=3*a;
    c=a/a;
    p= k+a+d;
    q= p+b+m;
    n= k+a;
    m= 1+b+l;
    l=3*a+k;
    k=a+b+3;
    t= r/a;
    u = t/a;
    v= h/a;
    w= b/z6;
    x= c/a;
    y= c/a +p;
    z=3*a;
    z1=z5/a;
    z2= k+a+d;
    z3= p+b+m;
    z4= k+a;
    z5= 1+b+l;
    a= a+b;
    }
 }
    

Med ARM A-53 fungerar detta utan optimering.
Men om jag kör for-slingan blir det floating point error.
Varför?
Nämnaren a är ju känd.
Citera
2020-01-14, 15:20
  #15
Medlem
Flyttal
Kod:
#include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
  float s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30;
  for (int i = 0; i < 2000000; i++)
   {
    s30= sqrt(5);
    s29= 1/s3;
    s28= 1/s1;
    s27= sqrt(s30);    
    s26= sqrt(10);
    s25= sqrt(5);
    s24= 1/s3;
    s23= 1/s1;
    s22= 1/s30;
    s21= 1/s3;
    s20= sqrt(10);
    s19=s20/s30;
    s17=sqrt(s20);
    s16=s15+s23;
    s7= 1/s1;
    s8=  s7*s7;
    s5=  s1+s1;
    s10= s3+s1;
    s1= sqrt(10);
    s12= 1/s1;
    s13= s2/s3;
    s14= 1/s3;
    s15= 5+s7;
    s2=s1/s5;
    s3=s10/s17;
    s4=s5/s2;
    }
}
   

Däremot fungerar detta utan optimering.
Citera
2020-01-14, 16:48
  #16
Medlem
Citat:
Ursprungligen postat av grabb1948
Eftersom timern mäter något annat så tar jag något enklare:

Kod:
 #include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
 {
   int a = 3, b, c, d, e, f, g, h, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, z1, z2, z3, z4, z5, z6 ;
   
  // for (int i = 0; i < 2; i++)
   {
    t= r/a;
    s= o/a;
    r= a/a;
    p= 2*a;
    o= b/a;
    h = b/a;
    g= h%a;
    f= b/a;
    e= c%a;
    d= c/a;
    b=3*a;
    c=a/a;
    p= k+a+d;
    q= p+b+m;
    n= k+a;
    m= 1+b+l;
    l=3*a+k;
    k=a+b+3;
    t= r/a;
    u = t/a;
    v= h/a;
    w= b/z6;
    x= c/a;
    y= c/a +p;
    z=3*a;
    z1=z5/a;
    z2= k+a+d;
    z3= p+b+m;
    z4= k+a;
    z5= 1+b+l;
    a= a+b;
    }
 }
    

Med ARM A-53 fungerar detta utan optimering.
Men om jag kör for-slingan blir det floating point error.
Varför?
Nämnaren a är ju känd.
Jag förstår inte riktigt vad du håller på med. Du skriver felaktig kod och sedan försöker du dra slutsatser av resultatet som många gånger blir odefinierat p g a den felaktiga koden... Ibland så går koden att köra då kompilatorn optimerat bort buggarna. Känns bara snurrigt. Kanske du borde lära dig att skriva korrekt kod istället för att slösa bort din tid på dessa i mitt tycke rena strunttesterna.
Mer till din fråga
Kod:
    w= b/z6;
a må vara känt men det är inte z6...
Citera
2020-01-14, 18:30
  #17
Medlem
Citat:
Ursprungligen postat av DieTrolle
Jag förstår inte riktigt vad du håller på med. Du skriver felaktig kod och sedan försöker du dra slutsatser av resultatet som många gånger blir odefinierat p g a den felaktiga koden... Ibland så går koden att köra då kompilatorn optimerat bort buggarna. Känns bara snurrigt. Kanske du borde lära dig att skriva korrekt kod istället för att slösa bort din tid på dessa i mitt tycke rena strunttesterna.
Mer till din fråga
Kod:
    w= b/z6;
a må vara känt men det är inte z6...

Tack jag får lägga in ett värde på z6.
Det går inte att editera här.

Jag testar CPUer inte kompilatorer.
Kompilatorn ska klara koden utan optimering. Däremot ska jag få run time error för vissa CPUer.
Hur ska jag annars se skillnaden mellan in-order och out-of-order?
__________________
Senast redigerad av grabb1948 2020-01-14 kl. 18:53.
Citera
2020-01-14, 19:02
  #18
Avslutad
Citat:
Ursprungligen postat av grabb1948
Tack jag får lägga in ett värde på z6.
Det går inte att editera här.

Jag testar CPUer inte kompilatorer.
Kompilatorn ska klara koden utan optimering. Däremot ska jag få run time error för vissa CPUer.
Hur ska jag annars se skillnaden mellan in-order och out-of-order?
Har du ens läst på om vad out-of-order betyder? Det är något som processorn sköter på egen hand. På vilket sätt hade du tänkt dig "testa" out-of-order med din kod?
Citera
2020-01-14, 19:42
  #19
Medlem
Citat:
Ursprungligen postat av SittFint
Har du ens läst på om vad out-of-order betyder? Det är något som processorn sköter på egen hand. På vilket sätt hade du tänkt dig "testa" out-of-order med din kod?

Prestanda är lite svårt att jämföra direkt bla pga olika MHz.
Men koder med tex 100 ADD+30 MUL+10 DIV skulle kunna visa något.
Det går att jämföra optimal och icke-optimal ordning.
Men ingen optimering från kompilatorn!
__________________
Senast redigerad av grabb1948 2020-01-14 kl. 19:44.
Citera
2020-01-14, 23:14
  #20
Medlem
kaks avatar
Citat:
Ursprungligen postat av grabb1948
Tack jag får lägga in ett värde på z6.
Det går inte att editera här.

Jag testar CPUer inte kompilatorer.
Kompilatorn ska klara koden utan optimering. Däremot ska jag få run time error för vissa CPUer.
Hur ska jag annars se skillnaden mellan in-order och out-of-order?
Hur menar du att du skulle få runtime error?
Citera
2020-01-15, 10:56
  #21
Medlem
Citat:
Ursprungligen postat av kak
Hur menar du att du skulle få runtime error?

Vissa beräkningar beror helt på ordningen de utförs i.
int a= 10*1/3.
Om nu 1 delas med 3 får man heltalet 0 som ger a= 10*0=0.
Däremot ger 10*1 =10 som ger a= 3 efter division.
Detta "problem" fixas vid optimering men troligen även vid "out of order".
Citera
2020-01-15, 12:18
  #22
Medlem
O-o-o är en liiiten aning mer komplext än att kolla int a = 10*1/3.

Det handlar om att CPUn kan dispatcha operationer till en instruktionskö, om inte operanderna är tillgängliga när instruktionen läses in. CPUn behöver alltså inte vänta på att operanderna blir tillgängliga för att kunna dispatcha instruktionen (och hämta nästa instruktion).
Instruktionen kommer ligga i kön till dess operanderna är tillgängliga.

O-o-o innebär alltså inte att instruktioner kommer exekveras i slumpmässig ordning och beroenden kommer såklart att hanteras också.

Dessutom är 10*1/3 entydigt definierat som (10*1)/3 och kommer alltså inte att evalueras som 10*(1/3).

Jag antar såklart att vi pratar om vriabler med värden enligt ovan. Konstanterna 10, 1 och 3 är ju totalt ointressanta för de kommer aldrig nå CPUn.

Men lycka till med dina försök avseende O-o-o...
Citera
2020-01-15, 13:58
  #23
Medlem
Citat:
Ursprungligen postat av A.Selkirk
O-o-o är en liiiten aning mer komplext än att kolla int a = 10*1/3.

Det handlar om att CPUn kan dispatcha operationer till en instruktionskö, om inte operanderna är tillgängliga när instruktionen läses in. CPUn behöver alltså inte vänta på att operanderna blir tillgängliga för att kunna dispatcha instruktionen (och hämta nästa instruktion).
Instruktionen kommer ligga i kön till dess operanderna är tillgängliga.

O-o-o innebär alltså inte att instruktioner kommer exekveras i slumpmässig ordning och beroenden kommer såklart att hanteras också.

Dessutom är 10*1/3 entydigt definierat som (10*1)/3 och kommer alltså inte att evalueras som 10*(1/3).

Jag antar såklart att vi pratar om vriabler med värden enligt ovan. Konstanterna 10, 1 och 3 är ju totalt ointressanta för de kommer aldrig nå CPUn.

Men lycka till med dina försök avseende O-o-o...

Det som är förbryllande med optimering som -O1 är att det sällan ger "run-time-error".
Division med noll borde väl alltid ge det?
Ja det är mycket med "out of order".
De flesta CPUer hanterar FADD i en egen pipe.
Däremot bör nog FDIV och FMUL störa varandra om de inte kommer i lämplig ordning.
Mycket tidsödande för A-53 verkar FSQRT vara även jämfört med FDIV.
Citera
2020-01-15, 22:52
  #24
Avslutad
Citat:
Ursprungligen postat av grabb1948
Vissa beräkningar beror helt på ordningen de utförs i.
int a= 10*1/3.
Om nu 1 delas med 3 får man heltalet 0 som ger a= 10*0=0.
Däremot ger 10*1 =10 som ger a= 3 efter division.
Detta "problem" fixas vid optimering men troligen även vid "out of order".
Men NEJ! Båda typerna av processorer ger exakt samma resultat. Out of order är något som sker internt i processorn. Det enda du kan märka av detta är ökad prestanda.

Citat:
Ursprungligen postat av grabb1948
Det som är förbryllande med optimering som -O1 är att det sällan ger "run-time-error".
Division med noll borde väl alltid ge det?
Ja det är mycket med "out of order".
De flesta CPUer hanterar FADD i en egen pipe.
Däremot bör nog FDIV och FMUL störa varandra om de inte kommer i lämplig ordning.
Mycket tidsödande för A-53 verkar FSQRT vara även jämfört med FDIV.
Om ditt program har olika beteende med och utan optimering så är det antingen fel på ditt program eller en bugg i kompilatorn. Punkt. Innehåller ditt program division med noll så är det felaktigt.

Kompilatorn är fri att spotta ur sig vilken maskinkod som helst så länge dess observerbara beteende inte förändras. Det inkluderar att ta bort död kod. Och om din kod innehåller något som är UB så får den spotta ur sig exakt vad som helst.
__________________
Senast redigerad av SittFint 2020-01-15 kl. 22:56.
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in