Vinnaren i pepparkakshustävlingen!
2020-08-07, 02:19
  #13
Avstängd
Citat:
Ursprungligen postat av kak
Ja det kan du, men det gör inte det du tror.
Du skapar två olika typer med samma namn, men med synlighet enbart i sitt respektive lokala block.
D.v.s. efter if/else satsen är båda typerna bortglömda.
Det du vill göra är
Kod:
#ifdef USE_FLOAT
typedef float hej;
#else
typedef double hej;
#endif 

uppskattar hjälpen, det här är sjukt bra om det funkar, hade gett upp om att det skulle gå att växla enkelt
Citera
2020-08-07, 02:35
  #14
Medlem
kaks avatar
Citat:
Ursprungligen postat av shotor
prestanda
Är du säker på att skillnad är så stor mellan float och double?
Citera
2020-08-07, 02:42
  #15
Avstängd
Citat:
Ursprungligen postat av kak
Är du säker på att skillnad är så stor mellan float och double?

har inte testat själv, men av vad jag har läst ska det vara signifikant, tillämpning är inbyggt system med FPU, de räknar floats snabbt men double är segare då det körs med mjukvara (på chip antar jag)
__________________
Senast redigerad av shotor 2020-08-07 kl. 02:45.
Citera
2020-08-07, 02:49
  #16
Avstängd
Citat:
Ursprungligen postat av kak
Är du säker på att skillnad är så stor mellan float och double?

är det nån hastighetsskillnad på att köra med generic selection eller flagga?
Citera
2020-08-07, 03:10
  #17
Medlem
Citat:
Ursprungligen postat av shotor
Jag vill inte fatta beslutet under runtime, jag skriver ett program som genererar kod och vill att denna kod ska kunna vara både float och double, float till inbyggda system och double till PC. Koden som genereras kallar en massa funktioner och jag vill att dessa funktioner ska kunna hantera båda fallen på ett så enkelt sätt som möjligt, men fortfarande vara snabbt för inbyggda system.

Så antingen använder jag typedef och flagga när jag skriver funktionerna eller så skriver jag funktioner för t.ex. float och försöker göra så att jag kan ändra dem till double genom att läsa in filen och ändra automatiskt, det senare med ett annat program så jag får två grupper med funktioner.

typedef och flagga måste vara enklare, påverkar det hastigheten att göra så?
OBS att double står för double float.

I din spec för ditt inbyggda system ska det finnas förklarat vad float och double innebär.
Många kompilatorer idag kör float som varande double, dvs float omdefinieras, defaultas till double direkt.

Är ditt inbyggda system bara tex 16-bitars så kan man förstå att float finns kvar.
Det är ju mest bara i specialfall som det blir stor skillnad i hastighet. I synnerhet om ditt inbyggda system saknar FPU.
Hastigheten i inbyggda system brukar vara av underordnad betydelse, om du nu inte bygger radarkontrollerade system som - typ Bofors (BAE Systems) Archer eller Israels Irondome, som måste köra kanske milljontals flyttalsberäkningar på kort tid. Eller typ kryssningsmissiler som måste bearbeta data mycket snabbt.

I professionella programvaror så skiljer man på de olika varianterna med att sätta till ett prefix på varje funktion, tex prefixet df för double float, och f för float.
Double är egentligen double float. Float omfattade 32 bitars flyttal, och kallades för single precision floating point numbers. Medans double float avsåg double precision floating point numbers, dvs 64 bitar.
Har du en 32-bitars CPU i ditt inbyggda system så finns det ingen anledning att använda float. Den extra overheaden att exekvera samma instruktioner för double float märker du inte mycket av.
Eller ja visst kan man nog bygga en testprogramvara där man kan se en sådan skillnad, om man nu vill alltså.

Jag vet inte ens om det finns 32-bits CPUer att köpa som saknar FPU ?
Det torde vara en verkligt smal marknad för sådana i så fall.

Du måste också vara säker på att en float omvandlas korrekt till rätt värde i double och även att det omvända kan ske korrekt. Man föredrar gärna double eftersom den översätts korrekt mellan olika system, tex Apple, PC, osv. Den omfattas IEEE754-standarden som garanterar detta.
Om flyttalsrepresentationen i diverse olika bit-konfigurationer:
https://en.wikipedia.org/wiki/Floating-point_arithmetic
https://en.wikipedia.org/wiki/IEEE_754

Varje output till skärmen är mycket långsammare än vad som händer inne i CPUn där det går miljontals gånger fortare i de flesta fall.

Är det redan 64-bitars CPU i ditt inbyggda system så finns det ingen anledning att använda float, du kan köra allt som double. Och det går ungefär lika fort.
I vissa fall kan det gå långsammare att tvinga CPUn att räkna som den vore en 32-bit CPU med 32-bits float, eftersom du måste maska bort överskottsbitarna då och då.

Man kan ju undra om det finns flyttal med färre än 32 bitar ? Jovisst skulle man kunna konstruera sådana men de blir inte särskilt användbara.
Det blir ungefär som att använda ett måttband som bara är en decimeter långt, typ...
Alltså inte så användbart, eller hur ?
16-bits floats har använts en del framförallt för tex vissa grafiktillämpningar, men det är väl helt överspelat nu kan jag tro. Med dagens CPUer så är det meningslöst att hantera 16-bitar åt gången, man kan lika gärna hantera 64-bitar i ett sjok -- det går nästan lika fort.
36-bitars CPUer kom att dominera på stordatorsidan på 1960/1970-talet för de kunde hantera 10 siffror i vetenskapliga beräkningar, 10 siffror tar nämligen upp 34 bitar, plus ett för tecknet + elr -. Och behovet var i början för bla militären att man var tvungen att ha så många siffror.

Men inte ens det räckte tex för komplicerade navigationsmanövrar tex till sjöss, eller på flygplan. Då var man tvungen att öka till 64 bitar.

Tips är att kolla specen för ditt inbyggda system om hur den räknar flyttal, och om FPUn kan hantera 64-bits double direkt.

Om det är minnesbehovet som är begränsande så är nog designen feltänkt ifrån början.
Redan 1 GB är en sjuhelvetes massa minne. Men det är klart om du bygger en kopia av Bofors Archer hemma i garaget så kan jag tänka mig att man börjar nog fundera på minska minnesfootprinten

Förresten är sådana system som tex Bofors Archer och Israels Irondome exempel på sådan programvara som kan parallelliseras i många trådar, och exekveras på många kärnor samtidigt, och dessutom klara av sin uppgift bra.

Nu vet jag inte hur de är byggda - Jag har inte tittat inuti, men det kan ju hända att det sitter en ryslig massa kineser där med kulramar, räknestickor och räknar hela tiden, fan vet ?

Citat:
Ursprungligen postat av shotor
har inte testat själv, men av vad jag har läst ska det vara signifikant, tillämpning är inbyggt system med FPU, de räknar floats snabbt men double är segare då det körs med mjukvara (på chip antar jag)

Aha, du ska ha rätt libs medlänkade i din exe. De kan kanske utnyttja din FPU på bästa sätt.
Chipet ÄR mjukvaran fast den är inbränd i kretsen.
Tillverkaren av CPU-modellen i ditt inbyggda system brukar ge fingervisningar om vilka switchar du måste sätta på kompilatorn vid kompileringen.
Om kompilatorn inte vet vilken CPU/FPU-modell du har kanske den eller op-systemet länkar in ett sk emulator-lib som omvandlar all flyttalskod till en (långsammare) mjukvarulösning
Och vad CPU/FPUn klarar i FLOPS (Floating point operations per second)
Möjligt att du kan hitta något på Forum och FAQs om just den CPU/FPU-modellen.
Tillverkaren av CPU/FPUn brukar ha länkbara libs för just din modell.
Och då också vilka kompilatorer som är kompatibla med dessa libs
Större länkbara libs finns också för ljudkort och grafikkort där en del modeller kan öka beräkningskapaciteten mycket kraftigt.

Om du sedan är nöjd med hastigheten eller inte är hopplöst svårt att svara på.
Det brukar vara ett design-problem ifrån början om hastigheten eller minnesutrymmet inte duger.
Antingen är problemet felformulerat, lösningen är feldesignad eller så måste ni använda en vassare CPU och mera minne, någon annan lösning brukar inte finnas.

BTW: Man undviker ibland flaggor just på grund av att varje test kostar en CPU-cykel. Duger för undervisning ja, men i tidskritisk programvara så undviker man att testa samma flagga om och om igen. Det är slöseri på CPU-tid...
Måste man använda den designen du implicerar med flaggor så kan du istället ha en funktionspekare som ställs att peka på en funktion som hanterar float i det ena scenariot, och pekar på en annan funktion som hanterar double i det andra. Så byggs tidskritiska system, på det viset så testas flaggan bara en gång. Funktionspekaren ställs bara i början i runtime.
Man kan också välja att tvångscasta till den typ du för tillfället vill köra, castar man en 32-bits float till en double så ska koden konvertera 32-bits float till 64-bits double. Och då expanderas utrymmet med de extra 32 bittarna, nollor läggs till alltså.
__________________
Senast redigerad av AnalAnalfabeten 2020-08-07 kl. 04:07.
Citera
2020-08-07, 04:57
  #18
Medlem
Citat:
Ursprungligen postat av AnalAnalfabeten
Man kan också välja att tvångscasta till den typ du för tillfället vill köra, castar man en 32-bits float till en double så ska koden konvertera 32-bits float till 64-bits double. Och då expanderas utrymmet med de extra 32 bittarna, nollor läggs till alltså.

OBS: Tvångscastning åt andra hållet ifrån double till float vill man gärna undvika eftersom 32 bitar kommer att kapas bort, det blir alltså en förlust i precisionen. Det är inte riktigt samma sak som avrundning. Programspråket C specificerar ingen avrundningsmetod generellt utan bittarna kapas (trunkeras) bara bort.
Filosofin i C är enkel att programmeraren själv ska (måste) ta ansvar för sådant.

Måste man på något sätt förbättra konverteringen så måste man skriva den koden själv.
Men alla som är insatta i detta vet att det blir en grötig kod då, därför skriver de flesta idag sin kod att bara hantera double. Enklast så. Särskilt inom de tekniskt orienterade verksamheterna.
Man kan helt enkelt inte i dessa sammanhang ha och bemästra de problem som följer med för låg precision i beräkningarna. Det kan man nämligen inte komma runt så lätt, utan blir svåra tankenötter att lösa om man måste göra det.
Och felberäkningar i tekniska sammanhang kan kosta sanslösa summor med pengar. Tex att man bygger en bro, och på grund av att man räknat belastningarna med 32-bits float, i Finita Element-Metoden så rasar bron ihop i en dammhög redan dagen efter den stod klar. Det blir ju inte så kul, om man då istället hade klarat av problemet med att räkna med double istället.

Men som jag tidigare nämnde så är kompilatorkonstruktörerna medvetna om detta problem, därför så översätts float till double direkt i många fall.
Visst finns det äldre länkbara libs som tex har den gamla float, dvs 32-bits.
Det är dock en hel del riktigt tuff och vital hjärngymnastik att tanka hem och läsa direkt i källkoden för tex ett emulatorlib. Hur man gör trollerier med flyttal för att operationerna ska gå någorlunda snabbt.

Och tex en del tidigare smartphones hade ingen bra flyttalsprestanda, utan det finns några modeller med handjagad emulator kod. Nu vet jag ju inte om de används längre.
Men med dagens utveckling så finns nya problem vid horisonten. Och det gäller tex simuleringar likt vädersystem mm. Eller andra simuleringar som innefattar GFLOPS och mera, och där inputdatan används i många miljoner steg.. Där ses tydligen de problem av sk propagering av avrundningsfel/trunkeringsfel genom hela beräkningskedjan.
Propagering av beräkningsfel innebär alltså att felen i beräkningarna förstärks efterhand ju fler steg i beräkningarna genomförs.

I banker och andra ekonomiska verksamheter så kan man förstås inte tolerera sådana fel. Nej sådan kod skrivs på ett annat sätt faktiskt.

Finns ju även tex 256 bits floats om man nu vill vara (extra) noga.
Citera
2020-08-07, 10:47
  #19
Medlem
kaks avatar
Citat:
Ursprungligen postat av shotor
är det nån hastighetsskillnad på att köra med generic selection eller flagga?
Nej, om du med flagga menar preprocessorvariabel.
Citera
2020-08-07, 12:10
  #20
Medlem
kaks avatar
Citat:
Ursprungligen postat av AnalAnalfabeten
OBS att double står för double float.

I din spec för ditt inbyggda system ska det finnas förklarat vad float och double innebär.
Många kompilatorer idag kör float som varande double, dvs float omdefinieras, defaultas till double direkt.

I professionella programvaror så skiljer man på de olika varianterna med att sätta till ett prefix på varje funktion, tex prefixet df för double float, och f för float.
Double är egentligen double float. Float omfattade 32 bitars flyttal, och kallades för single precision floating point numbers. Medans double float avsåg double precision floating point numbers, dvs 64 bitar.
C-standarden använder suffix, f för float, inget för double och l för long double. (sqrtf, sqrt, sqrtl)
Citat:
Ursprungligen postat av AnalAnalfabeten
Har du en 32-bitars CPU i ditt inbyggda system så finns det ingen anledning att använda float. Den extra overheaden att exekvera samma instruktioner för double float märker du inte mycket av.
Eller ja visst kan man nog bygga en testprogramvara där man kan se en sådan skillnad, om man nu vill alltså.
Bra, mät först och optimera sen.
Citat:
Ursprungligen postat av AnalAnalfabeten
Jag vet inte ens om det finns 32-bits CPUer att köpa som saknar FPU ?
Det torde vara en verkligt smal marknad för sådana i så fall.

Du måste också vara säker på att en float omvandlas korrekt till rätt värde i double och även att det omvända kan ske korrekt. Man föredrar gärna double eftersom den översätts korrekt mellan olika system, tex Apple, PC, osv. Den omfattas IEEE754-standarden som garanterar detta.
Om flyttalsrepresentationen i diverse olika bit-konfigurationer:
https://en.wikipedia.org/wiki/Floating-point_arithmetic
https://en.wikipedia.org/wiki/IEEE_754

Varje output till skärmen är mycket långsammare än vad som händer inne i CPUn där det går miljontals gånger fortare i de flesta fall.

Är det redan 64-bitars CPU i ditt inbyggda system så finns det ingen anledning att använda float, du kan köra allt som double. Och det går ungefär lika fort.
I vissa fall kan det gå långsammare att tvinga CPUn att räkna som den vore en 32-bit CPU med 32-bits float, eftersom du måste maska bort överskottsbitarna då och då.

Man kan ju undra om det finns flyttal med färre än 32 bitar ? Jovisst skulle man kunna konstruera sådana men de blir inte särskilt användbara.
Det blir ungefär som att använda ett måttband som bara är en decimeter långt, typ...
Alltså inte så användbart, eller hur ?
16-bits floats har använts en del framförallt för tex vissa grafiktillämpningar, men det är väl helt överspelat nu kan jag tro. Med dagens CPUer så är det meningslöst att hantera 16-bitar åt gången, man kan lika gärna hantera 64-bitar i ett sjok -- det går nästan lika fort.
Det finns folk som jobbar med att standardisera 16-bits flyttal i C++.
Detta då GPU:er kan utföra parallella beräkningar på många av dessa samtidigt.
16-bits flyttal är dessutom bättre i vissa applikationer än 16-bits och till och med 32-bits heltal.
De kan bättre beskriva dynamiken hos vissa storheter på ett sätt som efterliknar det mänskliga ögats känslighet.
Citat:
Ursprungligen postat av AnalAnalfabeten

Om det är minnesbehovet som är begränsande så är nog designen feltänkt ifrån början.
Redan 1 GB är en sjuhelvetes massa minne. Men det är klart om du bygger en kopia av Bofors Archer hemma i garaget så kan jag tänka mig att man börjar nog fundera på minska minnesfootprinten


Om du sedan är nöjd med hastigheten eller inte är hopplöst svårt att svara på.
Det brukar vara ett design-problem ifrån början om hastigheten eller minnesutrymmet inte duger.
Antingen är problemet felformulerat, lösningen är feldesignad eller så måste ni använda en vassare CPU och mera minne, någon annan lösning brukar inte finnas.

BTW: Man undviker ibland flaggor just på grund av att varje test kostar en CPU-cykel. Duger för undervisning ja, men i tidskritisk programvara så undviker man att testa samma flagga om och om igen. Det är slöseri på CPU-tid...
Måste man använda den designen du implicerar med flaggor så kan du istället ha en funktionspekare som ställs att peka på en funktion som hanterar float i det ena scenariot, och pekar på en annan funktion som hanterar double i det andra. Så byggs tidskritiska system, på det viset så testas flaggan bara en gång. Funktionspekaren ställs bara i början i runtime.
Test av flaggan kostar betydligt mer än en cykel. Det är framförallt hoppen som kostar då instruktionscachar invalideras m.m.
Tyvärr är ju inte funktionspekare gratis heller. Det kostar mer att anropa via pekare än att anropa funktionen direkt. Dessutom blir det omöjligt för kompilatorn att inlina effektivt.
TS fösöker skrivaa typgenerisk kod i ett språk som saknar bra stöd för detta.
Då får man ta till preprocessorn och generic selections, då de har noll overhead.
Citera
2020-08-08, 00:04
  #21
Avstängd
Citat:
Ursprungligen postat av AnalAnalfabeten
I professionella programvaror så skiljer man på de olika varianterna med att sätta till ett prefix på varje funktion, tex prefixet df för double float, och f för float.
Double är egentligen double float. Float omfattade 32 bitars flyttal, och kallades för single precision floating point numbers. Medans double float avsåg double precision floating point numbers, dvs 64 bitar.
Har du en 32-bitars CPU i ditt inbyggda system så finns det ingen anledning att använda float. Den extra overheaden att exekvera samma instruktioner för double float märker du inte mycket av.
Eller ja visst kan man nog bygga en testprogramvara där man kan se en sådan skillnad, om man nu vill alltså.


Du måste lära dig att fokusera på frågan

Är det inte orimligt att en double ska gå lika snabbt som en float i en 32 bitars FPU? FPU:n är ju designad just för floats.
Citera
2020-08-08, 03:53
  #22
Medlem
Citat:
Ursprungligen postat av kak
Tyvärr är ju inte funktionspekare gratis heller. Det kostar mer att anropa via pekare än att anropa funktionen direkt. Dessutom blir det omöjligt för kompilatorn att inlina effektivt.
TS fösöker skrivaa typgenerisk kod i ett språk som saknar bra stöd för detta.
Då får man ta till preprocessorn och generic selections, då de har noll overhead.

Hm har inte kollat men kanske att pekaren fungerar som en "wrapper", och att den därmed slösar på stackanropen, precis som du skriver. Det kan dock inte bli många extra steg. Kollade för ett tag sedan på gammal Mozilla Firefox-kod och där fanns mycket riktigt en hel del funktionspekare, beroende på vilken typ av objekt som lästs in. Tex GIF eller JPG. Nu gör man samma sak men läser in objektet i tex en klass istället.
Det finns ett flertal varianter. Den versionen av Firefox var optimerad och kunde inte se att det skulle vara så stor tidsförlust att använda pekare.
Skrev fel i början, alltså inget prefix, jag var väl trött efter en skön bastu igår natt. Suffixet är rätt sätt att namnge funktioner i C, det gör att man lättare kommer ihåg vad som gäller. Prefixet är tillämpligt för variablerna, sk hungarian notation. Hungarian notation är ett sätt att namnge variabler på ett sätt som är knutet till dess typ.
https://en.wikipedia.org/wiki/Hungarian_notation
Charles Simonyi, Microsofts utvecklare för bla Office switen gjorde denna till en slags standard, mest för att lära programmerarna att kunna komma ihåg hur de ska skriva kod på rätt sätt.
Men hungarian notation är liksom ingen egen standard.

Men jag tvivlar på att det ska krävas att man håller sig till den namnkonventionen för sina egna funktioner. Det är inte en del av standarden att namnge funktioner på det sättet.
Det borde vara svårt att lägga till sådan funktionalitet i kompilatorn att den skulle behärska de reglerna till punkt och pricka. De reglerna blir ju inte självklara om det rör sig om mer komplicerade funktioner och typer av variabler.
Microsoft bildade en egen skola med sin hungarian notation, och speciella sätt att skriva Win API anropen.
Tittar man och jämför med äldre Unix grafisk fönsterorienterad kod så ser man direkt att Microsofts approach med att ha genomgående namnkonventioner avsevärt förenklar lärandet - Och att i sådan Unix-kod nybörjarna såg ut som fågelholkar direkt ifrån Samhalls verkstad..
Även i Unix fanns viss logik där också men inte alls lika framträdande.

Ja precis, sk konditionell kompilering med preprocessordirektiv, defines, - jo koden kan då se ut så här:
Kod:
#if defined(USE_FLOAT) && defined(USE_DOUBLE)
#error Ambigous use of USE_FLOAT and USE_DOUBLE preprocessor defines
#endif
#if !defined(USE_FLOAT) && !defined(USE_DOUBLE)
#error No preprocessor define directive  USE_FLOAT or USE_DOUBLE used
#endif

#if defined(USE_FLOAT)
float Myfunction(float fParam)
{
/* Function body here */
return (float) 0.0;
}
#endif
#if defined(USE_DOUBLE)
double Myfunction(double dParam)
{
/* Function body here */
return (double) 0.0;
}
#endif 

De första #if raderna har att göra med att programmerarna måste komma ihåg att välja en av de två. Men bara en av dem.
Man kan se många liknande #if satser i tex headerfiler att man måste se till att använda rätt preprocessordirektiv. Ibland kan de också kallas switchar (= (signal-)flaggor) hos kompilatorn.
Man bör skriva kollen av defines på det sättet som visas här, och undvika komplexa nästlade #if-satser helt enkelt för att det är så sabla lätt att klanta sig utan att se var det går fel någonstans.

Vad är ett preprocessorkommando eller preprocessordirektiv då ?
Svar: - Alla rader som inleds med ett #-tecken
Också kan kallas ett macro, dvs en funktion som egentligen inte är en funktion utan bara en substitution av en bit text.
Och preprocessorn är det program som körs innan den egentliga kompileringen. Preprocessorns uppgift är främst att dels expandera alla sk macron till C-kod och sätta ihop alla headerfiler som behövs för kompileringen.
Kompilatorn gör sedan maskinkod av alltihopa, som då kommer att heta en OBJ-fil. Den länkas med länkaren ihop till ett körbart, exekverbart program.
Men att hela sekvensen gås igenom utan fel är ingen garanti för att det är ett meningsfullt program, och kraschar när man minst anar det.

Det har av och till framförts att kompilatorn ska ge mera uttrycksfulla felmeddelanden och varningar.
Utifrån felmeddelandet så kan den nybakade programmeraren ägna massor av timmar i onödan av letandet.
Trots att det ofta är något enkelt.
Men det har liksom gått i stå, dels ifrån gamla rävar att felmeddelandena kan inte göras så generella att man samtidigt ger nybörjaren ytterligare kunskap i språket. Medans andra anser att man visst kunde länka med tex hjälptexter.
Och tex speciellt så är felmeddelandena när det gäller templates synnerligen kryptiska. Den nyexaminerade programmeraren har ofta svårt att inse att hen glömt att instantiera en templateklass eller ett templatebibliotek. Och felutskriften ifrån kompilatorn blir rena gallimatiasen då.

Citat:
Ursprungligen postat av shotor
Du måste lära dig att fokusera på frågan

Är det inte orimligt att en double ska gå lika snabbt som en float i en 32 bitars FPU? FPU:n är ju designad just för floats.

Ja det är ju innebörden av namnet FPU, Floating Point Unit, en krets avsedd att beräkna flyttal helt enkelt. Men bara för att man säger att den kan hantera floats, så säger den inget om antalet bittar den använder internt och externt, nej.
Även en double är ett flyttal, men dubbla antalet bittar, och är en kortform av det ursrungliga namnet "double precision floating point number.
I och för sig så finns det säkert 32-bits lösningar som fungerar med 32-bit FPU tex i så fall sk Smart-TV och Platt-TV, men det är grafiken det handlar om då.
7 signifikanta siffror är där tillräckliga. Ögat kan inte upptäcka finare gradienter i bilden ändå.
Sådan grafik behöver inte beräknas med vanliga flyttalsoperationer. Man kan mycket väl skriva särskild programvara som sköter det numeriska utan att kalla dem för flyttal precis. Man har ju ingen nytta av exponenten då precis.
Finns säker mycket intressant att hämta där.
Tex när 24 bits grafik var i ropet, 8+8+8, 8 bitar för varje färg så skrevs kod särsklit för att hantera 24-bits "tal", pixelinfo alltså. Det var en specialllösning ja. Men när flera tillverkare började använda 32 bit ändå, och 30 bitars grafik. Att det sedan översattes till 24-bits grafik för att skärmen inte kunde visa mer än 24 bitar det må vara hänt. Finns otroligt mycket intressant att läsa om detta och hur de optimerade koden som skulle snurra där.
Citera
2020-08-08, 04:09
  #23
Medlem
Citat:
Ursprungligen postat av shotor
har inte testat själv, men av vad jag har läst ska det vara signifikant, tillämpning är inbyggt system med FPU, de räknar floats snabbt men double är segare då det körs med mjukvara (på chip antar jag)
"Chipet" är alltså FPUn som "mjukvaran" körs på.
Vilket värdeintervall förväntar du inom din programvara, tex exponent 10^-126 till 10^+127
eller ?
Citat:
Ursprungligen postat av shotor
Du måste lära dig att fokusera på frågan

Är det inte orimligt att en double ska gå lika snabbt som en float i en 32 bitars FPU? FPU:n är ju designad just för floats.
Hur ska jag kunna göra det om jag inte vet vilka prestanda FPUn har på din CPU ?
Jag vet ju inte om din "FPU" består av en massa kineser med kulramar ?
Du måste själv ta reda på vilka hastigheter du kan uppnå med din kod.
Kompilera en variant för float och en för double.
Och du ska mäta först och optimera sedan.
Tillverkaren har nog någonstans uppgifter av vad den ska klara av.
Är hastigheten inte tillräcklig för vad ditt inbyggda system måste klara av i responstider mm, så har du bara att välja en snabbare CPU/FPU - något annat val brukar inte finnas.
Ja i och för sig att du kan splitta beräkningarna på flera kärnor, om det går vill säga.
Och om du ändå vill använda 32-bits float, är du säker på att du kan tolerera felen i beräkningarna ?

Det är det jag skriver att många FPUer hanterar 64-bits double nästan lika bra som 32-bits float.
Fastän de är inbrända ihop med en 32-bit CPU så kan de räkna med fler bittar
Som jag skriver är 32-bits float nästan obsoleta nu. Med bara 7 signifikanta decimalsiffror i mantissan har du inte mycket att spela på faktiskt. Men det beror ju naturligtvis på vad ditt inbyggda system måste klara av att räkna med. Du kan ju i och för sig omvandla flyttalet till integers om det går att göra. Och att du inte behöver tex exponenten.
Bland annat på grund av att felpropageringen vid många aritmetiska operationer efter varandra är oacceptabelt stor för 32-bits floats, flyttal. Medans vid 64-bits double den kan hållas rätt så låg (*)
Dessutom så finns det sk extended double med 80-bitar vilket många FPUer använder idag internt.
Just för att undvika sådana fenomen som felpropagering (**).
Om du sedan konverterar en sådan 80-bit extended double till 32-bits float, så klipps bara 48 bitar bort

Här är en liten förklaring:
https://stackoverflow.com/questions/...ecision-number

(*) Det finns enormt mycket intressant att läsa och lära sig om sådant här, speciellt inom numerisk analys och den högre matematiken.
(**) Med felpropagering gällande flyttalsoperationer så menas att vid många flyttalsoperationer efter varandra så ökar felet i beräkningen. För tex tekniska, vetenskapliga och medicinska ändamål så kan man inte tolerera för stora fel i beräkningarna. Då kan det gå åt helvete. Om du konstruerar ett flygplan och du räknar med 32-bits float rakt igenom och det blir fel och flyplanet störtar så tror jag nog att din motivering med att din kod snurrade fortare inte imponerar på Luftfartsverket precis.

BTW: Ursäkta pekpinneattityden, men det enklaste är att du provar dig fram ett steg i taget. Och om du är säker på att 32-bitars float räcker dvs 7 signifikanta siffror, så är det väl bara att köra på det.

Jag vet att det här låter askrångligt när man inte satt sig in vad flyttalsberäkningar gör för något. Men även det går att lära sig efter hand. Jag skulle själv tycka att sälja en 32-bits CPU ihop med en FPU som bara klarar 32-bits floats, det måste vara en dålig affär idag. Med 7 signifikanta siffror kommer man inte långt.
Köparna kan inte vara många. Men det är klart att för tex grafik så är behovet inte större än så, eftersom varje pixel kan representeras av 30 bitar internt.

GNU har några projekt som håller på att ta fram numeriska bibliotek som har "godtycklig" precision, dvs enligt vad de påstår så kan man välja i runtime med vilken precision beräkningarna ska genomföras med. De kommer att få stor betydelse för att avgöra om en numerisk modell är tillräckligt pålitlig vad avser beräkningsfelet. Och att man kan få fler metoder att beräkna sådana faktorer som felpropagering och liknande. Dvs hur stora de är och vilka fallgropar man kan förvänta sig att hitta.
Många är kända idag, men det kan finnas fler.

OT: Ursäkta referenserna till Irondome etc, men sådana system är typexempel på där flyttalsberäkningarna är många och måste slutföras på en viss tid för att hinna ge svarseld.
Till viss del liknar lösningen avseende det numeriska den som Bofors Archer använder.
Vilka CPU/FPUer som ingår i de systemen det vet jag inte -- Kanske några dussin Pentium med Turbo-knapp, vad vet jag ? Eller kineser som räknar trigonometri med kulramar ?
Dessa system har bara några sekunder på sig att räkna ut missilens bana. Så snart raketmotorn har brunnit ut så övergår missilens bana till en kastparabel. Och den kan definieras ganska noggrant.
Plus minus 30 meter har jag fått i uppgift, men det kan fan lika gärna vara militärt skryt, propaganda eller äkta.

Ännu mera OT: Till er som ser att den programkod som ni skriver i C++ hamnar i en sk CPP-fil. Just extensionen CPP var i början ämnad åt C Pre Processor (output). Men det övergav man, och kallade dessa filer istället för C Plus Plus filer. I många programmeringskurser så utelämnar man mycket av hur man bygger headerfils-träd och preprocessorns användande och hur man gör detta rätt.
Preprocessorn är mycket kraftfull, och C++ vore inget språk alls om man inte tog tillvara allt man kan göra med den. Inte minst då när det gäller att binda ihop ett knippe headerfiler. Och att expandera typ-definitioner mm.
Det görs automatiskt javisst men den automatiken är det några glosögda akademiska programmerare som har totat ihop.
Ytterligare ännu mera OT: Och förresten är #ifdef -kommandot kompilatortillverkaren Borlands egen uppfinning istället för #if defined, likaså #undef Dåtidens PCs skärmar kunde bara visa 80 tecken horisonellt och man valde ett kortare kommando för att spara på horisontellt utrymme.

PS Men till skribenten shotor kan jag ju delvis ge rätt, tex Platt-TV men de är liksom ingen riktig flyttalsaritmetik inne i dessa. Men visst -- det fanns fördefinerade libs förr som hanterade pixelns data 24 bit åt gången. Men de expanderades först till 32 bit, operationen gjordes, sedan returnerades, sändes det beräknade värdet tillbaka, men de överskjutande 8 bitarna kapades bara bort.
Med 30 bits grafik så gjordes ungefär samma sak. Det var alltså mest en slags integer aritmetik bakom, inga flyttal alltså. DS
Det blev lite mycket okvalificerat svammel här, tänkte att det är väl någon som läser detta kanske och blir inspirerad. Aktiviteten här i detta ämne har varit lite väl låg ett tag här
Nu kanske jag har skrämt bort ännu fler ?

Inte så lätt för mig att lägga diskussionen på en lämplig nivå och som förstås av alla, typ
__________________
Senast redigerad av AnalAnalfabeten 2020-08-08 kl. 04:20.
Citera
2020-08-08, 23:06
  #24
Avstängd
Citat:
Ursprungligen postat av AnalAnalfabeten
"Chipet" är alltså FPUn som "mjukvaran" körs på.
Vilket värdeintervall förväntar du inom din programvara, tex exponent 10^-126 till 10^+127
eller ?

Hur ska jag kunna göra det om jag inte vet vilka prestanda FPUn har på din CPU ?
Jag vet ju inte om din "FPU" består av en massa kineser med kulramar ?
Du måste själv ta reda på vilka hastigheter du kan uppnå med din kod.
Kompilera en variant för float och en för double.
Och du ska mäta först och optimera sedan.
Tillverkaren har nog någonstans uppgifter av vad den ska klara av.
Är hastigheten inte tillräcklig för vad ditt inbyggda system måste klara av i responstider mm, så har du bara att välja en snabbare CPU/FPU - något annat val brukar inte finnas.
Ja i och för sig att du kan splitta beräkningarna på flera kärnor, om det går vill säga.
Och om du ändå vill använda 32-bits float, är du säker på att du kan tolerera felen i beräkningarna ?

Det är det jag skriver att många FPUer hanterar 64-bits double nästan lika bra som 32-bits float.
Fastän de är inbrända ihop med en 32-bit CPU så kan de räkna med fler bittar
Som jag skriver är 32-bits float nästan obsoleta nu. Med bara 7 signifikanta decimalsiffror i mantissan har du inte mycket att spela på faktiskt. Men det beror ju naturligtvis på vad ditt inbyggda system måste klara av att räkna med. Du kan ju i och för sig omvandla flyttalet till integers om det går att göra. Och att du inte behöver tex exponenten.
Bland annat på grund av att felpropageringen vid många aritmetiska operationer efter varandra är oacceptabelt stor för 32-bits floats, flyttal. Medans vid 64-bits double den kan hållas rätt så låg (*)
Dessutom så finns det sk extended double med 80-bitar vilket många FPUer använder idag internt.
Just för att undvika sådana fenomen som felpropagering (**).
Om du sedan konverterar en sådan 80-bit extended double till 32-bits float, så klipps bara 48 bitar bort

Här är en liten förklaring:
https://stackoverflow.com/questions/...ecision-number

(*) Det finns enormt mycket intressant att läsa och lära sig om sådant här, speciellt inom numerisk analys och den högre matematiken.
(**) Med felpropagering gällande flyttalsoperationer så menas att vid många flyttalsoperationer efter varandra så ökar felet i beräkningen. För tex tekniska, vetenskapliga och medicinska ändamål så kan man inte tolerera för stora fel i beräkningarna. Då kan det gå åt helvete. Om du konstruerar ett flygplan och du räknar med 32-bits float rakt igenom och det blir fel och flyplanet störtar så tror jag nog att din motivering med att din kod snurrade fortare inte imponerar på Luftfartsverket precis.

BTW: Ursäkta pekpinneattityden, men det enklaste är att du provar dig fram ett steg i taget. Och om du är säker på att 32-bitars float räcker dvs 7 signifikanta siffror, så är det väl bara att köra på det.

Jag vet att det här låter askrångligt när man inte satt sig in vad flyttalsberäkningar gör för något. Men även det går att lära sig efter hand. Jag skulle själv tycka att sälja en 32-bits CPU ihop med en FPU som bara klarar 32-bits floats, det måste vara en dålig affär idag. Med 7 signifikanta siffror kommer man inte långt.
Köparna kan inte vara många. Men det är klart att för tex grafik så är behovet inte större än så, eftersom varje pixel kan representeras av 30 bitar internt.

GNU har några projekt som håller på att ta fram numeriska bibliotek som har "godtycklig" precision, dvs enligt vad de påstår så kan man välja i runtime med vilken precision beräkningarna ska genomföras med. De kommer att få stor betydelse för att avgöra om en numerisk modell är tillräckligt pålitlig vad avser beräkningsfelet. Och att man kan få fler metoder att beräkna sådana faktorer som felpropagering och liknande. Dvs hur stora de är och vilka fallgropar man kan förvänta sig att hitta.
Många är kända idag, men det kan finnas fler.

OT: Ursäkta referenserna till Irondome etc, men sådana system är typexempel på där flyttalsberäkningarna är många och måste slutföras på en viss tid för att hinna ge svarseld.
Till viss del liknar lösningen avseende det numeriska den som Bofors Archer använder.
Vilka CPU/FPUer som ingår i de systemen det vet jag inte -- Kanske några dussin Pentium med Turbo-knapp, vad vet jag ? Eller kineser som räknar trigonometri med kulramar ?
Dessa system har bara några sekunder på sig att räkna ut missilens bana. Så snart raketmotorn har brunnit ut så övergår missilens bana till en kastparabel. Och den kan definieras ganska noggrant.
Plus minus 30 meter har jag fått i uppgift, men det kan fan lika gärna vara militärt skryt, propaganda eller äkta.

Ännu mera OT: Till er som ser att den programkod som ni skriver i C++ hamnar i en sk CPP-fil. Just extensionen CPP var i början ämnad åt C Pre Processor (output). Men det övergav man, och kallade dessa filer istället för C Plus Plus filer. I många programmeringskurser så utelämnar man mycket av hur man bygger headerfils-träd och preprocessorns användande och hur man gör detta rätt.
Preprocessorn är mycket kraftfull, och C++ vore inget språk alls om man inte tog tillvara allt man kan göra med den. Inte minst då när det gäller att binda ihop ett knippe headerfiler. Och att expandera typ-definitioner mm.
Det görs automatiskt javisst men den automatiken är det några glosögda akademiska programmerare som har totat ihop.
Ytterligare ännu mera OT: Och förresten är #ifdef -kommandot kompilatortillverkaren Borlands egen uppfinning istället för #if defined, likaså #undef Dåtidens PCs skärmar kunde bara visa 80 tecken horisonellt och man valde ett kortare kommando för att spara på horisontellt utrymme.

PS Men till skribenten shotor kan jag ju delvis ge rätt, tex Platt-TV men de är liksom ingen riktig flyttalsaritmetik inne i dessa. Men visst -- det fanns fördefinerade libs förr som hanterade pixelns data 24 bit åt gången. Men de expanderades först till 32 bit, operationen gjordes, sedan returnerades, sändes det beräknade värdet tillbaka, men de överskjutande 8 bitarna kapades bara bort.
Med 30 bits grafik så gjordes ungefär samma sak. Det var alltså mest en slags integer aritmetik bakom, inga flyttal alltså. DS
Det blev lite mycket okvalificerat svammel här, tänkte att det är väl någon som läser detta kanske och blir inspirerad. Aktiviteten här i detta ämne har varit lite väl låg ett tag här
Nu kanske jag har skrämt bort ännu fler ?

Inte så lätt för mig att lägga diskussionen på en lämplig nivå och som förstås av alla, typ

Lär dig fokusera på frågan...

Jag ser inga inbyggda system med 64 bitar, släpp dina extrema militära exempel, vanliga industriella tillämpningar är normen. 7 decimaler är ganska mycket för de flesta styrsystem och 32 bitars FPU verkar vara normen.

När jag läser om t.ex. simulink coder som genererar kod rekommenderas float eftersom det oftast räcker.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback