PDA

View Full Version : JAVA più lento del C++. Ma quanto?


Pagine : 1 [2]

cionci
03-01-2008, 17:11
Con il multi-threading te simuli questo comportamento, ma in realtà i programmi sotto girano sempre in maniera sequenziale se hai a disposizione un solo processore fisico..
Anche per il message passing puoi fare lo stesso discorso...

Unrue
03-01-2008, 17:12
I problema è che i thread sono fatti per le architetture a memoria condivisa...al contrario i super computer non lo sono...per questo il message passing viene in aiuto ;)

MM, questo non mi torna molto. MPi di per sè crea e gestisce un thread che vive su ogni processore. Addirittura, se usi un'altra libreria parallela che è Charm++, usi i cosiddetti "chare", che altro non sono che thread sui vari processori, ed in quel caso puoi avenre anche diversi su di uno :confused:

variabilepippo
03-01-2008, 17:14
Non mi pare di averlo mai detto


All'affermazione corretta (http://www.hwupgrade.it/forum/showpost.php?p=20360266&postcount=216) di TigerShark:


E che c'azzecca il Message Passing con la gestione di + processori?
Il Message Passing è utilizzato, ma non solo, per la comunicazione nei cluster server.
Esso se non erro viene utilizzato anche in qualche SO per la comunicazione tra i thread.
Ma alla fine è solo un protocollo per lo scambio di dati, non ha nulla a che vedere con l'elaborazione parallela vera e propria


hai risposto con


Perdonami ma.... hai letto bene a cosa serve quella libreria? Venire a dire che MPi con l'elaborazione parallela non c'entra nulla, quando la stragrande maggioranza di applicazioni parallele la usa, mi pare che sia una grossissima fesseria Gli algoritmi seriali genralmente sono parallelizzati proprio con quella libreria...


MPI è un'interfaccia utilizzabile *ANCHE* per implementare sistemi di calcolo distribuito (un concetto diverso rispetto ad "elaborazione parallela"), ma non esiste un nesso biunivoco tra "elaborazione parallela" e MPI (come ribadito da più fonti). Infatti il message passing viene impiegato anche nei microkernel, nell'IPC ed in tanti altri casi DIVERSI dal calcolo distribuito.

Unrue
03-01-2008, 17:17
Dire che una libreria è usata principalmente per quello scopo è bel diverso dal dire che c'è una relazione biunivoca tra la libreria e lo scopo stesso.. Il che equivarrebbe a dire che la libreria in questione è stata costruita SOLO per quello. Cosa che non ho mai affermato. Mi pare che si stia cercando il cosiddetto pelo nell'uovo..

E' poi che MPI sia usato principalmente per il calcolo distribuito è un dato di fatto, non vedo cosa tu abbia da obbiettare..

cionci
03-01-2008, 17:17
MM, questo non mi torna molto. MPi di per sè crea e gestisce un thread che vive su ogni processore.
Certo un thread locale a quel processore, ma che non può comunicare con un altro thread locale ad un altro processore perché l'architettura dei supercomputer non è a memoria condivisa ;)

cionci
03-01-2008, 17:19
ed in tanti altri casi DIVERSI dal calcolo distribuito.
Sì, infatti viene usato per implementare l'IPC nei sistemi operativi distribuiti...oppure come primitiva di comunicazione nei cluster.

Unrue
03-01-2008, 17:24
Certo un thread locale a quel processore, ma che non può comunicare con un altro thread locale ad un altro processore perché l'architettura dei supercomputer non è a memoria condivisa ;)

Continua a non tornarmi. In un singolo nodo di un supercomputers, possono esserci ad esempio 8 processori. Ebbene, la memoria globale del supercomputer non è condivisa ok, ma quella del nodo si. Quindi in teoria potrei usare thread per fare comunicazioni intranodo. Forse il message passing si attiva quando è richiesta la comunicazione tra nodi diversi?

cionci
03-01-2008, 17:30
Continua a non tornarmi. In un singolo nodo di un supercomputers, possono esserci ad esempio 8 processori.
Non è detto, i processori vettoriali operano praticamente sempre su memoria non condivisa che io sappia.
Se sono processori x86 o Risc tradizionali allora sì.
Ebbene, la memoria globale del supercomputer non è condivisa ok, ma quella del nodo si. Quindi in teoria potrei usare thread per fare comunicazioni intranodo. Forse il message passing si attiva quando è richiesta la comunicazione tra nodi diversi?
Se la memoria del nodo è condivisa potresti usarla per la comunicazione fra i thread, ma probabilmente non si usa per mantenere una certa uniformità in modo da non dover trattare diversamente thread locali tra loro e thread remoti.

Unrue
03-01-2008, 17:39
Non è detto, i processori vettoriali operano praticamente sempre su memoria non condivisa che io sappia.
Se sono processori x86 o Risc tradizionali allora sì.

Se la memoria del nodo è condivisa potresti usarla per la comunicazione fra i thread, ma probabilmente non si usa per mantenere una certa uniformità in modo da non dover trattare diversamente thread locali tra loro e thread remoti.

Pensandoci meglio non sono mica più così sicuro che la memoria nel nodo sia condivisa. Probabilmente dipende dal supercompuer in questione. Ora però mi fai venire una curiosità: perchè i threads non possono operare con architetture a memoria distribuita?

cionci
03-01-2008, 17:48
Perché la comunicazione fra i thread avviene attraverso la memoria ;) Infatti thread appartenenti allo stesso processo vedono la stessa memoria...
Ovviamente se i processori distinti sui quali girano non hanno memoria condivisa allora non possono comunicare ;)

Unrue
03-01-2008, 17:54
Perché la comunicazione fra i thread avviene attraverso la memoria ;) Infatti thread appartenenti allo stesso processo vedono la stessa memoria...
Ovviamente se i processori distinti sui quali girano non hanno memoria condivisa allora non possono comunicare ;)

Ok, allora guarda gua

http://charm.cs.uiuc.edu/manuals/html/charm++/manual.html

Questa è Charm++ un'altra libreria spesso usata con i supercomputers che fa un pesante uso di threads. Leggendo il manuale, almeno per adesso, non ho visto relazioni con il message passing. Allora come fanno i threads a comunicare tra loro ?:confused:

^TiGeRShArK^
03-01-2008, 17:55
Pensandoci meglio non sono mica più così sicuro che la memoria nel nodo sia condivisa. Probabilmente dipende dal supercompuer in questione. Ora però mi fai venire una curiosità: perchè i threads non possono operare con architetture a memoria distribuita?
Ogni thread va elaborato da un processore fisico/logico...
Se fai girare thread diversi in macchine che non condividono la stessa memoria (come ad esempio ogni macchina componente il cluster) allora devi ovviamente usare dei meccanismi di comunicazioni per scambiare i dati elaborati, siano essi meccanismi di messagge passing o ad esempio work units similari a quelle del folding@home (che, sinceramente, non ho idea su cosa siano basate).
Su una macchina a memoria condivisa invece non hai alcuna necessità di scambiare i dati dato che i thread hanno completamente a disposizione tutta la memoria della macchina, al massimo potranno avere prestazioni un pò inferiori nel caso in cui i dati da elaborare si trovino nei moduli di memoria direttamente connessi agli altri processori, e quindi le latenze sarebbero + elevate (ovviamente tralasciando il distinguo tra bus point-to-point, come l'HT o bus condiviso, quale il classico FSB, e la presenza di dati modificati nella cache di un processore che ancora devono essere scritti nella memoria RAM).

Unrue
03-01-2008, 18:03
Su una macchina a memoria condivisa invece non hai alcuna necessità di scambiare i dati dato che i thread hanno completamente a disposizione tutta la memoria della macchina, al massimo potranno avere prestazioni un pò inferiori nel caso in cui i dati da elaborare si trovino nei moduli di memoria direttamente connessi agli altri processori, e quindi le latenze sarebbero + elevate (ovviamente tralasciando il distinguo tra bus point-to-point, come l'HT o bus condiviso, quale il classico FSB, e la presenza di dati modificati nella cache di un processore che ancora devono essere scritti nella memoria RAM).

Okk, mi torna ;)

sottovento
03-01-2008, 18:18
Non credo assolutamente ;)
Praticamente nel 90% dei casi i passaggi si fanno per riferimento o per puntatore...se lo fai per copia sei un masichista ;)

void messageGot (Telegram &telegram);

Prima sei andato a sfruttare una caso (tante classi piccole) in cui il C++ era svantaggiato perché deallocavi subito, tra l'altro a mano...
Con una politica di deallocazione più furba il C++ sarebbe tornato nuovamente in testa,,,

Qui ti voglio! ;)
Specificata cosi', ogni programmatore Java sa gia quel che fare, e sa che telegram e' valido per ogni tipo di elaborazione che gli salta in mente.

Ma... e' lo stesso per il programmatore C++? Assolutamente no!
Telegram potrebbe essere una variabile locale, nel metodo di chiamata del dispatcher, giusto?

Come fai a saperlo? Se non te lo dice qualcuno, NON LO PUOI SAPERE.

A questo punto, aggiungo un tassello: ho ricevuto questo telegramma e lo devo, ovviamente, elaborare.
L'elaborazione e' affidata ad un altro thread, per motivi di efficienza. Devo quindi fare una push dell'oggetto in una coda, il thread lo prelevera' e lo elaborera'.
Sei costretto, in C++, a fare una copia! :D
Altrimenti, potrebbe essere che sei efficiente ma, sorry, vai in crash :D

Java ovviamente non fara' alcuna copia, tirera' dritto e saremo tutti sicuri che funziona correttamente. In C++ non potrai essere sicuro, ed avrai anche paura di generare dei leak!

cionci
03-01-2008, 18:41
Qui ti voglio! ;)
Specificata cosi', ogni programmatore Java sa gia quel che fare, e sa che telegram e' valido per ogni tipo di elaborazione che gli salta in mente.

Ma... e' lo stesso per il programmatore C++? Assolutamente no!
Telegram potrebbe essere una variabile locale, nel metodo di chiamata del dispatcher, giusto?

Come fai a saperlo? Se non te lo dice qualcuno, NON LO PUOI SAPERE.

Non ho capito :confused: Fammi un'esempio...

A questo punto, aggiungo un tassello: ho ricevuto questo telegramma e lo devo, ovviamente, elaborare.
L'elaborazione e' affidata ad un altro thread, per motivi di efficienza. Devo quindi fare una push dell'oggetto in una coda, il thread lo prelevera' e lo elaborera'.
Sei costretto, in C++, a fare una copia! :D
Altrimenti, potrebbe essere che sei efficiente ma, sorry, vai in crash :D

Java ovviamente non fara' alcuna copia, tirera' dritto e saremo tutti sicuri che funziona correttamente. In C++ non potrai essere sicuro, ed avrai anche paura di generare dei leak!
Certo...ma questo dovrebbe giustificare prestazioni migliori da parte di Java ?
Comunque stai ricadendo nuovamente sul garbage collector...se io uso un garbage collector in C++ posso copiare quanti riferimenti voglio ;)

sottovento
03-01-2008, 19:46
Non ho capito :confused: Fammi un'esempio...


In generale, quando si implementano queste architetture in C++ (beh, sono delle callback) i metodi sono del tipo:

void messageGot (Telegram *telegram);

oppure, come hai scritto:

void messageGot (Telegram &telegram);

Domanda: qual e' la durata della vita di questo oggetto?
Questo oggetto e' stato allocato per me: lo devo deallocare?
Se non lo devo deallocare, chi lo dealloca?
L'oggetto e' ancora valido al termine della MIA esecuzione? In pratica, come ho scritto nell'esempio che seguiva, posso scrivere:
coda.push (telegram)
oppure e' meglio infilarci una copia?


Certo...ma questo dovrebbe giustificare prestazioni migliori da parte di Java ?
Comunque stai ricadendo nuovamente sul garbage collector...se io uso un garbage collector in C++ posso copiare quanti riferimenti voglio ;)

Certo, e' ovvio che vado ad insistere proprio li', perche' e' quello che puo' fare la differenza, e la puo' fare senza che io ne sappia niente.
Esistono del garbage collector per C++ ma sono limitati, poiche' in C++ esiste un'algebra dei puntatori. Cmq se ci metti un garbage collector, allora siamo nel gruppo dei linguaggi "managed" ;)

Cionci: se pubblico un OT mi censuri? Certe volte ci sono notizie che vanno condivise ;)

cionci
03-01-2008, 21:22
In generale, quando si implementano queste architetture in C++ (beh, sono delle callback) i metodi sono del tipo:

void messageGot (Telegram *telegram);

oppure, come hai scritto:

void messageGot (Telegram &telegram);

Domanda: qual e' la durata della vita di questo oggetto?
Questo oggetto e' stato allocato per me: lo devo deallocare?
Se non lo devo deallocare, chi lo dealloca?
L'oggetto e' ancora valido al termine della MIA esecuzione? In pratica, come ho scritto nell'esempio che seguiva, posso scrivere:
coda.push (telegram)
oppure e' meglio infilarci una copia?

In generale l'oggetto passato per riferimento non lo deve deallocare nessuno...sicuramente non dentro messageGot...
Con il puntatore dipende dall'architettura che scegli di implementare.

Certo, e' ovvio che vado ad insistere proprio li', perche' e' quello che puo' fare la differenza, e la puo' fare senza che io ne sappia niente.
Esistono del garbage collector per C++ ma sono limitati, poiche' in C++ esiste un'algebra dei puntatori. Cmq se ci metti un garbage collector, allora siamo nel gruppo dei linguaggi "managed" ;)

No, è sempre C++...se il Garbage Collector si può implementare in C++ perché diventerebbe Managed ?
Cionci: se pubblico un OT mi censuri? Certe volte ci sono notizie che vanno condivise ;)
Non credo :D

tomminno
03-01-2008, 21:36
In generale, quando si implementano queste architetture in C++ (beh, sono delle callback) i metodi sono del tipo:

void messageGot (Telegram *telegram);

oppure, come hai scritto:

void messageGot (Telegram &telegram);

Domanda: qual e' la durata della vita di questo oggetto?


Sicuramente almeno fino all'uscita di messageGot.
Se vuoi usarlo fuori dal metodo devi farne una copia in una variabile locale.

Cosa che in realtà dovrebbe essere bene fare altrimenti qualcuno dall'esterno della classe potrebbe modificare il contenuto di una variabile magari privata.
Sai che bell'incapsulamento.


Questo oggetto e' stato allocato per me: lo devo deallocare?
Se non lo devo deallocare, chi lo dealloca?


Essendo un riferimento non deve nemmeno passarti per la mente di deallocarlo ;)


L'oggetto e' ancora valido al termine della MIA esecuzione? In pratica, come ho scritto nell'esempio che seguiva, posso scrivere:
coda.push (telegram)
oppure e' meglio infilarci una copia?


generalmente è meglio mettere puntatori nei contenitori STL.
Con il codice:

coda.push (telegram);

metti nel contenitore una copia dell'oggetto telegram.


Certo, e' ovvio che vado ad insistere proprio li', perche' e' quello che puo' fare la differenza, e la puo' fare senza che io ne sappia niente.
Esistono del garbage collector per C++ ma sono limitati, poiche' in C++ esiste un'algebra dei puntatori.


"Che cavolo stai dicendo Willy?"
I puntatori hanno tutti la stessa dimensione 32 o 64 bit a seconda dell'architettura, l'unica eccezione è per i puntatori a metodo che a seconda del compilatore possono arrivare ad occupare anche a 20 byte.

tomminno
03-01-2008, 21:38
In generale l'oggetto passato per riferimento non lo deve deallocare nessuno...sicuramente non dentro messageGot...


Un riferimento dovrebbe essere deallocato esclusivamente dal compilatore.
Penso che non ci sia cosa peggiore in C++ che passare il riferimento di qualcosa allocato dinamicamente.
Quello si che può portare ad errori a runtime difficilmente comprensibili.

cionci
03-01-2008, 21:42
Un riferimento dovrebbe essere deallocato esclusivamente dal compilatore.
Penso che non ci sia cosa peggiore in C++ che passare il riferimento di qualcosa allocato dinamicamente.
Quello si che può portare ad errori a runtime difficilmente comprensibili.
Chiaro...ma volevo sottolineare che c'è la possibilità di farlo ;) Infatti ho scritto che generalmente non lo deve deallocare nessuno...

marco.r
03-01-2008, 22:30
No, è sempre C++...se il Garbage Collector si può implementare in C++ perché diventerebbe Managed ?

E' una questione che mi incuriosisce da un po' e non ho mai avuto una risposta chiara: cosa si intende per linguaggio Managed ? Mi risulta che il termine sia stato coniato da Microsoft per indicare quei linguaggi che girano all'interno della framework .NET, ma vedo che e' spesso usato in contesti piu' generali. Ma allora che caratteristiche deve avere ? Avere un GC ? (Ma allora anche il C++ potrebbe esserlo), girare in una VM (quindi sarebbe da escludere Java compilato con gcj) ? Altro ?

marco.r
03-01-2008, 22:36
Un riferimento dovrebbe essere deallocato esclusivamente dal compilatore.
Penso che non ci sia cosa peggiore in C++ che passare il riferimento di qualcosa allocato dinamicamente.
Quello si che può portare ad errori a runtime difficilmente comprensibili.

Perche' ? I riferimenti rendono piu' chiara l'ownership dell'oggetto che deve essere allocato e (in generale) deallocato dal chiamante.
Ovvio che se vado a prendermi i puntatori di tali oggetti spesso vuol dire che sono in cerca di rogne...

sottovento
03-01-2008, 22:56
In generale l'oggetto passato per riferimento non lo deve deallocare nessuno...sicuramente non dentro messageGot...
Con il puntatore dipende dall'architettura che scegli di implementare.

Si, il puntatore probabilmente viene deallocato alla fine delle chiamate alle callback. Non hai grandi scelte, in una architettura simile (la piu' diffusa).
Ergo: dovrai copiare i tuoi dati per evitare che ti spariscano da sotto il naso. No other chances!


No, è sempre C++...se il Garbage Collector si può implementare in C++ perché diventerebbe Managed ?

Perche' ero convinto che Managed si riferisse al fatto che qualcuno fa il management della memoria per me. Se non e' cosi', allora non ho proprio la minima idea di cosa sia Managed :mbe:


Non credo :D
Ti riferisci al fatto che non mi censuri o che certe notizie non vadano condivise? :D

sottovento
03-01-2008, 23:01
Sicuramente almeno fino all'uscita di messageGot.
Se vuoi usarlo fuori dal metodo devi farne una copia in una variabile locale.


Esatto. E' proprio sulla copia che sto insistendo ;)


Cosa che in realtà dovrebbe essere bene fare altrimenti qualcuno dall'esterno della classe potrebbe modificare il contenuto di una variabile magari privata.
Sai che bell'incapsulamento.



Essendo un riferimento non deve nemmeno passarti per la mente di deallocarlo ;)

Perfetto! Ma... se e' un puntatore? Ne fai la copia comunque, no?


generalmente è meglio mettere puntatori nei contenitori STL.
Con il codice:

coda.push (telegram);

metti nel contenitore una copia dell'oggetto telegram.

Beh, diciamo che ci siamo capiti :)


"Che cavolo stai dicendo Willy?"
I puntatori hanno tutti la stessa dimensione 32 o 64 bit a seconda dell'architettura, l'unica eccezione è per i puntatori a metodo che a seconda del compilatore possono arrivare ad occupare anche a 20 byte.

Il cavolo che sto dicendo e' che i puntatori, in C++ hanno operazioni non solo di assegnamento ma anche di somma, sottrazione, ...
Queste operazioni non ti permetteranno ti tener conto di tutti i puntatori che fanno riferimento allo stesso oggetto, in modo da deallocarlo automaticamente quando nessuno lo punta piu'. (i famosi "smart pointer" che usi quando programmi usando COM).
E' un problema ben noto...

marco.r
03-01-2008, 23:03
Sì, ma devono essere gli STESSI programmi: stesse identiche funzionalità.

E' chiaro che poi, in base al linguaggio, posso utilizzare costrutti e librerie a disposizione. Ne parlo meglio qui: http://www.hwupgrade.it/forum/showpost.php?p=20347372&postcount=152 ;)

Ok, quando leggo "stesso programma" io capisco anche medesima implementazione :p, questione di capirsi.
In questo caso allora non ha molto senso star li' a destreggiarsi in loop ciclopici... decidiamo un task un po' piu' complesso e vediamo come va a finire C++ vs. Java vs. resto del mondo.
Sempre che abbia senso. Il web e' pieno di confronti simili.
Che nella maggior parte dei casi hanno poco senso visto che spesso dettano anche come debbano essere scritti i programmi (vedi ad esempio il famoso shootout (http://shootout.alioth.debian.org/)) e allora tanto vale.

sottovento
03-01-2008, 23:03
E' una questione che mi incuriosisce da un po' e non ho mai avuto una risposta chiara: cosa si intende per linguaggio Managed ? Mi risulta che il termine sia stato coniato da Microsoft per indicare quei linguaggi che girano all'interno della framework .NET, ma vedo che e' spesso usato in contesti piu' generali. Ma allora che caratteristiche deve avere ? Avere un GC ? (Ma allora anche il C++ potrebbe esserlo), girare in una VM (quindi sarebbe da escludere Java compilato con gcj) ? Altro ?

Mi associo. Credevo anch'io che si riferisse solo al fatto che qualcuno si prende cura della mia memoria, ma ora non sono piu' sicuro di nulla.

sottovento
03-01-2008, 23:09
Ok, quando leggo "stesso programma" io capisco anche medesima implementazione :p, questione di capirsi.
In questo caso allora non ha molto senso star li' a destreggiarsi in loop ciclopici... decidiamo un task un po' piu' complesso e vediamo come va a finire C++ vs. Java vs. resto del mondo.
Sempre che abbia senso. Il web e' pieno di confronti simili.
Che nella maggior parte dei casi hanno poco senso visto che spesso dettano anche come debbano essere scritti i programmi (vedi ad esempio il famoso shootout (http://shootout.alioth.debian.org/)) e allora tanto vale.

Fantastico! Ovviamente hai [hanno] ragione.

marco.r
03-01-2008, 23:15
Perfetto! Ma... se e' un puntatore? Ne fai la copia comunque, no?

Dipende che policy hai stabilito per la gestione della memoria.
Se ci si gestisce la memoria da se' bisogna farlo con criterio, per cui quando chiami quel metodo dovresti gia' sapere se la proprieta' di quella memoria e' del chiamato, del chiamante e in tal caso se per una quantita' di tempo sufficiente a garantirne l'uso da parte del chiamato. Ovvio che se ogni metodo fa caso a parte si diventa matti...

sottovento
03-01-2008, 23:28
Dipende che policy hai stabilito per la gestione della memoria.
Se ci si gestisce la memoria da se' bisogna farlo con criterio, per cui quando chiami quel metodo dovresti gia' sapere se la proprieta' di quella memoria e' del chiamato, del chiamante e in tal caso se per una quantita' di tempo sufficiente a garantirne l'uso da parte del chiamato. Ovvio che se ogni metodo fa caso a parte si diventa matti...

Forse non ci siamo capiti. Quello che volevo dire e' che:
1 - c'e' un "dispatcher" che riceve dei telegrammi da dove vuole lui;
2 - se qualcuno ne vuole copia, implementa una interfaccia (o una funzione virtuale in C++) e si registra. Quando un nuovo telegramma arriva, viene automaticamente chiamata la messageGot() (e' sempre un esempio);
3 - la messageGot() deve elaborare il telegramma. Supponendo che debba fare diverse operazioni, si sia deciso di affidare le medesime ad un altro thread.

Quindi la messageGot() sara' piu' o meno cosi':

void messageGot (Telegram *telegram) oppure
void messageGot (Telegram &telegram)
{
// Metti in coda per elaborare
taskQueue.push (telegram);
}


E' una soluzione ampiamente usata.

Quello che dicevo e' che C++ non puo' fare alcuna assunzione sulla validita' della variabile FUORI dalla messageGot (), pertanto in coda non avra' altra scelta che mettere un COPIA dell'oggetto, o un puntatore alla COPIA dell'oggetto, altrimenti il rischio e' quello di processare della fuffa.

Java non ha questo problema.

Questo e' sufficiente a far pendere l'ago delle prestazioni dalla parte di Java? Well, dipende da quanto e' pesante le copie che C++ e' obbligato a fare mentre Java puo' evitare.

Scusami se non ho capito bene quello che intendevi dire.
Cmq quello che voglio andare a sfatare e' l'assunto:
- compilato = efficiente
- interpretato = inefficiente

Non ne sono per niente convinto, come non sono convinto dell'equazione
- C++ = efficiente
- Java = inefficiente

Sono convinto che ci sono dei casi (e non proprio particolari) in cui queste equazioni si invertono. E sono convinto che in futuro le cose cambieranno ancora...

tomminno
03-01-2008, 23:41
Esatto. E' proprio sulla copia che sto insistendo ;)


La copia locale è sempre buona cosa, se devi riusare la variabile in altre parti della classe. Perchè significa che nessuno dall'esterno possa modificarne il contenuto a tua insaputa. Se condividi il riferimento con altre classi questo presupposto cade.


Perfetto! Ma... se e' un puntatore? Ne fai la copia comunque, no?


Per questo motivo è meglio passare il riferimento.
Se qualcuno ti passa un puntatore e te lo copi solo come puntatore e chi te lo ha passato decide di deallocarlo sei nei guai.
Stesso discorso per il chiamante che potrebbe vedersi deallocato il puntatore dal chiamato a sua insaputa.
Generalmente nelle classi si include il costruttore di copia che prende in ingresso un riferimento const, io almeno non ho mai scritto la versione di copia per puntatori, magari sono poco previdente :fagiano:


Il cavolo che sto dicendo e' che i puntatori, in C++ hanno operazioni non solo di assegnamento ma anche di somma, sottrazione, ...
Queste operazioni non ti permetteranno ti tener conto di tutti i puntatori che fanno riferimento allo stesso oggetto, in modo da deallocarlo automaticamente quando nessuno lo punta piu'. (i famosi "smart pointer" che usi quando programmi usando COM).
E' un problema ben noto...

Sarà anche un problema ben noto, ma auto_ptr funziona da più di 10 anni e ci sono gli smart pointer di boost (e del nuovo standard) che non hanno di questi problemi.
Mai usato COM potrebbe essere un problema suo :D

tomminno
03-01-2008, 23:56
Quello che dicevo e' che C++ non puo' fare alcuna assunzione sulla validita' della variabile FUORI dalla messageGot (), pertanto in coda non avra' altra scelta che mettere un COPIA dell'oggetto, o un puntatore alla COPIA dell'oggetto, altrimenti il rischio e' quello di processare della fuffa.

Java non ha questo problema.


Ma se non ne fai una copia locale qualcuno dall'esterno potrebbe modificare il contenuto del messaggio che hai messo in coda perchè ha un riferimento all'oggetto.
A me hanno sempre detto che è un comportamento da evitare, una classe dovrebbe avere il pieno controllo delle variabili che utilizza, se vuoi modificare una variabile devi passare per i metodi set, ma se dall'esterno qualcuno tiene il riferimento all'oggetto può modificarlo senza passare dal set.

Usi la copia o violi l'incapsulamento?

Per quanto riguarda processare fuffa, il C++ risolve utilizzando auto_ptr. Se qualcuno ti passa un auto_ptr sai per certo che ti lascia l'ownership del puntatore, altrimenti devi supporre che non lo deallocherai salvo specifiche opposte (generalmente questi problemi nascono interfacciandosi con librerie in C).


Questo e' sufficiente a far pendere l'ago delle prestazioni dalla parte di Java? Well, dipende da quanto e' pesante le copie che C++ e' obbligato a fare mentre Java puo' evitare.


Ripeto con gli smart pointer queste copie in più si possono evitare già da subito senza attendere gli rvalue reference e la move semantics del futuro standard (che promette di risolvere la questione definitivamente).


Sono convinto che ci sono dei casi (e non proprio particolari) in cui queste equazioni si invertono. E sono convinto che in futuro le cose cambieranno ancora...

Io aspetto di provare il nuovo C++ :D

cionci
04-01-2008, 00:24
Scusate...ma Java come si comporta in un caso del genere...ora mi create confusione :asd:
Io passo per riferimento la classe Telegram, ma se io mi devo prendere la stringa e modificarla devo assolutamente farmi una copia...sia per come è definita una string in Java, sia per evitare qualcun altro mi modifichi l'oggetto dall'esterno...no ?

Poi il fatto che si facciano queste copie in più non significa assolutamente che Java sia più lento del C++...abbiamo visto come anche su una cosa banale (il bubblesort che ho postato qualche pagina fa) il C++ possa essere anche più veloce di Java di 4-5 volte...credo che questo vantaggio possa far entrare ampiamente qualche copia in più fatta nel passaggio dei parametri e nella gestione delle classi...

sottovento
04-01-2008, 00:39
Scusate...ma Java come si comporta in un caso del genere...ora mi create confusione :asd:
Io passo per riferimento la classe Telegram, ma se io mi devo prendere la stringa e modificarla devo assolutamente farmi una copia...sia per come è definita una string in Java, sia per evitare qualcuno altro mi modifichi l'oggetto dall'esterno...no ?

In Java risolveresti (elegantemente) il problema allocando un nuovo oggetto ogni volta che ricevi un telegramma. Semplice, elegante, efficiente e non viola l'incapsulamento.
Purtroppo non e' cosi' facile in C++, occorre sempre trovare delle "scorciatoie" che non sempre funzionano, e decidono di non funzionare alle 3 del mattino, costringendo sottovento ad alzarsi, spostare la famiglia che gli dorme sopra, e correre per 30 miglia a risolvere il problema :Prrr: :D

auto_ptr e compagnia bella non mi sembra si possano applicare in questi casi, quanto meno io non ce lo vedo proprio...

cionci
04-01-2008, 00:45
In Java risolveresti (elegantemente) il problema allocando un nuovo oggetto ogni volta che ricevi un telegramma. Semplice, elegante, efficiente e non viola l'incapsulamento.
Purtroppo non e' cosi' facile in C++, occorre sempre trovare delle "scorciatoie" che non sempre funzionano, e decidono di non funzionare alle 3 del mattino, costringendo sottovento ad alzarsi, spostare la famiglia che gli dorme sopra, e correre per 30 miglia a risolvere il problema :Prrr: :D

auto_ptr e compagnia bella non mi sembra si possano applicare in questi casi, quanto meno io non ce lo vedo proprio...
Se in Java devi quindi creare un nuovo oggetto per ogni copia del messaggio che consegni ad un destinatario...allora sei nella stessa situazione della copia ;)
In C++ ti mantieni un solo messaggio locale al dispatcher e lo deallochi o automaticamente (variabile locale o auto_ptr) o con la delete quando lo hai consegnato a tutti i client registrati.

Sei esattamente nella stessa situazione...ne una copia in più ne una in meno ;)

marco.r
04-01-2008, 00:47
Quello che dicevo e' che C++ non puo' fare alcuna assunzione sulla validita' della variabile FUORI dalla messageGot (), pertanto in coda non avra' altra scelta che mettere un COPIA dell'oggetto, o un puntatore alla COPIA dell'oggetto, altrimenti il rischio e' quello di processare della fuffa.

Quel che stavo dicendo io e' che se il programma e' stato strutturato in un certo modo le assunzioni le puoi fare. E se non puoi ci sono gli smart_pointer.
Questo non toglie che la copia possa essere una soluzione piu' comoda, ma non e' l'unica.


come non sono convinto dell'equazione
- C++ = efficiente
- Java = inefficiente

Non ne sono convinto neanche io, ma adesso stiamo parlando di altro :D

tomminno
04-01-2008, 00:49
In Java risolveresti (elegantemente) il problema allocando un nuovo oggetto ogni volta che ricevi un telegramma. Semplice, elegante, efficiente e non viola l'incapsulamento.
Purtroppo non e' cosi' facile in C++, occorre sempre trovare delle "scorciatoie" che non sempre funzionano, e decidono di non funzionare alle 3 del mattino, costringendo sottovento ad alzarsi, spostare la famiglia che gli dorme sopra, e correre per 30 miglia a risolvere il problema :Prrr: :D

auto_ptr e compagnia bella non mi sembra si possano applicare in questi casi, quanto meno io non ce lo vedo proprio...

Ricevi un telegramma e allochi un nuovo telegramma copia del precedente.
Questo non significa per caso fare una copia dell'oggetto?

marco.r
04-01-2008, 00:52
La copia locale è sempre buona cosa, se devi riusare la variabile in altre parti della classe.

Diciamo che e' cattiva cosa cosa riutilizzare la variabile per altre cose... :p
non farlo e ti risparmi possibili rogne.

tomminno
04-01-2008, 00:56
Diciamo che e' cattiva cosa cosa riutilizzare la variabile per altre cose... :p
non farlo e ti risparmi possibili rogne.

Se sei in un metodo set cavolo vorrai riusarla quella variabile o no?

cdimauro
04-01-2008, 08:57
E' una questione che mi incuriosisce da un po' e non ho mai avuto una risposta chiara: cosa si intende per linguaggio Managed ? Mi risulta che il termine sia stato coniato da Microsoft per indicare quei linguaggi che girano all'interno della framework .NET, ma vedo che e' spesso usato in contesti piu' generali. Ma allora che caratteristiche deve avere ? Avere un GC ? (Ma allora anche il C++ potrebbe esserlo), girare in una VM (quindi sarebbe da escludere Java compilato con gcj) ? Altro ?
A parte l'esplicito riferimento alla CLR e all'IL, mi ritrovo esattamente in questa definizione: http://blogs.msdn.com/brada/archive/2004/01/09/48925.aspx

Quindi ci rientrano linguaggi come Java, C#, Python, Ruby, ecc., dove l'esecuzione avviene attraverso una VM che è dotata ANCHE di GC (nei casi in cui serva) e che "diriga" l'esecuzione del codice aggiungendo eventuali controlli necessari per impedire l'esecuzione di azioni dannose e/o non previste.
Ok, quando leggo "stesso programma" io capisco anche medesima implementazione :p, questione di capirsi.
Certamente: meglio rimuovere le ambiguità. :)
In questo caso allora non ha molto senso star li' a destreggiarsi in loop ciclopici... decidiamo un task un po' piu' complesso e vediamo come va a finire C++ vs. Java vs. resto del mondo.
Potremmo provare a convertire Diamond Crash in C++ e vedere come viene, come suggeriva Marco. :p
Sempre che abbia senso. Il web e' pieno di confronti simili.
Che nella maggior parte dei casi hanno poco senso visto che spesso dettano anche come debbano essere scritti i programmi (vedi ad esempio il famoso shootout (http://shootout.alioth.debian.org/)) e allora tanto vale.
Questi confronti vanno presi sempre con le pinze.

Possono essere un'utile "metrica" per vedere il comportamento di specifiche piattaforme su specifici pezzi di codice, ma giusto per farsi un'idea.

Non conosco nello specifico i "dettami" che si devono seguire per implementare i programmi, ma leggendo quella pagina non mi pare che vi siano imposizioni su come debba essere scritto il codice.
A cosa ti riferisci di preciso?

RaouL_BennetH
04-01-2008, 14:28
Potremmo provare a convertire Diamond Crash in C++ e vedere come viene, come suggeriva Marco. :p




Perdonami Cesare!! :D

Ma sottintendi che riscrivendo Diamond in C++ si tramuterà in un cicloopico Crash ? :D

Scusate l'ot :)

fek
04-01-2008, 14:38
io veramente a quel punto proporrei l'acquisizione di hardware migliore... seriamente, per un 1% ti stai ad ammazzare rendendo i tuoi sorgenti incomprensibili e per nulla manutenibili, aumentando a dismisura i costi futuri di riutilizzo di quel codice? :D
e secondo te un 1% di performance in più non lo puoi guadagnare migliorando l'hardware? perché cavolo deve essere il programmatore a farsi un didietro così a scrivere software? tantopiù che siamo a Natale :D

Ho creato un mostro. E francamente un po' mi dispiace pure :)

fek
04-01-2008, 14:41
Eh no... se sei bravo tu lo fai SIA veloce SIA funzionante... troppo comodo così :D

Spiegami come si fa! Spiegami come si fa! Diventiamo ricchissimi!

sottovento
04-01-2008, 14:57
Ricevi un telegramma e allochi un nuovo telegramma copia del precedente.
Questo non significa per caso fare una copia dell'oggetto?

No dai, non e' una copia del precedente. Ricevo un telegramma (potrebbe essere una sequenza di byte) ed in entrambi i linguaggi devo creare un nuovo oggetto.
In generale il costruttore si prendera' in carico delle eventuali decodifiche (che devono essere fatte una sola volta, in partenza).

cdimauro
04-01-2008, 21:02
Perdonami Cesare!! :D

Ma sottintendi che riscrivendo Diamond in C++ si tramuterà in un cicloopico Crash ? :D

Scusate l'ot :)
ARGH!!! :muro: Mica è la prima volta che confondo delle vocali... :stordita:

Figurati che una volta ho pronunciato "drag en drop" (proprio così) e i miei amici che erano vicini si sono ribaltati dalle risate. :p

pietro84
04-01-2008, 21:36
Sul web i pareri sono discordi e contrastanti, sebbene tutti ammettano che C++ sia più performante di java. Alcuni però sostengono che le prestazioni siano simili. Voi che ne dite?
Parlando ad esempio di software di visione artificiale, credete sia conveniente l'utilizzo di java (comodo per via delle libererie disponibili) o è meglio utilizzare il C++?

io mi sono occupato di visione artificiale. secondo me il linguaggio più adatto è ANSI C .
lascia stare i linguaggi ad oggetti.

tomminno
05-01-2008, 14:29
io mi sono occupato di visione artificiale. secondo me il linguaggio più adatto è ANSI C .
lascia stare i linguaggi ad oggetti.

Realizzare una GUI in puro C secondo me è da masochisti.
Mai avuto a che fare con le Win32 o le GTK?
Evidentemente no, altrimenti non avresti fatto un'affermazione simile.

marco.r
05-01-2008, 15:48
Se sei in un metodo set cavolo vorrai riusarla quella variabile o no?

Usare e riusare sono due cose distinte (e cosi' ho esaurito il mio bonus settimanale di pedanteria :D).
Se tu invece intendevi usare la variabile (per lo scopo per il quale e' stato chiamato il metodo) il discorso e' un po' diverso, ma per certi versi abbastanza semplice. Tenersi una copia di una istanza o un puntatore/riferimento dovrebbe dipendere semplicemente dal fatto che dal punto di vista logico l'oggetto a cui ci si riferisce sia lo stesso o un altro.
Voglio che chi elabora la coda possa modificare l'oggetto che mi e' stato passato o, al contrario, vedere le modifiche che ha effettuato qualcun altro ? Mi tengo il puntatore.
Voglio che il risultato dell'elaborazione sia un qualcosa di distinto dal suo input ? Me lo copio e poi lo modifico.
E' comunque una cosa che va al di la' del linguaggio, e che quindi vale tanto in C++ quanto in Java. A dire il vero in C++ ho un'arma in piu': se il chiamante vuole essere sicuro che l'oggetto non venga modificato posso passarlo come const, ed evitare che il chiamato adotti la prima soluzione.

tomminno
05-01-2008, 16:29
Usare e riusare sono due cose distinte (e cosi' ho esaurito il mio bonus settimanale di pedanteria :D).
Se tu invece intendevi usare la variabile (per lo scopo per il quale e' stato chiamato il metodo) il discorso e' un po' diverso, ma per certi versi abbastanza semplice. Tenersi una copia di una istanza o un puntatore/riferimento dovrebbe dipendere semplicemente dal fatto che dal punto di vista logico l'oggetto a cui ci si riferisce sia lo stesso o un altro.


Il mio discorso si concretizzava in particolare sui metodi set, visto che qualcuno ti passa un riferimento esterno, controlli se il riferimento contiene valori accettabili e infine lo copi su una variabile della classe per poterlo riusare in altre parti della classe stessa, ovunque sia necessaria. Era questo il senso del mio "riusare", non certo nel senso di riutilizzo di variabili per scopi differenti.


Voglio che chi elabora la coda possa modificare l'oggetto che mi e' stato passato o, al contrario, vedere le modifiche che ha effettuato qualcun altro ? Mi tengo il puntatore.


Il C++ in questo non aiuta visto che i riferimenti devono sempre esistere, una variabile di classe che sia un riferimento deve essere inizializzata nella lista di inizializzazione e quindi in generale di scarsa utilità.
Il C++ in questi casi obbliga ad usare i puntatori.


A dire il vero in C++ ho un'arma in piu': se il chiamante vuole essere sicuro che l'oggetto non venga modificato posso passarlo come const, ed evitare che il chiamato adotti la prima soluzione.

const_cast e passa la paura.
Purtroppo il C++ non garantisce niente, in quanto potresti volutamente togliere il const a qualunque cosa.
Infatti a causa di questo in linea teorica sarebbe sempre bene passare copie di variabili locali.
Io sinceramente me ne sono sempre fregato di potenziali terroristi del codice e restituisco sempre riferimenti const.

a2000.1
05-01-2008, 16:51
Realizzare una GUI in puro C secondo me è da masochisti.
Mai avuto a che fare con le Win32 o le GTK?
Evidentemente no, altrimenti non avresti fatto un'affermazione simile.

http://www.prangpower.com/shop/images/GlueSticks.gif

marco.r
05-01-2008, 17:22
Il mio discorso si concretizzava in particolare sui metodi set, visto che qualcuno ti passa un riferimento esterno, controlli se il riferimento contiene valori accettabili e infine lo copi su una variabile della classe per poterlo riusare in altre parti della classe stessa, ovunque sia necessaria. Era questo il senso del mio "riusare", non certo nel senso di riutilizzo di variabili per scopi differenti.

Certo se vuoi usarlo cosi' devi fai la copia, ma in che modo questo e' differente in C++ da Java (ricordo che il discorso iniziale era che il C++ obbligherebbe a fare piu' copie) ?


Il C++ in questo non aiuta visto che i riferimenti devono sempre esistere, una variabile di classe che sia un riferimento deve essere inizializzata nella lista di inizializzazione e quindi in generale di scarsa utilità.
Il C++ in questi casi obbliga ad usare i puntatori.

Perdonami, ma non ho capito cosa intendi dire con questo...


const_cast e passa la paura.
Purtroppo il C++ non garantisce niente, in quanto potresti volutamente togliere il const a qualunque cosa.
Infatti a causa di questo in linea teorica sarebbe sempre bene passare copie di variabili locali.
Io sinceramente me ne sono sempre fregato di potenziali terroristi del codice e restituisco sempre riferimenti const.
E' difficile che una persona aggiunga un const_cast per sbaglio, per cui si evitano tutti i casi in cui si va a modificare involontariamente un oggetto.
Era questo a cui mi riferivo, e non e' una cosa da poco. Il problema di chi opera con malizia e' tutto un altro paio di maniche, ma anche piu' circoscritto, visto che di solito e' legato a chi scrive codice che deve essere utilizzato da terze parti (ad esempio una libreria).

cionci
05-01-2008, 17:42
Certo se vuoi usarlo cosi' devi fai la copia, ma in che modo questo e' differente in C++ da Java (ricordo che il discorso iniziale era che il C++ obbligherebbe a fare piu' copie) ?
Infatti...quello che sostenevo anche io ;)

cratus
06-01-2008, 10:00
Ciao, c' è qualcuno che è interessato a elaborare un progetto java con me? E' da tempo che ho in mente una cosa simile ma non ho mai avuto degli amici interessati alla programmazione....

franksisca
06-01-2008, 11:00
Ciao, c' è qualcuno che è interessato a elaborare un progetto java con me? E' da tempo che ho in mente una cosa simile ma non ho mai avuto degli amici interessati alla programmazione....

dipende dal progetto, ma qui, a "perditempo", troverai molta gente interessata....apri un thrtead dove spieghi il tuo progetto e vedrai molte risposte ;)

cratus
06-01-2008, 11:09
Si grazie, non ho un progetto preciso in mente solo mi piacerebbe elaborarne uno con più persone. Comunque mi hanno gia contattato nei messaggi privati... :D

fek
06-01-2008, 15:06
io mi sono occupato di visione artificiale. secondo me il linguaggio più adatto è ANSI C .
lascia stare i linguaggi ad oggetti.

Scrivilo in assembly a questo punto, lascia stare i linguaggi ad alto livello.

dupa
06-01-2008, 15:17
Scrivilo in assembly a questo punto, lascia stare i linguaggi ad alto livello.

appunto.. a meno che un 10% di velocità in più non sia un requisito essenziale, meglio scrivere qualcosa che sia leggibile, facile da mantenere e soprattutto che porti meno il programmatore a commettere errori.

Nella mia esperienza da programmatore ritengo che programmare in C++ ti porti a commettere errori + facilmente rispetto a quando si programma in Java e questo a me basterebbe per accettare delle prestazioni leggermente inferiori.

fek
06-01-2008, 16:08
appunto.. a meno che un 10% di velocità in più non sia un requisito essenziale, meglio scrivere qualcosa che sia leggibile, facile da mantenere e soprattutto che porti meno il programmatore a commettere errori.

Nella mia esperienza da programmatore ritengo che programmare in C++ ti porti a commettere errori + facilmente rispetto a quando si programma in Java e questo a me basterebbe per accettare delle prestazioni leggermente inferiori.

Guarda, ho letto differenze di produttivita' fra C++ e Java/C#/Python che vanno fino a 5/10 volte. Roba che si puo' anche arrivare a impiegare un decimo del tempo per produrre un'applicazione in Java. Poi fattorizzando tool come Eclipse e la MONTAGNA di altri tool per Java, la differenza in termini di produttivita' e' enorme.

Qui si fatica a percepire il fatto che la risorsa piu' scarsa non e' la memoria o la cpu, ma il tempo dei programmatori.

E quando si parla anche di prestazioni, il 10% difficilmente lo raggiungi, anche perche', immagina di dover scrivere un tool di image recognition dove il 99% del tempo e' di solito speso all'interno di pochi operatori e di pochi inner loop: inutile scrivere l'intera applicazione in C/C++, basta riscrivere quei pochi inner loop una volta che sono testati e funzionanti in Java e azzeri le differenza prestazionali. E guadagni tempo di sviluppo.

dupa
06-01-2008, 17:20
Guarda, ho letto differenze di produttivita' fra C++ e Java/C#/Python che vanno fino a 5/10 volte. Roba che si puo' anche arrivare a impiegare un decimo del tempo per produrre un'applicazione in Java. Poi fattorizzando tool come Eclipse e la MONTAGNA di altri tool per Java, la differenza in termini di produttivita' e' enorme.

Qui si fatica a percepire il fatto che la risorsa piu' scarsa non e' la memoria o la cpu, ma il tempo dei programmatori.

E quando si parla anche di prestazioni, il 10% difficilmente lo raggiungi, anche perche', immagina di dover scrivere un tool di image recognition dove il 99% del tempo e' di solito speso all'interno di pochi operatori e di pochi inner loop: inutile scrivere l'intera applicazione in C/C++, basta riscrivere quei pochi inner loop una volta che sono testati e funzionanti in Java e azzeri le differenza prestazionali. E guadagni tempo di sviluppo.

sìsì ma guarda, non mi devi convincere, son già convinto :)

mi ritengo un buon programmatore, ai tempi dell'università l'esame di fondamenti d'informatica 1, al secondo compitino c'erano 3 esercizi abbastanza complessi in C++ e fui l'unico a farli tutti e 3 giusti nel tempo che ci era stato dato (era abb. breve)...

Però ad esempio 2 anni dopo quando ripresi in mano il C++ per far un mini-progettino di ingegneria del software (che si affiancava al progettone in Java) sinceramente nn è che mi ricordavo molto del C++ (che avevo visto solo 2 anni prima e in più ci avevo anche giochicchiato alle superiori..) mentre quando si tratta di riprendere in mano il Java dopo un po' che non lo si usa, l'impatto è molto migliore.

Poi oddio, sinceramente se uno è molto bravo a programmare, ha molto tempo, e ha una grossa capacità di restar concentrato, sicuramente C++ è potente.. non discuto questo.

Ma nel mondo dell'informatica, i team di sviluppo cambiano i loro membri continuamente.. la gente dopo mezza giornata di lavoro inizia ad aver la mente stanca.. insomma.. è decisamente meglio avere a disposizione qualcosa che non ci porti a commettere errori, e con C++ invece basta una piccola disattenzione e si possono fare grosse cazzate difficili da rimetter a posto.

Per non parlare del fatto che nn è nemmeno banalissimo trovare (e mantenere in azienda) anche solo 10 persone veramente brave a programmare in C++ per far un mini-team di sviluppo.

PS:
ultima cosa.. qualcuno mi pare che ha citato muTorrent come esempio di piccolo programma in C++ ben fatto che offre molto e occupa poca RAM... vorrei ricordare che è un programma che si appoggia a librerie Win32.. quindi non è che tutto ciò che utilizza per gestire TCP/IP, gestione componenti Finestre ecc. è gratis.. anzi anche le librerie Win32 occupano il loro bello spazio nella RAM :)

VICIUS
06-01-2008, 17:50
PS:
ultima cosa.. qualcuno mi pare che ha citato muTorrent come esempio di piccolo programma in C++ ben fatto che offre molto e occupa poca RAM... vorrei ricordare che è un programma che si appoggia a librerie Win32.. quindi non è che tutto ciò che utilizza per gestire TCP/IP, gestione componenti Finestre ecc. è gratis.. anzi anche le librerie Win32 occupano il loro bello spazio nella RAM :)
E aggiungiamo anche che il programma non è proprio 200k visto che l'eseguibile è compresso e viene estratto ogni volta che lo si lancia. :)

ciao ;)

variabilepippo
06-01-2008, 18:02
qualcuno mi pare che ha citato muTorrent come esempio di piccolo programma in C++ ben fatto che offre molto e occupa poca RAM... vorrei ricordare che è un programma che si appoggia a librerie Win32.. quindi non è che tutto ciò che utilizza per gestire TCP/IP, gestione componenti Finestre ecc. è gratis.. anzi anche le librerie Win32 occupano il loro bello spazio nella RAM

Non è gratis? E quanto costa? :rolleyes:

Trattandosi di DLL di sistema mi sembra ovvio che vengano condivise da tutte le applicazioni (uTorrent compreso) in esecuzione. Ogni programmatore dovrebbe riscrivere uno stack TCP/IP ed un GUI toolkit da zero?! :confused:


E aggiungiamo anche che il programma non è proprio 200k visto che l'eseguibile è compresso e viene estratto ogni volta che lo si lancia


Una volta decompresso occupa circa 400k su disco, posso chiederti quanto occupa Azureus? Ovviamente senza considerare il peso del JRE necessario per farlo funzionare...

VICIUS
06-01-2008, 18:30
Una volta decompresso occupa circa 400k su disco, posso chiederti quanto occupa Azureus? Ovviamente senza considerare il peso del JRE necessario per farlo funzionare...
Non ho idea di quanto pesi azureus perché lo detesto. Penso sia un abominio, un concentrato di over-engineering.
Con il mio intervento volevo solo far notare che gli sviluppatori di utorrent sono dei furbacchioni :D

ciao ;)

variabilepippo
06-01-2008, 18:53
Con il mio intervento volevo solo far notare che gli sviluppatori di utorrent sono dei furbacchioni

Non vedo la furberia, usare i packer per gli eseguibili è una prassi molto comune...

dupa
06-01-2008, 19:53
Non è gratis? E quanto costa? :rolleyes:

Trattandosi di DLL di sistema mi sembra ovvio che vengano condivise da tutte le applicazioni (uTorrent compreso) in esecuzione. Ogni programmatore dovrebbe riscrivere uno stack TCP/IP ed un GUI toolkit da zero?! :confused:



DLL di windows. Quindi se fai girare il tuo bel mutorrent su Linux devi riscrivere parte del codice.

variabilepippo
06-01-2008, 20:12
Quindi se fai girare il tuo bel mutorrent su Linux devi riscrivere parte del codice.


Non rigiriamo la frittata, questo è un problema completamente diverso, si parlava di prestazioni ed al limite di occupazione in termini di spazio (disco/memoria). Su Linux preferisco usare client nativi al posto di quel polpettone scritto in Java di Azureus...

marco.r
06-01-2008, 23:07
DLL di windows. Quindi se fai girare il tuo bel mutorrent su Linux devi riscrivere parte del codice.

Oppure uso qualcos'altro, non e' difficile trovare qualcosa di meglio di Azureus sotto linux. Meglio due programmi diversi che funzionano bene che uno unico che ti pianta il sistema.

dupa
06-01-2008, 23:08
Non rigiriamo la frittata, questo è un problema completamente diverso, si parlava di prestazioni ed al limite di occupazione in termini di spazio (disco/memoria). Su Linux preferisco usare client nativi al posto di quel polpettone scritto in Java di Azureus...

si ma scusa se tu usi le librerie Win32 stai usando cose che occupano "memoria" e allo stesso modo la JVM occupa memoria.. quindi non ho capito perchè se la memoria la occupa la JVM non va bene.. se la occupano le librerie Win32 va bene.. mah.

dupa
06-01-2008, 23:09
Oppure uso qualcos'altro, non e' difficile trovare qualcosa di meglio di Azureus sotto linux. Meglio due programmi diversi che funzionano bene che uno unico che ti pianta il sistema.

ma java != azureus

marco.r
06-01-2008, 23:10
Non ho idea di quanto pesi azureus perché lo detesto. Penso sia un abominio, un concentrato di over-engineering.
Con il mio intervento volevo solo far notare che gli sviluppatori di utorrent sono dei furbacchioni :D

ciao ;)

Azureus e' la dimostrazione che spesso il tempo risparmiato grazie all'uso di linguaggi piu' fruibili andrebbe dedicato a bersi un paio di birre in piu' e non a scrivere altro codice :D

marco.r
06-01-2008, 23:14
ma java != azureus

Verissimo. Diciamo che pero' e' l'esempio (uno dei tanti) di una propensione all'over-engineering secondo me piu' diffusa tra i programmatori Java che non tra altri, e che contribuisce alla nomea di lentezza del linguaggio.

AnonimoVeneziano
06-01-2008, 23:36
Che bel thread da Onanismo mentale :D

Durante la malattia me lo ero perso :)

Ganbattè :p

cionci
07-01-2008, 00:54
si ma scusa se tu usi le librerie Win32 stai usando cose che occupano "memoria" e allo stesso modo la JVM occupa memoria.. quindi non ho capito perchè se la memoria la occupa la JVM non va bene.. se la occupano le librerie Win32 va bene.. mah.
Perché se usi la JVM usi sia le dll Win32 che la JVM...mentre su un programma Win32 usi solo le dll Win32 ;) Tanto le dll di Win32 le devi comunque usare...qualsiasi cosa tu faccia su Windows...stessa cosa per le system call di Linux ;)

cdimauro
07-01-2008, 06:30
Azureus e' la dimostrazione che spesso il tempo risparmiato grazie all'uso di linguaggi piu' fruibili andrebbe dedicato a bersi un paio di birre in piu' e non a scrivere altro codice :D

Verissimo. Diciamo che pero' e' l'esempio (uno dei tanti) di una propensione all'over-engineering secondo me piu' diffusa tra i programmatori Java che non tra altri, e che contribuisce alla nomea di lentezza del linguaggio.

Due post da incorniciare... :p

P.S. Ma qui ci vorrebbe Cyrano... :asd:

shinya
07-01-2008, 08:24
mi ritengo un buon programmatore, ai tempi dell'università l'esame di fondamenti d'informatica 1, al secondo compitino c'erano 3 esercizi abbastanza complessi in C++ e fui l'unico a farli tutti e 3 giusti nel tempo che ci era stato dato (era abb. breve)...

HAHA! Scusa, ma questa mi fa ridere...posso usarla come sign? :sofico:

dupa
07-01-2008, 08:30
HAHA! Scusa, ma questa mi fa ridere...posso usarla come sign? :sofico:

boh, se ti fa ridere... :sofico:

banryu79
07-01-2008, 08:53
...
Qui si fatica a percepire il fatto che la risorsa piu' scarsa non e' la memoria o la cpu, ma il tempo dei programmatori.
...


Quoto al 100%.
Questa è la risorsa più importante, da tutti i punti di vista.

OT: bel 3D, meriterebbe uno sticky :)

banryu79
08-01-2008, 10:11
... ovvero un esempio tratto dal mondo reale che dimostra come, in talune situazioni pratiche, Java venga scelto anche per via delle sue performance.

L'articolo risale al 2005, quindi è un po' datato ma molto interessante, tratta infatti di un sistema di telemetria per Formula 1 realizzato basandosi su tecnologia Jini.

qui c'è l'articolo (http://www.mokabyte.it/2005/10/javapista.htm)

In particolare vorrei porre l'attenzione su questo passaggio :)

Ci piace subito sottolineare, a riprova di quanti passi avanti abbia compiuto Java in questi dieci anni, che uno dei problemi che non abbiamo avuto è stato quello della performance. In particolare, sul requisito della latenza siamo riusciti, senza troppi problemi, a garantire tempi non superiori a 10ms, molto al di sotto dei requisiti richiesti (per completezza sarebbe necessario dare qualche riferimento alla classe di hardware utilizzato: in sommi capi, perché varia da scuderia a scuderia, i client sono laptop di fascia altra e i server tipicamente sono macchine biprocessore di fascia medio-bassa. Insomma, niente di fantascientifico). Chissà se in futuro finirà finalmente la leggenda urbana che dice che “Java è lento”?

cionci
08-01-2008, 10:18
Java venga scelto anche per via delle sue performance.
Scusa, ma anche nel passo che riporti non si parla di performance, ma di quanto le performance non siano state un problema per l'applicazione in questione.

banryu79
08-01-2008, 10:25
Sì hai ragione, infatti ho detto che è un po' OT rispetto al discorso "Java più lento di C++"...

E' che poi il 3d ha spaziato rispetto al tema specifico del titolo; il fatto è che alla luce di tutti gli altri aspetti complementari che ruotano intorno alla realizzazione di un software, l'aspetto singolo "Java più lento di C++" può depistare un attimo chi si pone il problema di quale linguaggio utilizzare per, ad esempio, sistemi real time.

L'articolo postato la dice lunga proprio su questo aspetto (e altri, non strettamente legati alle performance ma ad altre problematiche).

Detto questo mi tolgo di torno: è chiaro che qui sono andato un po' troppo OT però aprire un nuovo 3d mi sembrava troppo :sofico:

Ciao :)

cionci
08-01-2008, 10:29
Nono...ci stava benissimo con il thread...fa vedere che quando i requisiti di tempo non sono strettissimi le performance non sono un problema.

fek
08-01-2008, 10:30
Scusa, ma anche nel passo che riporti non si parla di performance, ma di quanto le performance non siano state un problema per l'applicazione in questione.

Il passo interessante secondo me riguarda la garanzia di latenza che riescono a dare al di sotto dei 10ms. E' interessante perche' di solito quando c'e' un garbage collector di mezzo non si e' mai garantiti sulle latenze: per questo in sistemi strettamente real-time e' preferibile usare C++ non per le performance ma per le garanzie sulla latenza. E' anche il motivo per il quale gli engine 3d si scrivono in C++, perche' sono sistemi real-time!

Altra curiosita', in 10ms devo disegnare un terzo della scena, non pensate che siano pochi.

banryu79
08-01-2008, 10:36
Nono...ci stava benissimo con il thread...fa vedere che quando i requisiti di tempo non sono strettissimi le performance non sono un problema.

Come fai a dire che "i requisiti di tempo non sono strettissimi" in riferimento al caso di cui si parla nell'articolo? Dubito che tu sia già riuscito a leggerlo tutto :D è un po' lunghetto.

Comunque, a tal proprosito, proprio nella conclusione dell'articolo:

Conclusioni
Dobbiamo dire subito una cosa: il progetto è stato stressante, ma ci siamo divertiti: non capita molto spesso di poter utilizzare una tecnologia di frontiera, come Jini e Rio, in un ambito così delicato e challenging come la Formula Uno. È stata una grande soddisfazione portare a termine la realizzazione di un progetto così difficile (oltretutto in pochi mesi e con un sostanziale rispetto dei tempi) in un'area dove in molti non avrebbero scommesso a priori l'effettiva usabilità di Java.


Ciao :)

banryu79
08-01-2008, 10:39
Il passo interessante secondo me riguarda la garanzia di latenza che riescono a dare al di sotto dei 10ms.

Infatti, nelle specifiche si progetto, secondo quanto riportato nell'articolo, si richiedeva di rispettare una latenza massima di 50 ms.

Loro sono riusciti a stare entro i 10 ms: secondo me uno scarto così grande rispetto la richiesta significa che cmq per ottenere i 10 ms. non hanno dovuto fare i "salti mortali" (se così fosse stato, vista la complessità globale del progetto e i tempi stretti, credo avrebbero sforato, imho)

cionci
08-01-2008, 10:48
Ho letto un po'...non tutto. Ma i 10ms è il tempo in cui sono riusciti a mantenere la latenza...
In particolare, sul requisito della latenza siamo riusciti, senza troppi problemi, a garantire tempi non superiori a 10ms, molto al di sotto dei requisiti richiesti
La latenza richiesta era almeno 5 volte più alta, quindi non sono requisiti di tempo strettissimi ;) E non è un'applicazione real-time.

banryu79
08-01-2008, 11:20
La latenza richiesta era almeno 5 volte più alta, quindi non sono requisiti di tempo strettissimi ;) E non è un'applicazione real-time.

Vero, chiedo venia :)


Ma che mi dici di questo (http://it.bea.com/ultimissime/2007/070605_wlrt2.jsp)?

Vabbè dai, in questo 3d io faccio il crociato per Java :p

marco.r
08-01-2008, 21:16
Altra curiosita', in 10ms devo disegnare un terzo della scena, non pensate che siano pochi.
Immagino ! Domanda correlata: anche in C++ allocazioni e deallocazioni hanno un loro costo, anche se piu' controllabile, e penso soprattutto al caso di strutture dati composte da diversi oggetti diversi piu' piccoli. Nel vostro campo questo crea problemi ? Se si', quali sono gli accorgimenti tipici che adottate ?

fek
09-01-2008, 10:28
Immagino ! Domanda correlata: anche in C++ allocazioni e deallocazioni hanno un loro costo, anche se piu' controllabile, e penso soprattutto al caso di strutture dati composte da diversi oggetti diversi piu' piccoli. Nel vostro campo questo crea problemi ? Se si', quali sono gli accorgimenti tipici che adottate ?

In C++ allocazione/disallocazione sono operazioni considerate "lente". Poi gli accorgimenti dipendono da caso a caso: all'interno del render loop, di solito, non si alloca MAI. Il problema qui non e' tanto il tempo che si perde nelle operazioni di allocazioni/disallocazione, ma la frammentazione dell'heap: dopo qualche ora di gioco non vuoi che il render loop si inchiodi perche' un'allocazione fallisce a causa della troppa frammentazione...

Le soluzioni sono varie: al momento usiamo spesso allocatori custom. Ad esempio, se devi allocare della memoria che sai che vive solo per un flame, lo allochi con un semplice veloce allocatare che si limita ad un'addizione in uno spazio di memoria preallocato e alla fine del frame pulisce tutto.
Oppure uso un allocatoare a stack per la memoria video: alloco oggetti (render target) e disallocco in ordine inverso. E' veloce e mi garantisce nessuna frammentazione.

Poi dipende da caso a caso. Se vuoi, uno dei veri vantaggi del C++ rispetto a Java/C# e' l'avere questo livello di controllo sulle policy di allocazione e sulla gestione della memoria, cosa che non e' possibile in un linguaggio ad alto livello. Ed e' anche vero che questo livello di controllo porta tutta una serie di problemi non trascurabili.

Angus
09-01-2008, 13:52
Infatti Java è proliferato in tutti altri ambiti, non è mai diventato il linguaggio dei tostapane come pensato originariamente.


hmmm... MHP (http://www.mhp.org/)

marco.r
11-01-2008, 21:17
In C++ allocazione/disallocazione sono operazioni considerate "lente". Poi gli accorgimenti dipendono da caso a caso: all'interno del render loop, di solito, non si alloca MAI. Il problema qui non e' tanto il tempo che si perde nelle operazioni di allocazioni/disallocazione, ma la frammentazione dell'heap: dopo qualche ora di gioco non vuoi che il render loop si inchiodi perche' un'allocazione fallisce a causa della troppa frammentazione...

Non mi ero spiegato molto bene :p. Fin qui c'ero gia', perche' e' bene o male la situazione che abbiamo noi in laboratorio (il ciclo di controllo dei nostri robot va circa a 5 kHz e di conseguenza le allocazioni nel suo interno sono assolutamente vietate). Nel nostro caso pero' la situazione e' facilmente gestibile in quanto all'interno del loop bene le operazioni da eseguire sono abbastanza regolari (o anche assistite da hw esterno come fpga), e riusciamo tranquillamente a spostare su thread/processi esterni le operazioni che coinvolgono la memoria. Mi incuriosiva proprio la questione della gestione quando questo non si puo' fare.

Le soluzioni sono varie: al momento usiamo spesso allocatori custom. Ad esempio, se devi allocare della memoria che sai che vive solo per un flame, lo allochi con un semplice veloce allocatare che si limita ad un'addizione in uno spazio di memoria preallocato e alla fine del frame pulisce tutto.
Oppure uso un allocatoare a stack per la memoria video: alloco oggetti (render target) e disallocco in ordine inverso. E' veloce e mi garantisce nessuna frammentazione.

Grazie mille della risposta. Proprio quello che volevo sapere.


Poi dipende da caso a caso. Se vuoi, uno dei veri vantaggi del C++ rispetto a Java/C# e' l'avere questo livello di controllo sulle policy di allocazione e sulla gestione della memoria, cosa che non e' possibile in un linguaggio ad alto livello. Ed e' anche vero che questo livello di controllo porta tutta una serie di problemi non trascurabili.
Avevo letto un po' di tempo fa di estensioni di Java in cui si demarcavano con appositi attributi metodi/istanze/etc. in modo da marcare in modo esplicito i margini di vita degli oggetti ed ottenere, ad esempio allocazione assicurata sullo stack piuttosto che garanzie sui tempi di esecuzione etc. ma, al di la' dell'appesantimento del linguaggio, si trattava come spesso accade di estensioni chiuse (seppure prodotte dalla stessa Sun) e di un costo non banale.

Mixmar
11-01-2008, 21:41
Non mi ero spiegato molto bene :p. Fin qui c'ero gia', perche' e' bene o male la situazione che abbiamo noi in laboratorio (il ciclo di controllo dei nostri robot va circa a 5 kHz e di conseguenza le allocazioni nel suo interno sono assolutamente vietate). Nel nostro caso pero' la situazione e' facilmente gestibile in quanto all'interno del loop bene le operazioni da eseguire sono abbastanza regolari (o anche assistite da hw esterno come fpga), e riusciamo tranquillamente a spostare su thread/processi esterni le operazioni che coinvolgono la memoria. Mi incuriosiva proprio la questione della gestione quando questo non si puo' fare.


Piccolo OT: anche se ho (quasi) sempre programmato con linguaggi managed e non ho mai avuto l'onere/l'onore di confrontarmi direttamente con problemi di gestione della memoria, rimango sempre affascinato da queste argomentazioni... mi sembra quasi di riuscire a capire i dettagli! :stordita: (Ma questo dipenderà dalla competenza di chi li espone... ;) ).

Avevo letto un po' di tempo fa di estensioni di Java in cui si demarcavano con appositi attributi metodi/istanze/etc. in modo da marcare in modo esplicito i margini di vita degli oggetti ed ottenere, ad esempio allocazione assicurata sullo stack piuttosto che garanzie sui tempi di esecuzione etc. ma, al di la' dell'appesantimento del linguaggio, si trattava come spesso accade di estensioni chiuse (seppure prodotte dalla stessa Sun) e di un costo non banale.

Forse l'approccio migliore sarebbe qualcosa di simile al costrutto "unsafe" del C#: il problema è che di fatto più che una feature del linguaggio, in quel caso è una feature della CLR, e poi rompe il "contratto" dell'utilizzo di un linguaggio managed... senza considerare il fatto che non ho idea delle condizioni della memoria che si trovi di fronte chi usi un pezzo di programma in modo managed, poi entri in "unsafe mode", senza avere idea di quello che la CLR ha fatto per lui e dello stato della memoria che si trova davanti.

Almeno con un linguaggio "compilato" si può determinare (più o meno) lo stato della memoria perchè se ne gestisce personalmente l'evoluzione, ma in questo caso "ibrido" non so proprio cosa possa succedere... qualcuno ha esperienze in proposito? :)

marco.r
13-01-2008, 13:35
Forse l'approccio migliore sarebbe qualcosa di simile al costrutto "unsafe" del C#: il problema è che di fatto più che una feature del linguaggio, in quel caso è una feature della CLR, e poi rompe il "contratto" dell'utilizzo di un linguaggio managed... senza considerare il fatto che non ho idea delle condizioni della memoria che si trovi di fronte chi usi un pezzo di programma in modo managed, poi entri in "unsafe mode", senza avere idea di quello che la CLR ha fatto per lui e dello stato della memoria che si trova davanti.

Quel che riportavo nel passaggio qui sopra e' in un certo senso il contrario: il programmatore istruisce il compilatore delle condizioni che il codice deve soddisfare, e questo segnala errore se non riesce a verificarle. Ad esempio se voglio avere la garanzia che in un determinato loop non ci siano allocazioni (sullo heap), posso marcare in modo opportuno tutti i metodi che devo chiamare. Il compilatore verifichera' che tutti gli oggetti creati in quelle chiamate non possano "scappare" fuori, e che il loro ciclo di vita si concluda all'interno del loop. Se e' cosi', potra' allocare gli oggetti direttamente sullo stack, ottenendo idealmente l'effetto degli allocatori custom di cui parlava fek prima.
Questo in linea di principio, ci sono delle differenze e le cose sono un po' piu' complicate di cosi', ma penso possa rendere l'idea. Purtroppo non riesco a trovare il link che ne parlava... :rolleyes: