I am analyzing the effect of allocation across virtual pages while creating a 2-D array of dimension PageSize x PageSize. My machine's page size is 4096. I have an array of 4096 integer pointers(columns), pointing to 4096 integers(rows).
I want to begin the allocation for the first integer pointer at a new virtual page. How can I identify if the current memory location is a new page or not? Once, I have identified that, I believe I can write some garbage values and move the pointer to a new virtual page. This is how I allocate the array.
array = malloc(ncolumns * sizeof(int *));
for(j = 0; j < ncolumns; j++)
{
array[j] = malloc(nrows * sizeof(int));
if(array[j] == NULL)
{ reportError(8);}
}
If you know your page size, you can allocate a sufficiently sized portion of memory that will guarantee that some portion of the newly allocated memory is aligned on a page boundary. You will need to allocate at least 8192 bytes of memory to guarantee that you will have 4096 bytes aligned on a 4096 byte boundary.
For example, if you call malloc
and it returns to you an offset aligned to 0xDEAD1001
(4097), you will need to go to the next page at memory address 0xDEAD2000
to get to a 4096 byte alignment. Then, you'll need at least 4096 bytes of contiguous space. Hence, the need to allocate 8192 bytes.
To get a 4k byte aligned memory location, you can add 4095 to the address returned by malloc
and mask the last 3 bytes.
void *mem = malloc(8192);
void *ptr = ((void *)mem+0x0FFF) & ~ (void *)0x0FFF;
Edit: Make sure to keep a pointer to the original memory allocated, so you can later turn around and use it to call free()
.
Suppose this time, malloc returned 0xDEAD000F
.
0xDEAD000F + 0x0000FFF = 0xDEAD100E
0xDEAD100E & ~0x0000FFF = 0xDEAD1000
If you don't want to do all this messy pointer arithmetic, I think you could just use posix_memalign
. Check it out here. If you are on a different platform, I'm sure there are similar memory alignment services available.