ArsLudica.org Forum

Effettua l'accesso o una nuova registrazione.

Inserisci il nome utente, la password e la durata della sessione.
Ricerca avanzata  

News:

Autore Topic: Ognuno ottimizza come può  (Letto 1710 volte)

Ziggybee

  • Administrator
  • Hero Member
  • *****
  • Offline Offline
  • Post: 8.383
  • Gamer Extraordinaire
    • Mostra profilo
Ognuno ottimizza come può
« il: Maggio 22, 2009, 19:48:39 »

Uno dei miei progetti sulle simulazioni in performance computing si stava arenando. Prontamente uno dei miei manager mi consiglia di consultare uno dei nostri massimi esperti in materia, un guru di fama nazionale su algoritmi di calcolo applicati (in particolare sulle AI, i simulatori e gli scacchi). Sono sempre un po' scettico quando si va ad interpellare sti grandi vecchi dell'informatica ma avendo poco tempo, mi sono affidato a lui.

Il tizio effettivamente è un genio. Ha tirato fuori un algoritmo in C++ che incorniciarlo è poco. Un monumento al performance computing e alla scrittura di codice robusto e portabile. Insomma, anche io ho imparato un sacco di cose.

Problema: noi lo dovevamo mettere in un contesto multiutente e distribuito... Le applicazioni web in C++ hanno smesso di scriverle agli albori degli anni 90 per manifesta inefficienza rispetto agli interpreti ed ai modelli di gestione della memoria managed. Si entra quindi a parlare di VM e chiedo consigli su come effettuare il porting e quale linguaggio avrebbe potuto dare i risultati migliori (da un po' di giorni mi chiedevo cosa sarebbe successo a fare un port in Erlang). Vengo messo a tacere con sufficienza:

"Caro, si vede che sei giovane, ma dai retta a me che ho esperienza su queste cose: se devi correre ti serve una Ferrari, mica un giocattolino!"

Abbozzo. Se vi siete mai trovati in un contesto aziendale in cui c'è uno che viene considerato iperesperto dal capo dei capi per pregressi accademici (che poi ho scoperto essere del tutto analoghi ai miei, che ho oltre 20 anni di meno) e meriti conquistati sul campo, sapete come vanno queste cose. Risolini da gente che si scagazza addosso quando i clienti gli fanno domande tecniche e cose del genere, solo perché voi siete quello giovane e li fate sentire a disagio gran parte delle volte. Abbozzo un po' piccato, anche perché il tipo tutto sommato è un grande (e ho già deciso di chiedergli un po' di dritte per una AI per gli scacchi con cui lavoro da un paio di annetti per hobby).

Torno in ufficio nel pomeriggio e (quasi dando per scontato che il mio orgoglio sarebbe stato ulteriormente ferito) porto tutto prima in Java e poi in C#. Erlang me lo devo rivedere bene e ci vorrebbe troppo. So un po' rosic ma è pur vero che ormai ho un'esperienza decennale su certe cose e me un po' me le sento a sensazione. Mi occupo di 3D e performance computing su linguaggi managed da prima di Java 3D ed ho una discreta esperienza su cosa si fa meglio e cosa si fa peggio con cosa.

La prima versione mi fa guadagnare un +40% su Java, che diventa un +50% quando alle ottimizzazioni per l'esecuzione fatte per il C++ sostituisco quelle più tipiche per fare calcolo intensivo su VM Sun (poche righe di codice cambiate, giusto per venire incontro alle prerogative della VM).

Provo su .NET, il codice con poche modifiche non algoritmiche (francamente penso sia impossibile migliorarlo, è un'implementazione talmente perfetta da essere inattaccabile) guadagna un +70%, che mantiene anche su Ubuntu 9 con Linux.

I test fatti fianco a fianco rispetto al C++ sono stati realizzati con tutte le ottimizzazioni e gli inlining necessari, utilizzando la build più efficiente valutata con la media di 10 sessioni di profiling, che poi erano corrispondenti al 100% rispetto a quelle proposte dal luminare per quell'architettura (che volete, so malfidato!)

Evidentemente le Ferrari non sono più quelle di una volta :)

In realtà era semplicemente un contesto con cui le VM vanno a nozze: decine di milioni di calcoli in virgola mobile al secondo, con prospettive di parallelizzazione molto spinta (non ancora implementata) e un sacco di traffico in memoria. Insomma, ogni context switch produce un'inefficienza ed evitarli il più possibile aiuta.

Sono rimasto un po' male perché l'espertone in questione è veramente un genio di cui se ne vedono pochi in giro, ma a volte trolla come un forsennato (è arrivato a tirare fuori delle leggende metropolitane anti Java e anti Microsoft che nemmeno i talebani della FSF conoscono ed interpretano così bene).

Insomma, ho imparato un sacco di cose, oggi. La più importante è che mantenere una mente aperta quando progetti fa sempre molto comdo! Non siamo evangelisti! :)
« Ultima modifica: Maggio 22, 2009, 19:50:32 da z.e.r.o »
Connesso
Matteo Anelli

Vazkor: "Altro che Apple TV"

StM

  • Administrator
  • Hero Member
  • *****
  • Offline Offline
  • Post: 9.424
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #1 il: Maggio 22, 2009, 23:01:17 »

Mi sono perso qualche passaggio, ma interessante ;D

E' normale che ogni volta che comincio un progetto nuovo io sia sommamente inefficente e ci metta un secolo perché cerco nuovi modi di fare le cose, anche se già con quelli che conosco ci impiegherei un tempo dignitoso? Voglio dire, a parte il caso in cui mi aprano un nuovo buc' di cul' per estenuazione :asd:, smetterò mai di fare così? ;D
Connesso

Ziggybee

  • Administrator
  • Hero Member
  • *****
  • Offline Offline
  • Post: 8.383
  • Gamer Extraordinaire
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #2 il: Maggio 24, 2009, 11:09:32 »

Secondo me fare come fai tu è molto salutare. Sempre che non ci metti troopo a decidere come fare :)

Quando vedo grandi professionisti che pretendono di fare le cose come le facevano 10-20 anni fa mi viene l'orticaria... Specie in informatica, dove 5 anni sono già un'era geologica. Poi ci sono le eccezioni, ma spesso una buona svecchiata farebbe parecchio bene :)
Connesso
Matteo Anelli

Vazkor: "Altro che Apple TV"

Monopoli

  • Hero Member
  • *****
  • Offline Offline
  • Post: 4.296
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #3 il: Maggio 24, 2009, 13:31:50 »

Sei bello :D
Connesso
Il mio blog agghiacciante
http://monopoliano.blogspot.com
E' Uscito! Compra qui: http://itunes.apple.com/us/album/crystal/id461134607

"Monopoli hai la voce da frocio ma sei un figo sull'Arsludicast."

Ziggybee

  • Administrator
  • Hero Member
  • *****
  • Offline Offline
  • Post: 8.383
  • Gamer Extraordinaire
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #4 il: Maggio 26, 2009, 12:08:00 »

Cmq monopozzolo non mi aspettavo un incremento così radicale, avevo intuito che c'era un sacco di context switch (e questo è male) ma non mi aspettavo di ridurre ad 1/3 i tempi di esecuzione del codice C++ nativo, profilato al massimo delle sue possibilità e compilato espressamente per quell'architettura hardware...

Mi era pure venuto un dubbio e ho provato a portare in C++ gli interventi che ho fatto sul codice managed (più che altro per ottimizzare stack ed heap del CLR), con risultati ovviamente disastrosi!

C'è da dire che lo switch /clr del compiler Microsoft sembra miracoloso, se scrivi C++ ANSI
Ora c'è un discreto incremento di prestazioni (dimezzo quasi i tempi) ed una compatibilità pressoché totale anche con Linux, usando Mono 2.0! :)
« Ultima modifica: Maggio 26, 2009, 12:11:33 da z.e.r.o »
Connesso
Matteo Anelli

Vazkor: "Altro che Apple TV"

Cherno

  • Redazione
  • Hero Member
  • *****
  • Offline Offline
  • Post: 3.829
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #5 il: Maggio 26, 2009, 13:48:07 »

Meno male che c'è ancora gente che sperimenta!

Ziggybee

  • Administrator
  • Hero Member
  • *****
  • Offline Offline
  • Post: 8.383
  • Gamer Extraordinaire
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #6 il: Maggio 26, 2009, 19:02:13 »

Meno male che c'è ancora gente che sperimenta!

Ci sono pure i lati negativi dell'usare direttamente il C++ managed.

La sintassi del C++ già è una trappola per niubbi, quella del C++ managed è semplicemente una sfida alla semantica del cervello umano.

Ora per distingure le variabili managed da quelle unmanaged ci sono due tipi di puntatori (rispettivamente identificate da "^" e dal classico "*"). Le prime si inizianizzano con la nuova direttiva gcnew. Cosa succede se poi nel codice mischi i due tipi di dati? La risposta è: dipende! Per esempio l'indirection & non funziona sul managed, quindi se hai di questi problemi ti devi smanettare le signature o boxare le variabili managed in quelle unmanaged (bene, ora però prova a farlo con un oggetto complesso, tipo uno scenegraph).

Poi la manutenzione del codice va allegramente a puttane. Un array managed è definito con un costrutto ad-hoc:

Codice: [Seleziona]
array<TIPO, NUM_DIMENSIONI> ^miaVar = gcnew array<Tipo, NUM_DIMENSIONI>(lunghDim1, lunghDim2, ..., lunghDimN)

Ovviamente non funziona per gli array jagged e la signature non è sintetica come il classico **miaVar del C++.

Per chi fosse curioso, un array Jagged in Managed C++ lo gestisci come in ActionScript:

Codice: [Seleziona]
array<array<TIPO> ^> ^miaVar = gcnew array<array<TIPO> ^>(DIM1);

//e poi per ogni riga, sei costretto a fare:

miaVar[i] = gcnew array<TIPO>(DIM2i);

Cazzo è, Klingon?

Apprezzo il fatto che il codice C++ funziona anche senza modifiche, ma di certo si poteva fare di meglio.

Tra parentesi prima di .NET 2 era molto peggio, con decoratori tipo __gc da mettere su ogni dichiarazione di variabile managed e stronzate simili.

La cosa bella è che uno pensa: ah che figata, allora le vecchie variabili ed il codice dichiarato canonicamente è mantenuto nativo e Unsafe (dove si possono fare un sacco di porcate). Assolutamente no: tranne poche eccezioni (se usi __asm, jumpy a mano o smanetti coi returnAddress) parliamo sempre di codice che viene tutto compilato in CLR con i limiti del caso: la distrinzione serve giusto per evitare che il programmatore commetta errori ???. Insomma la tecnica è rincoglionirlo sino a renderlo inoffensivo.

La cosa esilarante è che non sono funzionalità in più: anche in C# puoi mixare codice safe ed unsafe ma con l'autoboxing a compile time (tanto alla fine è tutto CLR) non devi farti due palle così a capire come maneggiare un handle (è safe? unsafe?) o ad impacchettare dati da spedire ad una libreria nativa nel modo corretto senza che il compilatore si scazzi...
Connesso
Matteo Anelli

Vazkor: "Altro che Apple TV"

Cherno

  • Redazione
  • Hero Member
  • *****
  • Offline Offline
  • Post: 3.829
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #7 il: Maggio 26, 2009, 19:31:04 »

Proprio per questi motivi quando ho dovuto scegliere se utilizzare il codice managed con visual c++ 2008, ho preferito togliere la clausola /clr e fare tutto come ho sempre fatto. Il punto è che effettivamente dei vantaggi li ha, quindi bisogna valutare di caso in caso come giustamente hai fatto tu.

Ziggybee

  • Administrator
  • Hero Member
  • *****
  • Offline Offline
  • Post: 8.383
  • Gamer Extraordinaire
    • Mostra profilo
Re: Ognuno ottimizza come può
« Risposta #8 il: Maggio 27, 2009, 10:58:53 »

Alla fine per lavorare con .NET abbiamo riconvertito tutto in C#, non è complicatissimo rifattorizzare e il codice risulta molto più conciso e leggibile.

Le prestazioni sono le stesse, con lo svantaggio che in C++ Managed le puoi peggiorare moltissimo se smanetti (male) con le opzioni di ottimizzazione. Un uso incauto può impedire al codice di essere managed e causa slowdon (è un po' come se si utilizzassero le vecchie Java Native Interfaces di Java) pazzeschi.

Un'altra cosa assurda è l'impatto del codice di debug: ti ritrovi l'eseguibile zeppo di hook di debug e con delle prestazioni veramente penalizzate (-27% secondo il profiler di Team System). Purtroppo è l'unico modo visto che il codice managed deve essere fatto coesistere con la potenzialità di codice unmanaged che non ha un supporto molto trasparente al debugging.

Alla fine non mi meraviglia che il C++ Managed sia così impopolare.
Connesso
Matteo Anelli

Vazkor: "Altro che Apple TV"
 

Pagina creata in 0.016 secondi con 15 interrogazioni al database.