PDA

View Full Version : [C] Problema MPI e matrici trasposte


Unrue
01-01-2007, 17:50
Salve,
sto facendo un programma che fa la matrice trasposta in modo parallelo. A tal proposito, ho definito una matrice 8x8 ed un'altra 2x8. Uso 4 processori:

float**matrice_nativa;
float**matrice_nativa_locale;
matrice_nativa= malloc(8*sizeof(float*));
matrice_nativa_locale=malloc(2*sizeof(float*));

for(i=0; i<2;i++)
{
matrice_nativa_locale[i]=malloc(8*sizeof(float));

}

for(i=0; i<8;i++)
{
matrice_nativa[i]=malloc(8*sizeof(float));

}

L'idea è che il processore 0 crea la matrice globale, poi con una Send invia una parte(due righe) ad ogni processore. Essi traspongono la loro parte e ritornano indietro il risultato. Ho un problema nell'invio della matrice globale però. L'implementazione è la seguente:

if(me==0)
{

for(i=0;i<4;i++)
{
MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD);

}
}

MPI_Recv(&matrice_nativa_locale[0][0],16,MPI_REAL,0,0,MPI_COMM_WORLD,&status);

La cosa strana è che,nonostante gli dica chiaramente di inviare 16 elementi ad ogni processore, ne invia solo 8. Ad esempio, per questa matrice di ingresso:

Matrice nativa :
[ 3.0 6.0 17.0 15.0 13.0 15.0 6.0 12.0 ]
[ 9.0 1.0 2.0 7.0 10.0 19.0 3.0 6.0 ]
[ 0.0 6.0 12.0 16.0 11.0 8.0 7.0 9.0 ]
[ 2.0 10.0 2.0 3.0 7.0 15.0 9.0 2.0 ]
[ 2.0 18.0 9.0 7.0 13.0 16.0 11.0 2.0 ]
[ 9.0 13.0 1.0 19.0 4.0 17.0 18.0 4.0 ]
[ 15.0 10.0 13.0 6.0 11.0 0.0 16.0 13.0 ]
[ 2.0 10.0 16.0 1.0 5.0 5.0 4.0 7.0 ]

Ottengo:

Matrice nativa locale dal processore : 0
[ 3.0 6.0 17.0 15.0 13.0 15.0 6.0 12.0 ]
[ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]
Matrice nativa locale dal processore : 2
[ 2.0 18.0 9.0 7.0 13.0 16.0 11.0 2.0 ]
[ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]
Matrice nativa locale dal processore : 1
[ 0.0 6.0 12.0 16.0 11.0 8.0 7.0 9.0 ]
[ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]
Matrice nativa locale dal processore : 3
[ 15.0 10.0 13.0 6.0 11.0 0.0 16.0 13.0 ]
[ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ]


Il programma in realtà è parametrico, non lavora ssolo su matrici 8x8, ma quadrate. Ho messo un numero secco per evitare di scrivere troppe cose, tanto il problema si presenta anche in questo caso. grazie a chiunque mi aiuti.

trallallero
02-01-2007, 08:07
scusa ma tu con questa istruzione
MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD);
secondo me stai passando 16 valori della stessa riga. Non conosco la funzione ma ad occhio sembra cosí.
Infatti gli passi il puntatore alla riga e il numero di valori (16) ... come fa la funzione a sapere che sono 8 valori per riga ???

Unrue
02-01-2007, 10:13
scusa ma tu con questa istruzione
MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD);
secondo me stai passando 16 valori della stessa riga. Non conosco la funzione ma ad occhio sembra cosí.
Infatti gli passi il puntatore alla riga e il numero di valori (16) ... come fa la funzione a sapere che sono 8 valori per riga ???

No, lui preleva 16 elementi a partire dalla posizione matrice_nativa[i*2][0]. Questo va bene. La funzione MPI_Send vuole un punto di inizio ed il numero di elementi da prelevare partenda da lì.

trallallero
02-01-2007, 10:59
No, lui preleva 16 elementi a partire dalla posizione matrice_nativa[i*2][0]. Questo va bene. La funzione MPI_Send vuole un punto di inizio ed il numero di elementi da prelevare partenda da lì.
Ogni riga ha il suo puntatore allocato dinamicamente quindi, per quel che ne so (poi interverrá qualche guru), non puoi considerare contigui i valori tra una riga e l'altra.

Io non mi azzarderei a passare 16 elementi che sono divisi in 2 righe allocate dinamicamente ad una funzione che vuole un indirizzo iniziale e il numero di elementi come parametri.

Unrue
02-01-2007, 11:05
Ogni riga ha il suo puntatore allocato dinamicamente quindi, per quel che ne so (poi interverrá qualche guru), non puoi considerare contigui i valori tra una riga e l'altra.

Io non mi azzarderei a passare 16 elementi che sono divisi in 2 righe allocate dinamicamente ad una funzione che vuole un indirizzo iniziale e il numero di elementi come parametri.

Beh, però il c alloca le matrici per righe, quindi due righe da 8 elementi equivalgono a 16 elementi consecutivi in memoria. Ad esempio,in una matrice 8x8, l'elemento (0,7) e (1,0) sono contigui.

trallallero
02-01-2007, 11:36
Beh, però il c alloca le matrici per righe, quindi due righe da 8 elementi equivalgono a 16 elementi consecutivi in memoria. Ad esempio,in una matrice 8x8, l'elemento (0,7) e (1,0) sono contigui.
da quel che so il C garantisce la contiguitá in un array (altrimenti va a farsi friggere la matematica dei puntatori) ma non tra le righe.
Infatti compila questo :

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>


int main()
{
float **matrice_nativa;

int i, j;

matrice_nativa = malloc(8*sizeof(float*));

for( i = 0; i < 8; i++)
matrice_nativa[i] = malloc(8*sizeof(float));


for( i = 0; i < 8; i++)
for( j = 0; j < 8; j++)
matrice_nativa[i][j] = i * j;


for( i = 0;i < 4; i++ )
MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD);



for( i = 0; i < 8; i++)
free(matrice_nativa[i]);

free(matrice_nativa);

return 0;
}


void MPI_Send( float *ppM, int Count )
{
int i;

for (i = 0; i < Count; i++ )
printf( "<%.0f> ", ppM[i] );

puts("");
}

Unrue
02-01-2007, 11:54
Dunque, le righe in c sono contigue in memoria, però ovviamente il c sa dove inizia e finisce una, quindi l'aritmetica dei puntatori è salva. Riguardo MPI_Send, è una funzione propria di MPI, non l'ho definita io. A me pare di ricordare che si possa fare come ho fatto io, altrimenti sarebbe un enorme spreco, in quanto si dovrebbe fare una MPi_Send per ogni riga della matrice, anche per inviare più righe allo stesso processore.

trallallero
02-01-2007, 12:16
Dunque, le righe in c sono contigue in memoria, però ovviamente il c sa dove inizia e finisce una, quindi l'aritmetica dei puntatori è salva. Riguardo MPI_Send, è una funzione propria di MPI, non l'ho definita io. A me pare di ricordare che si possa fare come ho fatto io, altrimenti sarebbe un enorme spreco, in quanto si dovrebbe fare una MPi_Send per ogni riga della matrice, anche per inviare più righe allo stesso processore.

io ti sto solo dimostrando che i valori sono contigui SOLO sulla singola riga.
Infatti ecco l'output del mio esempio:


< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1>
< 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2>
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3>
< 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4>
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5>
< 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6>
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7>
< 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8>

< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 2> < 2> < 2> < 2> < 2> < 2>
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 4> < 4> < 4> < 4> < 4> < 4>
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 6> < 6> < 6> < 6> < 6> < 6>
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 8> < 8> < 8> < 8> < 8> < 8>

la prima stampa é la matrice cosí come l'ho inizializzata.
La seconda stampa come fai tu. Una riga ogni 2 ma 16 elementi.
Puoi ben vedere che non corrisponde perfettamente. Gli elementi ci sono ma spostati

Ma puoi risolvere il problema facendo una matrice 4 X 16 ;)

Unrue
02-01-2007, 13:18
Grazie del chiarimento, però non capisco da cosa sia dato il numero di 0 che sono presenti tra una riga e l'altra e sopratutto perchè la MPI_Send invii solo una riga, e non due spostate come nel tuo esempio.

trallallero
02-01-2007, 13:28
Grazie del chiarimento, però non capisco da cosa sia dato il numero di 0 che sono presenti tra una riga e l'altra e sopratutto da dove escano fuori
giá ... ci stavo pensando anch'io :wtf:

visto che lavori abbastanza a basso livello ti potrebbe servire questo che mi son fatto per analizzare buffers e aree di memoria:

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#define WRAP_MSG_LEN 96

#define USAGE_STR "\n\n" \
"Visualizza un buffer (anche binario) nel seguente formato:\n" \
"\n" \
"¤···½····1····½· numero colonna\n" \
"----------------\n" \
" AbCd-+GhIjK carattere (se stampabile)\n" \
"----------------\n" \
"3333446462246464 carattere in\n" \
"CDEF01234DB789AB esadecimale\n\n" \
" trallallero 20 Gennaio 2005\n"


/* *\
"LOGGA" UN BUFFER pBuf (ANCHE BINARIO)
NEL SEGUENTE FORMATO:

¤···½····1····½· NUMERO COLONNA
----------------
ABCDEFGHIJK CARATTERE (SE STAMPABILE)
----------------
3333444444444444 CARATTERE IN
CDEF0123456789AB ESADECIMALE

\* */
int HexAlphaLogger( unsigned char *pBuf )
{
int i,
c,
Len,
IsLong = strlen(pBuf) > WRAP_MSG_LEN;

unsigned char pS[WRAP_MSG_LEN + 1];

if ( IsLong )
strncpy( (char *)pS, pBuf, WRAP_MSG_LEN );
else
strcpy ( (char *)pS, pBuf );

pS[WRAP_MSG_LEN] = 0x00;

Len = strlen( pS );

putchar( '\n' );

/* STAMPO I NUMERI */
for ( i = 1, c = 1; i < Len; i++ )
if ( i == 1 ) putchar( '¹' /*'¤'*/ );
else if ( i % 10 == 0 ) putchar( c++ + 48 );
else if ( i % 5 == 0 ) putchar( '½' );
else putchar( '·' );

putchar( '\n' );

/* STAMPO IL DIVISORIO */
for ( i = 0; i < Len; i++)
printf( "-" );
putchar( '\n' );

/* STAMPO IL CARATTERE SE ALPHA */
for ( i = 0; i < Len; i++)
printf( "%c", (isalpha(pS[i])) ? pS[i] : ' ' );
putchar( '\n' );

/* STAMPO IL DIVISORIO */
for ( i = 0; i < Len; i++)
printf( "-" );
putchar( '\n' );

/* STAMPO GLI ESADECIMALI IN VERT. */
for ( c = 0; c < 2; c++ )
{
for ( i = 0; i < Len; i++ )
{
unsigned int n = (unsigned int)pS[i];
unsigned char s[3];

sprintf( (char *)s, "%02X", n );

putchar( c ? s[1] : s[0] );
}
putchar( '\n' );
}

/* STAMPO IL DIVISORIO */
for ( i = 0; i < Len; i++)
printf( "-" );
putchar( '\n' );

/* STAMPO GLI ESADECIMALI IN VERT. */
for ( c = 0; c < 2; c++ )
{
for ( i = 0; i < Len; i++ )
{
unsigned int n = (unsigned int)pS[i];
unsigned char s[3];

sprintf( (char *)s, "%02i", n );

putchar( c ? s[1] : s[0] );
}
putchar( '\n' );
}

/* RICORSIONE SE MSG LUNGO */
if ( IsLong )
HexAlphaLogger( pBuf + WRAP_MSG_LEN );

putchar( '\n' );
}

/*------------------------------*\
\*------------------------------*/
void main( int argc, char **argv )
{
if ( argc == 1 )
printf( "%s SINTASSI: <%s> <buffer> %s", argv[0], argv[0], USAGE_STR );
else
{
int i = 1;

while ( i < argc )
HexAlphaLogger( (unsigned char *)argv[i++] );
}
}

EDIT: ovviamente "trallallero 20 Gennaio 2005" l'ho cambiato adesso (trallallero é nato a Maggio 2005), c'era il mio nome che ho tolto per privacy :D

Unrue
02-01-2007, 14:03
Grazie infinite, gli darò un'occhiata. Nel frattempo seguo il tuo consiglio sulla matrice 4x16 :)

Unrue
02-01-2007, 14:48
giá ... ci stavo pensando anch'io :wtf:

Non è che tra una riga e l'altra in memoria inserisce dei "terminatori di riga" chiamiamoli cosi'? Ho provato con una matrice 16X16 e vengono sempre fuori due zeri tra ogni riga.

trallallero
02-01-2007, 15:18
Non è che tra una riga e l'altra in memoria inserisce dei "terminatori di riga" chiamiamoli cosi'? Ho provato con una matrice 16X16 e vengono sempre fuori due zeri tra ogni riga.
ci vorrebbe qualche guru del C ... son tutti in vacanza :fagiano:

Qu@ker
02-01-2007, 16:59
Sulla falsariga del codice di Trallallero:

[qu@ker tmp]$ ./allineamento
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> indirizzo iniziale: 0x601060
< 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> indirizzo iniziale: 0x601090
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> indirizzo iniziale: 0x6010c0
< 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> indirizzo iniziale: 0x6010f0
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> indirizzo iniziale: 0x601120
< 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> indirizzo iniziale: 0x601150
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> indirizzo iniziale: 0x601180
< 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> indirizzo iniziale: 0x6011b0

|00| |04| |08| |0c| |10| |14| |18| |1c| |20| |24| |28| |2c| |30|
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 0> < 0> < 2> < 2> < 2> < 2>
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 0> < 0> < 4> < 4> < 4> < 4>
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 0> < 0> < 6> < 6> < 6> < 6>
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 0> < 0> < 8> < 8> < 8> < 8>
[qu@ker tmp]$ uname -m
x86_64
[qu@ker tmp]$ info libc Aligned 2>&1 | sed -ne '5,9p'
3.2.2.7 Allocating Aligned Memory Blocks
........................................

The address of a block returned by `malloc' or `realloc' in the GNU
system is always a multiple of eight (or sixteen on 64-bit systems).
[qu@ker tmp]$

trallallero
03-01-2007, 14:05
Sulla falsariga del codice di Trallallero:

[qu@ker tmp]$ ./allineamento
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> indirizzo iniziale: 0x601060
< 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> indirizzo iniziale: 0x601090
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> indirizzo iniziale: 0x6010c0
< 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> indirizzo iniziale: 0x6010f0
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> indirizzo iniziale: 0x601120
< 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> indirizzo iniziale: 0x601150
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> indirizzo iniziale: 0x601180
< 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> indirizzo iniziale: 0x6011b0

|00| |04| |08| |0c| |10| |14| |18| |1c| |20| |24| |28| |2c| |30|
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 0> < 0> < 2> < 2> < 2> < 2>
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 0> < 0> < 4> < 4> < 4> < 4>
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 0> < 0> < 6> < 6> < 6> < 6>
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 0> < 0> < 8> < 8> < 8> < 8>
[qu@ker tmp]$ uname -m
x86_64
[qu@ker tmp]$ info libc Aligned 2>&1 | sed -ne '5,9p'
3.2.2.7 Allocating Aligned Memory Blocks
........................................

The address of a block returned by `malloc' or `realloc' in the GNU
system is always a multiple of eight (or sixteen on 64-bit systems).
[qu@ker tmp]$

quindi ?

Qu@ker
03-01-2007, 20:41
Scusa, ho postato il pezzo sbagliato! :cool:

[qu@ker tmp]$ ./allin
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> indirizzo iniziale: 0x601060 spazio utilizzabile: 40 (0x28)
< 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> indirizzo iniziale: 0x601090 spazio utilizzabile: 40 (0x28)
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> indirizzo iniziale: 0x6010c0 spazio utilizzabile: 40 (0x28)
< 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> indirizzo iniziale: 0x6010f0 spazio utilizzabile: 40 (0x28)
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> indirizzo iniziale: 0x601120 spazio utilizzabile: 40 (0x28)
< 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> indirizzo iniziale: 0x601150 spazio utilizzabile: 40 (0x28)
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> indirizzo iniziale: 0x601180 spazio utilizzabile: 40 (0x28)
< 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> indirizzo iniziale: 0x6011b0 spazio utilizzabile: 40 (0x28)

|00| |04| |08| |0c| |10| |14| |18| |1c| |20| |24| |28| |2c| |30|
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 0> < 0> < 2> < 2> < 2> < 2>
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 0> < 0> < 4> < 4> < 4> < 4>
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 0> < 0> < 6> < 6> < 6> < 6>
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 0> < 0> < 8> < 8> < 8> < 8>
[qu@ker tmp]$

Lo spazio utilizzabile è ricavato con malloc_usable_size() (in malloc.h), che riporta quanti byte di un blocco di memoria, ottenuto con malloc(), si possono effettivamente utilizzare a causa dei vincoli di allineamento e di grandezza minima.

trallallero
03-01-2007, 20:49
Scusa, ho postato il pezzo sbagliato! :cool:

[qu@ker tmp]$ ./allin
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> indirizzo iniziale: 0x601060 spazio utilizzabile: 40 (0x28)
< 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> indirizzo iniziale: 0x601090 spazio utilizzabile: 40 (0x28)
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> indirizzo iniziale: 0x6010c0 spazio utilizzabile: 40 (0x28)
< 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> indirizzo iniziale: 0x6010f0 spazio utilizzabile: 40 (0x28)
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> indirizzo iniziale: 0x601120 spazio utilizzabile: 40 (0x28)
< 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> indirizzo iniziale: 0x601150 spazio utilizzabile: 40 (0x28)
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> indirizzo iniziale: 0x601180 spazio utilizzabile: 40 (0x28)
< 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> indirizzo iniziale: 0x6011b0 spazio utilizzabile: 40 (0x28)

|00| |04| |08| |0c| |10| |14| |18| |1c| |20| |24| |28| |2c| |30|
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 0> < 0> < 2> < 2> < 2> < 2>
< 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 0> < 0> < 4> < 4> < 4> < 4>
< 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 0> < 0> < 6> < 6> < 6> < 6>
< 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 0> < 0> < 8> < 8> < 8> < 8>
[qu@ker tmp]$

Lo spazio utilizzabile è ricavato con malloc_usable_size() (in malloc.h), che riporta quanti byte di un blocco di memoria, ottenuto con malloc(), si possono effettivamente utilizzare a causa dei vincoli di allineamento e di grandezza minima.
questo dimostra che non si possono considerare contigue le righe della matrice :yeah:

però c'è qualcosa che non capisco sulla quantità di memoria allocata, visto che sono float :wtf:
ma per evitare di dire stronzate, visto che son parecchio stanco, rimando a domani mattina ... in pratica la stronzata la dirò domani :D

Unrue
03-01-2007, 21:35
Infatti è strano quel 40.. Riguardo le righe contigue invece torna:l'indirizzo iniziale della prima riga è 0x601060, della seconda è indirizzo iniziale: 0x601090 . La differenza è di 30 in esadecimadecimale, ovvero 48 byte. Se fossero contigue,ovrebbe essere, 4 bytes*8 =32 bytes . I 16 Bytes in più sono dati dai 4 zeri( 4 double) che inserisce lui tra una riga e l'altra

trallallero
04-01-2007, 07:43
Infatti è strano quel 40.. Riguardo le righe contigue invece torna:l'indirizzo iniziale della prima riga è 0x601060, della seconda è indirizzo iniziale: 0x601090 . La differenza è di 30 in esadecimadecimale, ovvero 48 byte. Se fossero contigue,ovrebbe essere, 4 bytes*8 =32 bytes . I 16 Bytes in più sono dati dai 4 zeri( 4 double) che inserisce lui tra una riga e l'altra
ah ecco, mi sembrava infatti che non tornassero i conti ieri sera ...
Forse quei 4 in piú li aggiunge in automatico per i programmatori piú distratti che hanno il vizio di sforare gli array :asd:

PS: da me i double sono 8 bytes quindi penso tu intendessi 4 floats ;)

Unrue
04-01-2007, 13:03
Si si volevo dire floats, era tardi anche per me :D Mi piacerebbe davvero sapere a cosa cavolo servono quegli zeri, se fossero solo un terminatore di riga sarebbe rischioso, metti che ho 4 zeri in una mia riga. Boh..

trallallero
04-01-2007, 13:12
Si si volevo dire floats, era tardi anche per me :D Mi piacerebbe davvero sapere a cosa cavolo servono quegli zeri, se fossero solo un terminatore di riga sarebbe rischioso, metti che ho 4 zeri in una mia riga. Boh..
calcola che quegli zeri noi non dovremmo neanche sapere se ci sono o no perché sono messi in un'area di memoria per noi non accessibile: se tu allochi per 10 e poi vai a mettere il naso in 11 e 12 non ti puoi lamentare se il SO s'incazza :read: