Torna indietro   Hardware Upgrade Forum > Software > Programmazione

iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile
iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile
C'è tanta sostanza nel nuovo smartphone della Mela dedicato ai creator digitali. Nuovo telaio in alluminio, sistema di raffreddamento vapor chamber e tre fotocamere da 48 megapixel: non è un semplice smartphone, ma uno studio di produzione digitale on-the-go
Intel Panther Lake: i processori per i notebook del 2026
Intel Panther Lake: i processori per i notebook del 2026
Panther Lake è il nome in codice della prossima generazione di processori Intel Core Ultra, che vedremo al debutto da inizio 2026 nei notebook e nei sistemi desktop più compatti. Nuovi core, nuove GPU e soprattutto una struttura a tile che vede per la prima volta l'utilizzo della tecnologia produttiva Intel 18A: tanta potenza in più, ma senza perdere in efficienza
Intel Xeon 6+: è tempo di Clearwater Forest
Intel Xeon 6+: è tempo di Clearwater Forest
Intel ha annunciato la prossima generazione di processori Xeon dotati di E-Core, quelli per la massima efficienza energetica e densità di elaborazione. Grazie al processo produttivo Intel 18A, i core passano a un massimo di 288 per ogni socket, con aumento della potenza di calcolo e dell'efficienza complessiva.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-07-2011, 15:42   #1
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
[C] Memory mapping di shared object

Ciao a tutti,

vorrei capire come effettuare un memory mapping di uno shared memory object, anche se non mi è molto chiaro come fare. La stragrande maggioranza degli esempio che si trova in rete utilizza mmap con dei files. Ad esempio, vorrei provare a fare una memory map di un array:

int*array=(int*) mmap(NULL, 100*sizeof(int), PROT_READ| PROT_WRITE, MAP_SHARED, -1, 0);

ma mi restituisce MAP_FAILED

Non mi è chiaro il mappaggio di shared objects con mmap, qualcuno mi può illuminare? Grazie.
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2011, 15:45   #2
tuccio`
Senior Member
 
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
se vuoi usare la mmap per la memoria condivisa devi usare il flag MAP_ANONYMOUS
tuccio` è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2011, 16:12   #3
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da tuccio` Guarda i messaggi
se vuoi usare la mmap per la memoria condivisa devi usare il flag MAP_ANONYMOUS
Ok, grazie per la dritta. Ma anche con quel flag non fa il mapping
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2011, 16:41   #4
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Ok, grazie per la dritta. Ma anche con quel flag non fa il mapping
Che errore ti da ?
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2011, 17:17   #5
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Che errore ti da ?
Sono riuscito a fare il mapping così:

Codice:
int*array=(int*) mmap(NULL, 100*sizeof(int), PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Il mio scopo però è fare un memory mapping di una matrice bidimensionale:

Codice:
int**array=(int**) mmap(NULL, dim_x*sizeof(int*), PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

for(..i..)
array[i]=(int*) mmap(NULL, dim_y*sizeof(int), PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);


Però se cerco di allocare oltre un limite che non conosco (ma già con 40 mb succede), mi dice " Cannot allocate memory" nel mapping dentro il for. Però, stranamente, un mapping di controesempio delle stesse dimensioni su un singolo array funziona. Ha senso effettuare un mapping di una matrice in questa maniera? Preciso che la macchina in questione ha circa 50 Gb di RAM.

Ultima modifica di Unrue : 08-07-2011 alle 17:38.
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 09-07-2011, 00:16   #6
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Sono riuscito a fare il mapping così:

Codice:
int*array=(int*) mmap(NULL, 100*sizeof(int), PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Il mio scopo però è fare un memory mapping di una matrice bidimensionale:

Codice:
int**array=(int**) mmap(NULL, dim_x*sizeof(int*), PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

for(..i..)
array[i]=(int*) mmap(NULL, dim_y*sizeof(int), PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);


Però se cerco di allocare oltre un limite che non conosco (ma già con 40 mb succede), mi dice " Cannot allocate memory" nel mapping dentro il for. Però, stranamente, un mapping di controesempio delle stesse dimensioni su un singolo array funziona. Ha senso effettuare un mapping di una matrice in questa maniera? Preciso che la macchina in questione ha circa 50 Gb di RAM.
Potrebbe essere un limite sul numero di aree di memoria allocate.
In ogni caso non la vedo una buona scelta, per due motivi:
In primis di performance, una matrice con doppi puntatori e' generalmente piu' lenta di una implementata con un singolo array.
La seconda e' che, a meno che tu poi non condivida la memoria con dei figli generati con una fork, hai dei puntatori che in generale non hanno senso in altri processi..

Per ovviare al problema del numero di chiamate, potresti semplicemente allocare una singola area condivisa.
Poi puoi usare una struttura piatta per la matrice oppure ,se vuoi mantenere quella attuale, prenderne dei segmenti da assegnare al vettore elle righe piuttosto che alle singole colonne.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 09-07-2011, 19:38   #7
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Potrebbe essere un limite sul numero di aree di memoria allocate.
Potresti chiarirmi questo punto?

Quote:
Originariamente inviato da marco.r Guarda i messaggi
In ogni caso non la vedo una buona scelta, per due motivi:

In primis di performance, una matrice con doppi puntatori e' generalmente piu' lenta di una implementata con un singolo array.
Si, questo lo so.

Quote:
Originariamente inviato da marco.r Guarda i messaggi
La seconda e' che, a meno che tu poi non condivida la memoria con dei figli generati con una fork, hai dei puntatori che in generale non hanno senso in altri processi..
Il discorso è un pò più complesso, in quanto sto allocando con la mmap per utilizzare la memoria in modalità intervealed tramite la libnuma, una libreria di gestione della memorai modalità NUMA, la quale prevede in questo caso che la memoria sia allocata con mmap o shmat. Tale memoria sarà condivisa poi da più threads.

Quote:
Originariamente inviato da marco.r Guarda i messaggi
Poi puoi usare una struttura piatta per la matrice oppure ,se vuoi mantenere quella attuale, prenderne dei segmenti da assegnare al vettore elle righe piuttosto che alle singole colonne.
Mm, puoi farmi un esempio? Grazie.
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 09-07-2011, 21:11   #8
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Potresti chiarirmi questo punto?
Ah pensavo potesse esserci un limite sul numero di memorie mappate, pero' guardando sembra non sia cosi'. Potrebbe cmq essere qualche altro limite impostato per processo. Ad esempio:
Quote:
RLIMIT_MEMLOCK
The maximum number of bytes of memory that may be locked into RAM. In effect this limit is rounded down to the nearest multiple of the system page size. This limit affects mlock(2) and mlockall(2) and the mmap(2) MAP_LOCKED operation. Since Linux 2.6.9 it also affects the shmctl(2) SHM_LOCK operation, where it sets a maximum on the total bytes in shared memory segments (see shmget(2)) that may be locked by the real user ID of the calling process. The shmctl(2) SHM_LOCK locks are accounted for separately from the per-process memory locks established by mlock(2), mlockall(2), and mmap(2) MAP_LOCKED; a process can lock bytes up to this limit in each of these two categories. In Linux kernels before 2.6.9, this limit controlled the amount of memory that could be locked by a privileged process. Since Linux 2.6.9, no limits are placed on the amount of memory that a privileged process may lock, and this limit instead governs the amount of memory that an unprivileged process may lock.
Potrebbe essere questo.

Quote:
Il discorso è un pò più complesso, in quanto sto allocando con la mmap per utilizzare la memoria in modalità intervealed tramite la libnuma, una libreria di gestione della memorai modalità NUMA, la quale prevede in questo caso che la memoria sia allocata con mmap o shmat. Tale memoria sarà condivisa poi da più threads.
Ok, quindi si tratta tutti di thread di uno stesso processo ? In tal caso la mia osservazione non fa testo.

Quote:
Mm, puoi farmi un esempio? Grazie.
Qualcosa tipo
Codice:
int nRows;
int nCols;
int size
...

size = nRows * sizeof(int*) + nRows*nCols*sizeof(int);
void* data=(int*) mmap(NULL, size, PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

int** array = (int**)data;
for ( int i=0; i< nRows; ++i )
{
    array[i] = (int*)(array+nRows) + i*nCols;
}
(potrebbe esserci qualche errore eh, controlla)
ovvero alloco un'unica zona di memoria e poi la suddivido cosi':
Codice:
+-------+--------+--------+-----+---
| array | riga 1 | riga 2 | ... |
+-------+--------+--------+-----+---
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 10-07-2011, 13:20   #9
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Ah pensavo potesse esserci un limite sul numero di memorie mappate, pero' guardando sembra non sia cosi'. Potrebbe cmq essere qualche altro limite impostato per processo. Ad esempio:

Potrebbe essere questo.
Mm, si, avevo visto questo limite. Ma controllando con ulimit -l ( che dovrebbe indicare proprio tale limite) dice che è settato "unlimited", quindi pare non dipenda da questo.

Quote:
Originariamente inviato da marco.r Guarda i messaggi
Ok, quindi si tratta tutti di thread di uno stesso processo ? In tal caso la mia osservazione non fa testo.
Si esatto.

Quote:
Originariamente inviato da marco.r Guarda i messaggi

Qualcosa tipo
Codice:
int nRows;
int nCols;
int size
...

size = nRows * sizeof(int*) + nRows*nCols*sizeof(int);
void* data=(int*) mmap(NULL, size, PROT_READ| PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

int** array = (int**)data;
for ( int i=0; i< nRows; ++i )
{
    array[i] = (int*)(array+nRows) + i*nCols;
}
(potrebbe esserci qualche errore eh, controlla)
ovvero alloco un'unica zona di memoria e poi la suddivido cosi':
Codice:
+-------+--------+--------+-----+---
| array | riga 1 | riga 2 | ... |
+-------+--------+--------+-----+---
Ok, buona idea. Quindi alloco un singolo array ma accedo all'elemento i-j-e-simo con array[i][j] se non ho capito male, giusto?

Io però ancora non ho ben chiaro su cosa cambi nell'allocare memoria di uno shared object tra la malloc e la mmap. Potresti chiarirmi questo punto? Grazie.

Ultima modifica di Unrue : 10-07-2011 alle 13:24.
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 10-07-2011, 14:00   #10
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Ok, buona idea. Quindi alloco un singolo array ma accedo all'elemento i-j-e-simo con array[i][j] se non ho capito male, giusto?
Si' esatto, quello che cambia e' solo che fai un'unica allocazione iniziale


Quote:
Io però ancora non ho ben chiaro su cosa cambi nell'allocare memoria di uno shared object tra la malloc e la mmap. Potresti chiarirmi questo punto? Grazie.
La memoria allocata con una malloc e' visibile solo all'interno del processo che l'ha allocata.
La memoria che ricevi con una mmap e' indirizzabile anche da altri processi.
Se vi deve accedere un processo esterno devi mapparla mediante file (altrimenti non hai modo di dire "voglio vedere _quella_ zona di memoria".
La mappatura anonima va bene quando prima mappi la memoria e poi fai le fork dei vari processi. La differenza rispetto ad una malloc in questo caso e' che dopo una fork la memoria ottenuta precedentemente da una malloc viene copiata ed e' distinta mentre quella ottenuta da una mmap e' effettivamente comune a tutti i processi.
Nel tuo caso hai dei thread che condividono tutto la stessa memoria per cui in sostanza dovrebbe cambiare poco. L'unica nota che mi viene in mente e' che se hai sotto una architettura numa, avere dei thread di uno stesso processo che girano su nodi differenti potrebbe non essere ideale: una parte della memoria viene condivisa tra i nodi e nel caso di scritture ottieni una sincronizzazione non voluta tra i nodi.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 10-07-2011, 19:40   #11
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Si' esatto, quello che cambia e' solo che fai un'unica allocazione iniziale



La memoria allocata con una malloc e' visibile solo all'interno del processo che l'ha allocata.
La memoria che ricevi con una mmap e' indirizzabile anche da altri processi.
Se vi deve accedere un processo esterno devi mapparla mediante file (altrimenti non hai modo di dire "voglio vedere _quella_ zona di memoria".
La mappatura anonima va bene quando prima mappi la memoria e poi fai le fork dei vari processi. La differenza rispetto ad una malloc in questo caso e' che dopo una fork la memoria ottenuta precedentemente da una malloc viene copiata ed e' distinta mentre quella ottenuta da una mmap e' effettivamente comune a tutti i processi.
Perfetto! Adesso ho capito

Quote:
Originariamente inviato da marco.r Guarda i messaggi
Nel tuo caso hai dei thread che condividono tutto la stessa memoria per cui in sostanza dovrebbe cambiare poco. L'unica nota che mi viene in mente e' che se hai sotto una architettura numa, avere dei thread di uno stesso processo che girano su nodi differenti potrebbe non essere ideale: una parte della memoria viene condivisa tra i nodi e nel caso di scritture ottieni una sincronizzazione non voluta tra i nodi.
Cosa intendi per nodi in questo caso?
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 10-07-2011, 23:56   #12
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Cosa intendi per nodi in questo caso?
Un insieme di processori della macchina "vicini" dal punto di vista della memoria. Un sistema NUMA non è come il classico SMP dove hai N processori che condividono tutta la memoria. Viene piuttosto suddiviso in un certo numero di nodi i quali hanno una loro memoria locale. Un nodo puo' accedere anhe al resto della memoria, ma con tempi di accesso piu' elevati
Sulle architetture x86 mi risulta che questo modus operandi sia presente solo sugli opteron e alcuni xeon bi/quadri processore, e comunque selezionabile da BIOS.
su che sistema stai lavorando ?
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 11-07-2011, 11:24   #13
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Un insieme di processori della macchina "vicini" dal punto di vista della memoria. Un sistema NUMA non è come il classico SMP dove hai N processori che condividono tutta la memoria. Viene piuttosto suddiviso in un certo numero di nodi i quali hanno una loro memoria locale. Un nodo puo' accedere anhe al resto della memoria, ma con tempi di accesso piu' elevati
Sulle architetture x86 mi risulta che questo modus operandi sia presente solo sugli opteron e alcuni xeon bi/quadri processore, e comunque selezionabile da BIOS.
su che sistema stai lavorando ?

Ok, la tua definizione di nodo coincide con la mia Sto lavorando su Linux. Facendo come suggerisci tu, la chiamata:

numa_interleave_memory fallisce se l'interleaving non parte dal primo elemento di array. Cioè, questo funziona:
Codice:
numa_interleave_memory(&array[0], 1, &numa_all_nodes);
Questo no:
Codice:
numa_interleave_memory(&array[1], 1, &numa_all_nodes);
Al di là della funzione numa_interleave_memory, che non so se conosci, in un array creato con mmap, c'è qualche differenza su come sono mappati in memoria array[0] e array[1]? Sembrerebbe di si..

Ultima modifica di Unrue : 11-07-2011 alle 11:28.
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 11-07-2011, 11:38   #14
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Ok, la tua definizione di nodo coincide con la mia Sto lavorando su Linux. Facendo come suggerisci tu, la chiamata:

numa_interleave_memory fallisce se l'interleaving non parte dal primo elemento di array. Cioè, questo funziona:
Codice:
numa_interleave_memory(&array[0], 1, &numa_all_nodes);
Questo no:
Codice:
numa_interleave_memory(&array[1], 1, &numa_all_nodes);
Al di là della funzione numa_interleave_memory, che non so se conosci, in un array creato con mmap, c'è qualche differenza su come sono mappati in memoria array[0] e array[1]? Sembrerebbe di si..

Dal manuale:
Quote:
numa_interleave_memory() interleaves size bytes of memory page by page from start on nodes specified in nodemask. The size argument will be rounded
up to a multiple of the system page size.
A naso direi che la memoria deve partire da un page boundary.
mmap ritorna memoria sempre mappata (in linux) all'inizio di una page, per cui array[0] e' all'inizio di una pagina, array[1] no.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 11-07-2011, 14:16   #15
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6146
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Dal manuale:

A naso direi che la memoria deve partire da un page boundary.
mmap ritorna memoria sempre mappata (in linux) all'inizio di una page, per cui array[0] e' all'inizio di una pagina, array[1] no.
Si vero, grazie mille
Unrue è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile iPhone 17 Pro: più di uno smartphone. &Eg...
Intel Panther Lake: i processori per i notebook del 2026 Intel Panther Lake: i processori per i notebook ...
Intel Xeon 6+: è tempo di Clearwater Forest Intel Xeon 6+: è tempo di Clearwater Fore...
4K a 160Hz o Full HD a 320Hz? Titan Army P2712V, a un prezzo molto basso 4K a 160Hz o Full HD a 320Hz? Titan Army P2712V,...
Recensione Google Pixel Watch 4: basta sollevarlo e si ha Gemini sempre al polso Recensione Google Pixel Watch 4: basta sollevarl...
Disney+ cambia: arriva Hulu, ma il servi...
Google annuncia Gemini Enterprise: l'IA ...
Battlefield 6 debutta tra code infinite ...
Gli iPhone di seconda mano dominano il m...
Pavel Durov (Telegram) lancia l'allarme:...
Occhiali Smart come lo smartphone: il fu...
Arriva NVIDIA GB300 NVL72, il cluster di...
Copilot si collega a OneDrive, Gmail e D...
Il Liquid Glass di iOS 26 è stato...
I biocarburanti fanno più danni d...
ELF, il Frankenstein di Mercedes che ant...
Da Kia arriva il passaporto per le batte...
The Elder Scrolls 6 renderà omagg...
YouTube dà una 'seconda chance' a...
Attacco hacker a Oracle E-Business Suite...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:20.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v