|
|
|
|
Strumenti |
07-08-2016, 20:49 | #41 |
Bannato
Iscritto dal: Nov 2014
Messaggi: 292
|
Ritengo che una singola MOV da o verso la memoria sia assai più lenta di una IDIV.
Che un compilatore trasformi una divisione in uno shift quando il divisore è potenza di due è normale, credo che qualunque architettura riesca a fare uno shift in un solo colpo di clock. Che motivazioni riportava la roba che hai letto circa questa lentezza? |
07-08-2016, 22:09 | #42 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
|
@fano: passi la moltiplicazione per potenze di due, ma lo shift a destra NON è equivalente alla divisione quando hai a che fare con interi con segno. Quindi... OCCHIO!
Riguardo ai tuoi problemi con quel pezzo di codice, sarebbe più utile un dump del binario generato.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
08-08-2016, 08:48 | #43 | ||||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Quote:
Quote:
Possibile però che i processori moderni abbiano ancora questo problema? Quote:
Mah io resto nel dubbio che fare CDQ + SAR invece che semplicemente IDIV (come fa il compilatore C#) faccia poi tutta sta differenza... tu cosa ne dici? Quote:
Comunque ho cambiato il codice facendo una Push dentro ESP non ho capito perché ho dovuto "muovere" lo stack di 4 se no non funzionava, comunque ottengo il valore coretto "-42.0" peccato che l'asserzione fallisce dicendo che "-42.0" != "-42.0". Codice:
// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); //XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true); //XS.Set(ESP, 0x80000000); XS.Add(ESP, 4); XS.Push(0x80000000); XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true); XS.SSE.XorPS(XMM0, XMM1); XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 08-08-2016 alle 09:03. |
||||
08-08-2016, 13:51 | #44 | ||
Bannato
Iscritto dal: Nov 2014
Messaggi: 292
|
Quote:
Quote:
|
||
08-08-2016, 13:55 | #45 | |
Bannato
Iscritto dal: Nov 2014
Messaggi: 292
|
Quote:
Gli ho solo dato un'occhiata, ma il tipo mi sembra riuscire nell'implementazione di un divisore senza usare microcodice, solo una rete combinatoria. |
|
08-08-2016, 15:23 | #46 | |
Senior Member
Iscritto dal: Apr 2010
Città: Leuven
Messaggi: 667
|
Quote:
Il circuito combinatorio di quel documento illustra in linea di principio come si fa la divisione con un circuito combinatorio, ma quella soluzione è troppo lenta per i processori moderni. Attenzione che a disegnare i blocchettini negli schemi non ci vuole niente, poi però i segnali si devono propagare in un mezzo fisico e li escono le magagne e ciò che funziona su carta funziona sempre meno bene (da cui scaturisce la minchiata che ho scritto nella mai firma, che in realtà tanto minchiata non è...). [edit] Wikipedia riporta anche quest'altro metodo: https://en.wikipedia.org/wiki/Divisi...m#SRT_division ma non so se effettivamente è ancora usato da Intel o no. Le look up table velocizzano molto i calcoli ma quanto spazio occupano sul silicio!
__________________
L'elettronica digitale non esiste, è solo elettrotecnica con interruttori piccoli! Ultima modifica di ingframin : 08-08-2016 alle 15:28. |
|
08-08-2016, 15:37 | #47 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Allego questo PDF come si può vedere per processori vecchi DIV e MUL potevano anche occupare 46 cicli (!) mentre SHL / SHR ne occupano quasi sempre solo 1:
http://www.agner.org/optimize/instruction_tables.pdf quindi sì sembrerebbe un'ottimizzazione che ha senso fare anche con le CPU di oggi mi chiedo perché C# non lo faccia non sembra troppo complessa da implementare o mi perdo qualcosa? Comunque tornando al mio problema: Codice:
// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); //XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true); //XS.Set(ESP, 0x80000000); XS.Add(ESP, 4); XS.Push(0x80000000); XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true); XS.SSE.XorPS(XMM0, XMM1); XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); Quando il valore era una constante scritta nella sezione "DATA" funzionava alla perfezione...
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
08-08-2016, 15:50 | #48 | |
Bannato
Iscritto dal: Nov 2014
Messaggi: 292
|
Quote:
|
|
08-08-2016, 15:52 | #49 | |
Senior Member
Iscritto dal: Apr 2010
Città: Leuven
Messaggi: 667
|
Quote:
Sul perché c# non lo faccia non so che rispondere Sei sicuro che il codice compilato dal JIT non faccia la sostituzione? Tieni pure conto che sostituire una divisione intera per due con uno shift a destra ti fa perdere il resto della divisione. Quindi non sono sicuro al 100% che sia una cosa sempre fattibile.
__________________
L'elettronica digitale non esiste, è solo elettrotecnica con interruttori piccoli! |
|
08-08-2016, 16:23 | #50 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Il C++ faceva questa ottimizzazione, C# apparentemente no! Ma appunto non sono cosa intenda Visual Studio con quel "disassemble"... sinceramente avrebbe più senso se mostrasse l'IL invece che ASM x86!
Beh in quel caso particolare io non necessitavo del resto quindi lo shift era perfettamente lecito come sostituto della divisione
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
08-08-2016, 20:50 | #51 | |
Bannato
Iscritto dal: Nov 2014
Messaggi: 292
|
Quote:
Va da se' che e' un problema per il compilatore e che il programmatore C# non se ne deve minimamente preoccupare. |
|
09-08-2016, 07:27 | #52 | |
Bannato
Iscritto dal: Nov 2014
Messaggi: 292
|
Quote:
Ultima modifica di 71106 : 09-08-2016 alle 07:29. |
|
09-08-2016, 09:03 | #53 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Comunque in caso di resto di divisione per 2 credo - di nuovo - ci sia qualche ottimizzazione possibile invece che fare la IDIV (o l'istruzione apposita per ottenere il resto che in x86 ci sarà sicuramente ) forse un & 2?
In ogni caso assembler mi sta facendo totalmente impazzire! Ricapitoliamo sto cercando di negare un valore floating point faccio 2 test la negazione di un numero positivo che mi torna lo stesso numero negato (42 ==> -42) e l'inverso (-42 ==> 42). Questa è la prima versione che funziona perfettamente: Codice:
// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true); XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true); XS.SSE.XorPS(XMM0, XMM1); XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); La seconda versione è analoga semplicemente la constante è dichiarata dentro il metodo Execute() (poco prima del codice che vedete) invece che essere in un file a caso: l'unica differenza è che nel kernel __floatsignbit si trova non più in fondo in una posizione random sempre dentro la stessa sezione data. Ebbene in questo caso come per magia (!) il primo test funziona, ma il secondo no... dicendo - senza alcuna vergogna che -42.0 != -42.0 Questa è la III versione in cui la constante è "pushata" nello stack: Codice:
// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.Add(ESP, 4); XS.Push(0x80000000); XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true); XS.SSE.XorPS(XMM0, XMM1); XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); Prima che vi emozionate tutti lo so che gli operatori == e != non funziona con i float ed infatti uso questa routinetta fornitami gentilemente dalla Microsoft per testare se sono uguali ha sempre funzionato per tutti i test che ho fatto (e funziona anche per -42.0 quando la constante è dichiarata dentro CosmosAssembler.cs): Codice:
/* The single== equality operator is so imprecise to not be really ever useful we should be happy if the two values are "similar" */ private static bool SinglesAreEqual(Single left, Single right) { // Define the tolerance for variation in their values Single difference = (Single) Math.Abs(left * .00001); if (Math.Abs(left - right) <= difference) return true; else return false; }
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
24-08-2016, 13:07 | #54 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Con oggi sono entrato ufficialmente nel gruppo direttivo di Cosmos "CoreDev - The Inner Sanctum":
https://github.com/orgs/CosmosOS/teams/coredev Beh devo dire che è una bella soddisfazione Ovviamente non è che mi poteva andare bene non riuscivano ad aggiungermi Github diceva che io NON esisto che ho conflitti con sto tizio: https://github.com/undefined Poi si scopre qual era il problema? Il mio userId di github è fanoI (con la i), ma loro scrivevano fanol (con la elle!) per forza che non mi arrivava nessuna notifica Detto questo abbiamo deciso quali sono i piani dopo il merge del mio lavoro sui float (e la chiusura di più PR possibili) e il termine del lavoro sul memory manager (RAT) passeremo da .NET a .NET core questo dovrebbe permetterci di avere molti, molti meno plug da sviluppare così da poterci concentrare sul vero lavoro che è scrivere il kernel in C#! Si è subito però scatenato un dibattito compiliamo anche IL2CPU con .NET core? Temiamo che ci saranno problemi con reflection e feature avanzate dato che .NET core è ancora immaturo. D'altro canto il grosso vantaggio sarebbe che usando .NET core potremmo molto più facilmente rendere possibile compilare Cosmos su MacOS e su Linux! Voi cosa ne pensate?
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
27-08-2016, 10:13 | #55 | |
Senior Member
Iscritto dal: May 2004
Messaggi: 390
|
Quote:
"divisione per 2 x86: sar eax, 1" francamente non ricordo quasi nulla dell'argomento per cui non garantisco che possa in effetti essere utile al discorso. EDIT: sorry ho letto di fretta a te interessava il discorso del resto. Come non detto.
__________________
--In Siberia non sono tutte gnocche... ma tante si... Ultima modifica di Shirov : 27-08-2016 alle 10:33. |
|
27-08-2016, 14:17 | #56 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Il trucco vale per tutti i multipli di 2 quindi: divisione per 4 == shift a destra di 2!
Per il modulo sempre per multipli di 2: x % 2n == x & (2n - 1) quindi per esempio: x % 4 == x & 3 https://en.wikipedia.org/wiki/Modulo_operation Comunque mi sono installato la release 1.0 di .Net Core e la buona notizia è che la / 2 è ora ottimizzata con uno shift come atteso! S'aggiunga: Ottimizzazione divisione con costanti. (Che casino ) Io mi sono predisposto già a compilare Cosmos con .Net Core, ma mi sa che i lavori sul gestore di memoria RAT si protrarranno per le lunghe
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 29-08-2016 alle 14:49. |
28-08-2016, 21:54 | #57 |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Edit.
|
23-10-2016, 17:25 | #58 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Allora vi aggiorno un po':
1. RAT è stato integrato nel main branch e dopo i primi bachetti (fixati) ora Cosmos ha il suo bravo gestore di memoria 2. L'integrazione di Cosmos col Net Core runtime procede su un suo branch separato (https://github.com/CosmosOS/Cosmos/tree/NetCore) il grosso dei problemi che stiamo avendo è dovuto all'immaturità della cosa sembra Visual Studio si incasini tra PCL, Net Core, Net Standard... se non ci capisce lui figurarsi noi E per quanto riguarda me? Visto che c'è grande richiesta di fare grafica su Cosmos e si stanno già forkando 13 GUI diverse () si è deciso che doveva esserci una soluzione pulita e funzionante dentro Cosmos e che me ne sarei occupatp io. Questa è la nostra idea: https://github.com/fanoI/Cosmos/wiki...Graphic-Revamp ma prima di arrivarci abbiamo un altro grosso problema ci sono attualmente 2 driver in Cosmos per pilotare la VGA: 1. VGADriver modalità testuale e modalità grafica fino a 320x200@256 colori 2. VBEDriver modalità grafica fino a 1600x1200@truecolor Hanno ambedue dei problemini il primo manco tanto un problemino: non funziona proprio! Il secondo non è davvero un driver VBE, ma è l'implementazione di VBE secondo Bochs quindi non è la cosa vera che dovrebbe andare su tutte le schede video dal 2000 in poi... (a parte il nome VBE funziona però! Ma già non funziona su VmWare l'emulatore più diffuso quindi non serve a nulla quel driver ) Il driver VGA è questo: https://github.com/CosmosOS/Cosmos/b...s/VGAScreen.cs che sembra grosso modo derivare da questo codice C: http://files.osdev.org/mirrors/geeze...aphics/modes.c Il mio kernel di test fa semplicemente questo: Codice:
VGA.SetGraphicsMode(ScreenSize.Size320x200, ColorDepth.BitDepth8); VGA.SetPixel(42, 42, 0x000003); // 3 dovrebbe essere il colore "ciano" Avere due possibili driver (uno solo avrebbe girato a run time) era interessante anche per capire che l'idea di Canvas era veramente fatta bene cioè per esempio ho VmWare e disegno un rettangolo con lo sfigato driver VGA poi uso Bochs e disegno lo stesso rettangolo con il driver VBE che non è VBE e sono a cavallo! Farlo solo con uno rischierei di non avere una cosa universale... quindi magari scriveremo un driver per la GPU di VmWare e scopriamo che Canvas non era veramente venuto. Avete qualche idea?
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 23-10-2016 alle 17:27. |
24-10-2016, 05:53 | #59 | ||
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26107
|
Ne abbiamo parlato in privato, ma appena posso mi smazzo il lungo PVT e ti rispondo.
Rispondo soltanto a questo, che avevo perso di vista: Quote:
In generale in quest'ultimo caso vale la seguente: Codice:
x / 2^n = (x + (2^n - 1 if x < 0 else 0)) >> n Quote:
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||
24-10-2016, 10:41 | #60 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Mah mi chiedo alla fine, ma vale la pena davvero cambiare le divisioni con gli shift e i moduli con gli and se ci sono tutte queste trappole? Perché la CPU non può farsele da sole queste cose (magari quelle può moderne lo fanno pure, ma si ottimizza per il caso più generico... il 486)?
Nei test che feci ho visto che anche Visual Studia fa questi "giochini" oltre che GCC e Clang quindi sicuramente è un ottimizzazione "benefica" però mi fa pensare sembra così semplice la divisione Ritornando alla VGA devo forse settare la palette? Ovvero la palette di default dopo il boot mappa tutti i 256 possibili valori sul nero?
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:27.