Cosa mai potrebbe accadere se due macchine dotate di intelligenza artificiale venissero messe una contro l’altra? Stringerebbero una collaborazione o finirebbero per litigare? È ciò che si sono chiesti gli ingegneri di DeepMind (dal 2014 sotto l’ala di Google) i cui risultati sono stati presentati in uno studio di recente pubblicazione. Per l’occasione le macchine sono state poste di fronte a “dilemmi sociali”, ovvero situazioni in cui un individuo può trarre vantaggio dal fatto di restare da solo, ma il vantaggio è destinato a sparire nel momento in cui più individui dovessero competere. The Verge cita l’esempio del dilemma del prigioniero : due individui si contendono un premio scegliendo tra diverse opzioni, se per entrambi la scelta ricade sulla stessa opzione il premio viene perso.
I ricercatori hanno usato dei videogame come pretesto per stimolare le macchine e farle scontrare . Il contesto è semplice: In Gathering il giocatore ha la possibilità di colpire con un raggio laser l’altro concorrente sospendendolo momentaneamente dal gioco. Durante la sua assenza il giocatore può raccogliere più agevolmente degli oggetti, acquisendo punti.
In Wolfpack invece due giocatori devono catturarne un terzo. I punti ottenuti dalla cattura sono rivendicati non solo dal giocatore che ha completato la missione, ma anche da chi vi si trova vicino.
A secondo del contesto, l’intelligenza artificiale ha agito in maniera differente , a volte collaborando e a volte preferendo lo scontro. Nel primo gioco ad esempio l’introduzione di un giocatore più forte ha alterato il comportamento facendo propendere l’intelligenza artificiale ad adottare un atteggiamento più aggressivo. All’inizio del gioco invece, vista l’abbondanza degli oggetti da raccogliere si è registrata una maggior collaborazione: concentrarsi sull’aggressione dell’avversario infatti equivale a spendere più potenza di calcolo e perdere opportunità di raccolta di oggetti. In Wolfpack invece è stato evidenziato che per collaborare (scelta più opportuna) è richiesta molta potenza di calcolo. Solo l’intelligenza artificiale più sofisticata ha quindi propeso per la collaborazione con migliori risultati.
I ricercatori hanno espresso soddisfazione per i risultati, che potranno infatti essere utilizzati “per capire meglio i complessi sistemi multi-agente come l’economia, i sistemi di traffico e la salute ecologica del pianeta: tutte cose che dipendono dalla nostra continua cooperazione”.
È interessante notare che ormai tutti i più recenti esperimenti che hanno a che fare con l’intelligenza artificiale prevedono di riflesso applicazioni con il mondo reale (si pensi all’ultima vittoria a poker contro campioni in carne ed ossa). Le macchine hanno imparato a reagire a stimoli inconsueti e aleatori tipici della vita quotidiana . Non si tratta più di predire le mosse dell’altro, ma saper reagire di conseguenza in modo consono. In lontananza si intravedono già questioni inerenti alle alterazioni di comportamento causati da possibili cattive compagnie (come i troll online). Ebbene sì, anche i robot dovranno fare i conti con la “coscienza” e rispettare l’etica pur non avendo la consapevolezza di cosa siano (almeno per ora).
Mirko Zago
-
Rust e Go
Rust e Go? Sciacquatevi la bocca. Forse si può passare al C++, ma di sicuro non a linguaggi in cui è _obbligatorio_ l'uso del garbage collector. Altrimenti vi potete scordare le prestazioni di rete a cui siamo abituati.AndreabontRe: Rust e Go
non sai di cosa parli, informatiil solito purlaRe: Rust e Go
> Più il programmatore è competente, più riesce a> utilizzare linguaggi di basso livello e più> riesce specializzare e a sfruttare la conoscenza> dell'hardware per incrementare le performance del> suo programma. Per codec audio/video,> applicazioni di rete (es: router),> microcontrollori/dispositivi embedded con> hardware limitato la differenza è importante e si> nota. Altrove dove va bene anche il visual basic,> e le performance non contano niente, allora> arrivano i winari e gli scripettari a predicare> che puoi fare tutto in C#, java, shell script....> ma la realtà è> diversa.E pensare che la prima cosa che mi hanno insegnato si basa su tre parole: Astrazione, Riduzione, InduzionekmiknmkRe: Rust e Go
sole cuore amoredammi tre paroleRe: Rust e Go
- Scritto da: dammi tre parole> sole cuore amoreE la zappa per dissodare i campivghrvvgtRe: Rust e Go
Prestazioni di rete? Per la maggior parte delle appliance di rete anche il Python va bene (e per esempio applicazioncine piccole piccole e giocattolo tipo Youtube sono in Python)...Guarda che le app di rete sono tipicamente affette per natura da latenze che a livello CPU son ere geologiche.Quanto alle performance nella programmazione di sistema, anche per roba piuttosto cpu-bound sia Rust (sopratutto) che Go non si mostrano diversi dal C++, dal C o manco dall'assembly manuscritto... A parte ciò non dimenticare la grande lezione di UNIX: un os scritto in un linguaggio assai meno performante di quelli usati dai rivali dell'epoca ha sbaragliato tutti per due semplici regioni: facilità di codifica, facilità di avere una ricca e portabile libreria standard (ai tempi). Ad oggi il C ed anche il C++ in un contronto con Rust o Go si possono considerare i nuovi asm vs i nuovi C.xteRe: Rust e Go
- Scritto da: xte> Prestazioni di rete? Per la maggior parte delle> appliance di rete anche il Python va bene (e per> esempio applicazioncine piccole piccole e> giocattolo tipo Youtube sono in> Python)...> > Guarda che le app di rete sono tipicamente> affette per natura da latenze che a livello CPU> son ere> geologiche.> > Quanto alle performance nella programmazione di> sistema, anche per roba piuttosto cpu-bound sia> Rust (sopratutto) che Go non si mostrano diversi> dal C++, dal C o manco dall'assembly> manuscritto... A parte ciò non dimenticare la> grande lezione di UNIX: un os scritto in un> linguaggio assai meno performante di quelli usati> dai rivali dell'epoca ha sbaragliato tutti per> due semplici regioni: facilità di codifica,> facilità di avere una ricca e portabile libreria> standard (ai tempi). Ad oggi il C ed anche il C++> in un contronto con Rust o Go si possono> considerare i nuovi asm vs i nuovi> C.Se sai come ottimizzarlo il python non e tanto un giocattolino. Ti basti vedere i progetti(non piccoli) su implementazione pypy! Od anche Cython, ma non solo.Il fuddaroRe: Rust e Go
Bé la realtà è anche un pelino diversa da quella che descrivi te mettendo insieme Rust già solo con Go, per di più poi unito a Python e Java...Per quanto riguarda l'asm ti faccio notare che a sua volta è compilato da un assembler che non è scritto da nessuna parte ne sappia di più di un compilatore C o Rust sulle istruzioni della CPU per cui compila. A parte ciò se compilassi veramente usando tutte le possibili ottimizzazioni della CPU che hai ti troveresti ad aver binari praticamente importabili, un hello world compilato per un Intel Core i3 di VI generazione avrebbe ottime probabilità di non girare su un Core i7 di V genrazione ecc. In pratica dovresti compilare (e ciò in se non sarebbe male, ammazzerebbe definitivamente il sw proprietario) per ogni CPU esistente e ricompilare tutto quando cambi CPU sullo stesso ferro inoltre chi scrive tanto i compilatori quanto gli assembler avrebbe un lavoro a dir poco improbo per stare al passo col ferro.xteRe: Rust e Go
> Per quanto riguarda l'asm ti faccio notare che a> sua volta è compilato da un assembler che non è> scritto da nessuna parte ne sappia di più di un> compilatore C o Rust sulle istruzioni della CPU> per cui compila. Ti stai sbagliando di grosso.Un assembler è in grado di tradurre TUTTO il set di istruzioni per la CPU per cui è stato concepito.Avendo il codice sorgente in assembly come input (un tempo conosciuto anche come il "listato") l'assembler si limita a tradurre istruzione-per-istruzione in opcode. L'unica modifica ben nota che esegue un assember sul suo codice sorgente in ingresso è quella di calcolare gli indirizzi per i jump (che a seconda dell'assembler usato possono generare istruzioni di lunghezza diverse....quindi può essere importante). Per il resto puoi anche inserire istruzioni inesistenti scrivendo ".byte 123,123" e l'assembler semplicemente trascriverà quei valori. Puoi compilare un sorgente che usa istruzioni AVX2 sia col loro valore numerico (.byte...) sia scrivendo il nome mnemonico e l'assembler genererà l'opcode appropriato. Se andrai a eseguire il programma su un i386 che di sicuro non conosce le istruzioni AVX2 allora non funzionerà (la CPU genererà un'eccezione di invalid opcode o una #GP). In realtà pure questo può essere più complicato di così. Per esempio l'istruzione PAUSE del Pentium4 genera come opcode F3 90 (due byte). Se ci fai caso, l'pcode "F3" è lo stesso opcode del prefisso di istruzione "REP", mentre l'istruzione "90" è l'opcode del NOP. Per una coincidenza eseguire l'istruzione PAUSE su una CPU precedente il Pentium4 non genera nessuna eccezione perché viene "scambiata" per un'altra istruzione valida ma che non ha nessun effetto "REP;NOP". E' un trucco ben noto.http://x86.renejeschke.de/html/file_module_x86_id_232.html PAUSEhttp://x86.renejeschke.de/html/file_module_x86_id_279.html REPhttp://x86.renejeschke.de/html/file_module_x86_id_217.html NOP>A parte ciò se compilassi> veramente usando tutte le possibili> ottimizzazioni della CPU che hai ti troveresti ad> aver binari praticamente importabili, un hello> world compilato per un Intel Core i3 di VI> generazione avrebbe ottime probabilità di non> girare su un Core i7 di V genrazione ecc. Infatti per i programmi scritti in C si usa l'apposito switch nel compilatore... o non si usa con lo scopo di generare eseguibili "generici" che funzionino ovunque e che pero' non sono ottimizzati (o cambiando punto di vista: che sono di fatto ottimizzati per la CPU più antica).PreproXXXXXre del compilatore -> compilatore (fa le ottimizzazioni e genera il listato) -> assembler (genera file oggetto) -> linker (genera l'eseguibile, se usa l'LTO può fare l'inlining di alcune funzioni ma meglio evitare per ora)Nella sequenza quindi, basta che per la fase del compilatore usi l'apposito switch, che per il GCC è -march.Lo trovi proprio qui come primo nella lista:https://gcc.gnu.org/onlinedocs/gcc/x86-Options.htmlCertamente (come hai detto) se compili per pentium4 poi l'eseguibile non andrà su un pentium3 e forse nemmeno su CPU successive (troppo lungo da spiegare... ma per esempio il codice non sta' a guardare il CPUID quindi se una feature sparisce, il programma non se ne accorge)> In> pratica dovresti compilare (e ciò in se non> sarebbe male, ammazzerebbe definitivamente il sw> proprietario) per ogni CPU esistente e> ricompilare tutto quando cambi CPU sullo stesso> ferro Basta che scarichi il sorgente di GMP per capire: https://gmplib.org/Alternativamente puoi scaricare anche il sorgente della glibc. Dopo averli letti capirai....... tutte quelle funzioni importanti, delle librerie, che vengono usate spesso e che sono rilevanti per le performance sono scritte in assembly per ogni CPU. C'è la stessa funzione scritta in assembly (in alcuni casi con le intrinsic, solitamente in assembly puro) con istruzioni SSE2, con l'SSE4.1, con l'AVX2, con l'AVX512..... e in assembly "generico" per i686 e AMD64(cioè SSE2 con 16 registri) nel caso usi un PC un po' vecchiotto. Anche per ARM64, mips, mipsel ecc... succede la stessa cosa.> inoltre chi scrive tanto i compilatori> quanto gli assembler avrebbe un lavoro a dir poco> improbo per stare al passo col> ferro.Non è così impervio come sembra ed accade proprio quello che dici: chi scrivi i compilatori (per gli assembler è una cavolata) si tiene al passo coi tempi e aggiunge al suo compilatore nuovi casi in cui vengono generate istruzioni diverse a seconda della CPU target (nonostante il codice in C in input sia lo stesso il listato generato è diverso). Semmai il problema è che risulta molto più facile a chi scrive il programma usare direttamente il codice in assembly giusto, che sperare che il compilatore se ne accorga. Per la vettorizzazione delle istruzioni nei cicli for/while il GCC fa miracoli, ma alcuni trucchi che potrebbe fare gli sono invisibili. Quindi se usi tu direttamente le istruzioni SIMD è meglio (ma la stessa logica vale anche per le altre unità... ALU, AGU, x87/MMX..). Per esempio non puoi mai sapere che cosa succede se scrivi "long double n" (in C in realtà col GCC lo puoi fare, ma solo se lo costringi ad usare una sola unità a virgola mobile... nella pagina di prima guarda anche lo switch -mfpmath.... ) se scrivi in assembly (anche se solo un inline assembly in un sorgente in C) puoi scrive manualmente le istruzioni per l'x87 (il coproXXXXXre matematico dell'x86) in modo da sfruttare le operazioni a virgola mobile a 80-bit, mentre se lasci decidere al compilatore quello genererà le istruzioni a virgola mobile per l'SSE2 (e successivi) a 64-bit (l'SSE manovra solo i float a 32-bit, quindi su CPU a 32 bit compreso il P4 sarà invece usato l'x87, ma l'AMD64 usa esclusivamente l'SSE2...perdendo precisione, ameno che non obblighi l'esecuzione dall'x87).Mentre un assembler conosce TUTTE le istruzioni per la CPU che supporta, un compilatore no (e non scriverà nel listato le istruzioni che non conosce). Quindi non sempre genererà codice ottimale. Inoltre i compilatori per il C non generano mai le istruzioni nth. E quindi le funzioni come memcpy per grandi aree di memoria si possono scrivere (ottimizzate) solo in assembly perché il compilatore non puo' usare quelle istruzioni (che sono per esempio MOVNTDQ, MOVNTI, MOVNTPD, MOVNTPS, MOVNTQ, MASKMOVDQU e svariate altre) perché non sà gestirle e sarebbe svantaggioso se imponesse delle fence sulla pipeline di store o load di sua iniziativa. Solo chi programma in assembly sà quando usarle (ad esempio per fare una memcpy o memset, ma solo quando viene messa in esecuzione su grandi aree di memoria; ma dipende anche dalla dimensione della cache della CPU; e da fattori temporali quando si accederà nuovamente a quella memoria?) Ho finito i caratteri :) Gli altri linguaggi cmq sono una caxata.ben10Re: Rust e Go
> Ti stai sbagliando di grosso.> Un assembler è in grado di tradurre TUTTO il set> di istruzioni per la CPU per cui è stato> concepito.Ceeerrto, perché secondo gli assemblers esistenti sono fatti e mantenuti dai produttori di CPU che aggiornano la grammatica per ogni singola istruzione che aggiungono vero?> Avendo il codice sorgente in assembly come input> (un tempo conosciuto anche come il "listato")> Nella sequenza quindi, basta che per la fase del> compilatore usi l'apposito switch, che per il GCC> è> -march.-march vuol dire machine architetture, non sono istruzioni specifiche per una singola CPU, non c'è alcuna differenza tra il binario che genera un backend di gcc e un assembler, la differenza è che l'assembly scritto a mano, in teoria, contiene solo quel che serve senza le aggiunte che il linguaggio impiega per i suoi automatismi interni. Giacché ti piace uesto argomento qui hai un confronto d'esempio con listati e dumptimelessname.com/elfbin/> Non è così impervio come sembra ed accade proprio> quello che dici: chi scrivi i compilatori (per> gli assembler è una cavolata) si tiene al passo> coi tempi e aggiunge al suo compilatore nuovi> casi in cui vengono generate istruzioni diverse a> seconda della CPU target (nonostante il codice in> C in input sia lo stesso il listato generato è> diverso).Listato? Forse hai incollato male... > Mentre un assembler conosce TUTTE le istruzioni> per la CPU che supporta, un compilatore no (e non> scriverà nel listato le istruzioni che non> conosce). Quindi non sempre genererà codice> ottimale. Ahem, guarda che i compilatori sono normalmente composti da un frontend che conosce il linguaggio da compilare ed un backend che conosce il ferro per cui compilarlo... Ma, per curiosità, ti interessa veramente quel che dici o fai collages di copia&incolla da articoli sparsi per l'web?xteRe: Rust e Go
- Scritto da: xte> scritto da nessuna parte ne sappia di più di un> compilatore C o Rust sulle istruzioni della CPUdi sicuro ne sa meno sulla struttura astratta del programma che stiamo realizzando, il che significa che e' impossibilitato a fare qualsiasi tipo di controllo sulla correttezza delle operazioni svolte dal programmasull'ottimizzazione, boh, loro dicono che il programmatore e' sempre meglio del compilatore, ma ho qualche dubbio in proposito> per cui compila. A parte ciò se compilassi> veramente usando tutte le possibili> ottimizzazioni della CPU che hai ti troveresti ad> aver binari praticamente importabili, un hello> world compilato per un Intel Core i3 di VI> generazione avrebbe ottime probabilità di non> girare su un Core i7 di V genrazione ecc. In> pratica dovresti compilare (e ciò in se non> sarebbe male, ammazzerebbe definitivamente il sw> proprietario) per ogni CPU esistente e> ricompilare tutto quando cambi CPU sullo stesso> ferro inoltre chi scrive tanto i compilatori> quanto gli assembler avrebbe un lavoro a dir poco> improbo per stare al passo col> ferro.fino ad oggi gli unici che possono farlo in termini realistici, sono i compilatori jitma ripeto, qui il problema e' la correttezza dei programmi, per cui assembly non puo' proprio avervi cittadinanzacollioneRe: Rust e Go
> che puoi fare tutto in C#, java, shell script....> ma la realtà è> diversa.Vero, la realtà è che i *grandi programmatori* che usano C e assembly hanno riempito i router di bug... e ogni tanto saltano fuori.nome e cognomeRe: Rust e Go
- Scritto da: nome e cognome> Vero, la realtà è che i *grandi programmatori*> che usano C e assembly hanno riempito i router di> bug... e ogni tanto saltano> fuori.esistono casi in cui il workload e' talmente elevato che e' giustificabile cercare di estrarre dalla macchina il massimo delle prestazioni ( FFMPEG e' pieno di codice assembly )cio' non toglie che la complessita' di un programma assembly rispetto anche ad uno in c e' svariati ordini di grandezza superiore, il che ( siccome l'uomo ha una memorietta da 7 posti ) significa che la probabilita' di introdurre bug e' altissimaed e' questa la ragione per cui sono nati linguaggi di sempre piu' alto livellooggi si sta cercando di creare linguaggi che siano di alto livello, garantiscano una maggiore correttezza del software e producano pure binari performantiche io sappia il primo a tentare cio' e' stato RustcollioneRe: Rust e Go
Analisi perfetta.Rust è un'ottima idea. Vedremo se riusciranno a portarlo in alto o ad affossarlo (vedi Vala).Garson PolloRe: Rust e Go
- Scritto da: collione> > esistono casi in cui il workload e' talmente> elevato che e' giustificabile cercare di estrarre> dalla macchina il massimo delle prestazioni (> FFMPEG e' pieno di codice assembly)> > cio' non toglie che la complessita' di un> programma assembly rispetto anche ad uno in c e'> svariati ordini di grandezza superiore, il che (> siccome l'uomo ha una memorietta da 7 posti )> significa che la probabilita' di introdurre bug> e' altissima> Esatto, infatti secondo me è autolesionistico voler usare il C a tutti i costi, soprattutto se ci tiri in ballo protocolli e modelli di dati nati per linguaggi a più alto livello.C'è un sacco di gente che programma da vent'anni in C e non segue le più elementari regole di manutenibilità, ci sono sorgenti pieni di bug in agguato e il cargo cult programming è diffusissimo.Se devo scrivere codice di basso livello e ho necessità di prestazioni molto alte, il C è praticamente imbattibile (strano a credersi, ma in matematica va più veloce il Fortran, che passa nei registri più tipi di dato). Fuori dal ciclo più interno, però, almeno finché si tratta di programmi con interfaccia utente, manutenibilità e stabilità diventano secondo me più importanti. Ecco, nel caso di roba che gira sui server interconnessi delle grandi aziende, mi sa che l'ottimizzazione spinta torni a rivestire un ruolo primario.L'importante è non essere partigiani a priori di un approccio o dell'altro, senza considerare le condizioni di utilizzo.Izio01Re: Rust e Go
- Scritto da: Andreabont> Rust e Go? Sciacquatevi la bocca. Forse si può> passare al C++, ma di sicuro non a linguaggi in> cui è _obbligatorio_ l'uso del garbage collector.> Altrimenti vi potete scordare le prestazioni di> rete a cui siamo> abituati.ma Rust non usa nessun garbage collector ne' altri stratagemmi a runtimeil pilastro fondante di Rust e' proprio la capacita' di scovare comportamenti anomali a compile time, cosa resa possibile dal particolare sistema di ownership che hanno inventatocollioneRe: Rust e Go
Tu sai vero che i vari linguaggi che hai definito come "da buttare" possono essere espansi da librerie in C / C++ là dove serve.Vero?Perché a sentire te si dovrebbe ancora sviluppare TUTTO in asm. Non mi sembri molto furbo, scusami se te lo dico.Garson PolloTanto tempo fa
Sacrosante parole quelle di ben10, se non conoscete niente di assembly forse è il caso, magari, di non fare considerazioni in modo da non risultare saccenti ma ottusi.darkinvaderRe: Tanto tempo fa
- Scritto da: darkinvader> Sacrosante parole quelle di ben10, se non> conoscete niente di assembly forse è il caso,> magari, di non fare considerazioni in modo da non> risultare saccenti ma> ottusi.Ma certo. Solo un incerto avrebbe partorito dette incertezze! (rotfl)Il fuddaroRe: Tanto tempo fa
Guarda che vale anche il contrario. Dire che bisogna affidarsi a C++ / C / asm per forza di cose ed affidarsi alla "bontà" del programmatore è di una pttusità ben più elevata di voler fare tutto con Java (o mettici il linguaggio che vuoi).Ricordo inoltre che non è detto che chi conosce il C++ poi sappia anche creare codice utile ad esempio per frangenti differenti dall'informatica "pura".Fonte: programmo in asm, C, C++ probabilmente da prima di molti di voi.Garson PolloUna sola nota
Per heartbleed le maggiori distro ed OS open avevan le patch rapidamente pronte, le vittime sono state (e magari sono ancora) solo gente che non manuteneva i suoi servizi o che non poteva farlo per i pezzi di ferro cuciti al sw di cert'uni produttori (router, telefoni &c basati su codice open, anche reso disponibile nel rispetto delle licenze ma di fatto abbandonati). Per questo baco bisogna aspettare che F5 si svegli e non vi sono certezze sul quando e come lo farà.xteRe: Una sola nota
E' closed sorcio corporate se la patch non c'è vuol dire che non serve. Fidati!maxminchRe: Una sola nota
Però in ogni contratto corporate c'è scritto che il software è "conXXXXX in uso" senza alcuna garanzia di sorta... Hum, il sola-ometro in genere va fuori scala...Ps tempo fa un collega disse che il software "enterprise" assomigliava alla nave Enterprise di Star Trek: c'è sempre qualche disastro critico che rischia di far saltar tutto, non c'è mai alcun "backup" di nessun sistema critico (c'è 1 solo computer, che fa tutto, un solo reattore per tutto ecc)... 'Somma qualcosa che farebbe sbatter fuori a calci qualsiasi matricola di ingegneria!xteGrazie, il tuo commento è in fase di approvazioneGrazie, il tuo commento è stato pubblicatoCommento non inviatoGrazie per esserti iscritto alla nostra newsletterOops, la registrazione alla newsletter non è andata a buon fine. Riprova.Leggi gli altri commentiMirko Zago 13 02 2017
Ti potrebbe interessare