lesson_07.md 4.5 KB

Piattaforme e Software per la rete - lezione 7

William Fornaciari

13 April 2016

Shared Memory

Possibilità di creare un segmento di memoria condiviso per far scambiare i dati tra diversi processi. È uno dei modi più veloci per comunicare, ma è pericoloso: può essere necessario controllare i permessi di scrittura. Un alternativa sono i memory mapped files:

  • primitive semplici (stesse dei file)
  • prestazioni leggermente peggiori

Conviene utilizzare i memory mapped files quando una normale scrittura su filesystem non sarebbe abbastanza veloce.

L'utilizzo della shared memory consiste in:

  • il primo processo crea un segmento di memoria e lo inizializza
  • Altri processi possono accedere al segmento condiviso

La primitiva usata per la creazione è shmget() e necessita delle librerie 'ipc.h' e 'shm.h' Per poter accedere allo stesso segmento condiviso, i vari processi possono usare la chiave che viene restituita al momento della creazione. Il segmento più piccolo che può essere allocato è 1 pagina, che può valere 1K,4K,... a seconda del sistema. Il terzo parametro è un valore bitwise o flag che serve a dare opzioni o impostazioni di sicurezza, le flag vanno usate in OR per ottenere la sequenza i bit di opzioni finali. La sincronizzazione migliore viene effettuata con i semafori piuttosto che con i permessi, i permessi servono per questioni di sicurezza.

Con la primitiva shmat() che sta per shared memory attach posso collegare il segmento condiviso ad altri processi. smhdt() è un modo per staccare il segmento dal processo chiamante.

Ciclo di utilizzo di una shared memory

Operazioni necessarie:

  • Creazione del segmento condiviso
  • Attaccare il segmento a tutti i processi che lo devono usare
  • Staccare il segmento dai processi che hanno finito di usarlo
  • Deallorare il segmento una volta che non serve più

Memory mapped files

Diversi processi sono in grado di comunicare con un file condiviso In linux a basso livelli il file viene diviso in pezzi della dimensione delle pagine per avere un acesso ottimizzato. La primitiva usata per questo meccanismo è mmap() e dopo la chiamata posso accedere all'oggetto con le primitive dei file Il file dovrebbe sopravvivere al riavvio del computer. La chiamata ad mmap() è più flessibile rispetto alle shm ma ha più overhead è possibile caricare in memoria con mmap() anche file letti dal filesystem (con le primitive dei file)

Condivisione di dati attraverso una rete IP

Remote Procedure Call è una procedura remota bloccante eseguita nello spazio di memoria della propria macchina Ci sono dei problemi nello scambio di dati, ad esempio può cambiare la endianness tra le due macchine e quindi risulterebbe complicato passare dei puntatori. RPC è stata la soluzione storica (vecchia di 30anni) per le architetture client server rpc si basa su UDP e quindi non garantisce la consegna, in base al valore di ritorno possiamo solo dire che la procedura è stata eseguita almeno una volta, risulta quindi una buona idea fare funzioni idempotenti, cioè che produce lo stesso risultato se eseguita più volte. Remote Procedure Call Messages di solito usando External Data Representation che è una codifica indipendente rispetto alle due macchine e che permette di trasferire i dati usando una codifica universale.

Meccanismo dell' RPC

  • Programma remoto si registra
  • Chiamante ottiene il numero di porta
  • Chiamante codifica i parametri e li invia al remoto
  • Remoto effettua i calcoli, codifica il risultato e lo invia al chiamante.

rpcgen è il compilatore che genera gli stub per server e client.

Architetture parallele

  • Shared memory in cui più processori usano una memoria condivisa Caratterizzati da UniformMemoryAccess (UMA), è l'architettura più semplice
  • Message passing in cui ogni cpu ha una memoria privata consistente rispetto alla memoria condivisa, architettura NotUniformMemoryAccess (NUMA)
  • Distributed systems in cui i processori comunicano attraverso internet.

Aspetti HW dei sistemi multiprocessore

  • Sistemi UMA Possono usare una matrice crossbar oppure una gerarchia di memorie (come le cache) Le architetture UMA funzionano bene per un basso numero di core (<16) La memoria condivisa può essere acceduta tramite un bus, con eventuali cache, i processori posso utilizzare anche una memoria privata per i conti e scrivere il risultato su una memoria condivisa.

Le matrici crossbar hanno il problema che il numero di punti cresce esponenzialmente quindi spesso vengono sostituite da switch a strati.