calcolo scientifico:
Python e Julia
Maurizio Tomasi
Giovedì 22 Marzo 2018
Funzionamento dei
compilatori C++
Tipi di memoria
• Memoria volatile:
• Registro (qualche kB, 64 bit per ciclo di clock)
• Cache (128 kB–128 MB, 40–700 GB/s)
• Memoria RAM (10 GB/s)
• Memoria permanente:
• Disco fisso SSD (~1 GB/s)
• Disco fisso HDD (120 MB/s)
Accesso alla memoria
• Memoria nei registri: si accede solo attraverso
identificativi (rbp, rsp, rax, rbx… per gli interi,
xmm0, xmm1… per i floating-point)
• Memoria RAM: la CPU richiede il dato specificando
un indirizzo numerico
• Hard disk: la CPU emette un «interrupt», che fa
eseguire un codice al micro-controller del disco e
restituisce un risultato.
Dimensioni e velocità
Banco di RAM da 8 GB
00110100
10111101
01001011
01001100
…
iter++;
}
if (iter == max_iter)
return -1; // Point (startx, starty) is in the set
else
return iter;
}
Codice assembler (-O0)
zy = 2 * zx * zy + cy;
diventa
• r: registro
• sr: puntatore RAM (vecchio tipo)
• i: valore immediato
• m: puntatore RAM (nuovo tipo)
http://www.agner.org/optimize/instruction_tables.pdf
Il linguaggio Python
L’approccio di Python
• Python nasce all’inizio degli anni 90, 20 anni dopo il
C e 7 dopo il C++
• Quando nasce il Python c’è la consapevolezza che i
computer saranno sempre più veloci: programmi
«lenti» sono sempre meno un problema
• L’approccio di Python è completamente diverso
rispetto al C++: non è più compilato, ma
interpretato
Esempio: complessità del C++
#include <iostream>
int main(void) {
int i;
1324623600
Esempio: complessità del C++
#include <iostream>
int i;
int main(void) {
0
Esempio: complessità del C++
#include <iostream>
int main(void) {
int arr[10];
std::cout << arr[0] << std::endl;
return 0;
}
-1423518960
Esempio: complessità del C++
#include <iostream>
int arr[10];
int main(void) {
std::cout << arr[0] << std::endl;
return 0;
}
0
Esempio: complessità del C++
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> arr(10);
std::cout << arr[0] << std::endl;
return 0;
}
0
Esempio: complessità del C++
#include <iostream>
void miagola() {
std::cout << "Miaooo!\n";
}
class Cane {
public:
Cane() { std::cout << "Bau! Bau!\n"; }
};
int main(void) {
miagola();
Cane miocane();
return 0;
} Dov’è l’errore?
Lo Zen di Python
• Beautiful is better than ugly
• Explicit is better than implicit
• Simple is better than complex
• Complex is better than complicated
• Flat is better than nested
• Sparse is better than dense
• Etc.
https://www.python.org/dev/peps/pep-0020/
Come installare e usare Python
• Qualsiasi sistema usiate (Windows, Mac, Linux),
installate Anaconda Python 3
• Evitate Anaconda Python 2 (è vecchio)
• Aprite «Anaconda Prompt» ed installate una serie
di pacchetti con questo comando:
conda install numpy scipy matplotlib jupyter
• Sempre da «Anaconda Prompt», scrivete
jupyter notebook
• Al posto di notebook potete usare console oppure
qtconsole (provate!)
Frattale Julia in Python
Non è necessario definire i tipi delle variabili
import numpy
Il ciclo for è implicito qui
def midpoint(fn, a, b, nsteps):
Python h = (b - a) / nsteps
x = numpy.linspace(a + h/2, b - h/2, nsteps)
return numpy.sum(fn(x)) * h
Esempio: simulazione
esperimento
Consideriamo l’esercizio 9.5 del corso di TNDS, in cui si simula
la misurazione della viscosità di un fluido misurando la
velocità limite di caduta di una sferetta nel fluido, data da
2𝑅
𝑣𝐿 = 𝜌 − 𝜌0 𝑔
9𝜂
Compilati Interpretati
• C • Python
Misti
• C++ • MATLAB
• Julia!
• Fortran • IDL
• Pascal • R
• Ada
• Rust
Cos’è Julia?
• Linguaggio molto recente (versione 0.1 rilasciata il
14/2/2013)
• Creato espressamente per il calcolo scientifico
• Facile come Python e veloce come il C++…?
• Non ancora stabile (versione corrente 0.6.2, la 0.7 è
attesa a breve, poi finalmente 1.0): in particolare, il
sistema di gestione delle librerie verrà presto
sostituito
• https://julialang.org/
Funzionamento di Julia
• Il codice viene compilato in un formato chiamato
AST (Abstract Syntax Tree)
• Al momento di essere eseguito, viene compilato in
linguaggio macchina
• Il linguaggio macchina è quello vero della CPU su
cui gira il codice, e sono implementate tutte le
ottimizzazioni tipiche di C++ e di Fortran
• L’ottimizzatore usato è LLVM, usato anche dal
compilatore C++ usato sui sistemi Mac OS X (clang)
Esempio: somma di due numeri
julia> mysum(a, b) = a + b
mysum (generic function with 1 method)
julia> mysum(1, 2)
3
import numpy
import numpy
https://github.com/HSU-ANT/ACME.jl
Julia e la programmazione OOP
• Julia non è OOP come il C++ o Python: OOP non è
una scelta naturale per codici numerici
• Julia implementa un paradigma nuovo, il multiple
dispatch, che è pensato apposta per il calcolo
scientifico
• Si tratta di una versione avanzata dell’overloading di
operatori che implementa il C++