Formula for memory alignment
Looking through the kernel code, I found a formula for memory alignment:
aligned = ((operand + (alignment - 1)) & ~ (alignment - 1))
So, I even write a program to do this:
#include <stdio.h>
int main(int argc, char** argv) {
long long operand;
long long alignment;
if(argv[1]) {
operand = atol(argv[1]);
} else {
printf("Enter value to be aligned!\n");
return -1;
}
if(argv[2]) {
alignment = strtol(argv[2],NULL,16);
} else {
printf("\nDefaulting to 1MB alignment\n");
alignment = 0x100000;
}
long long aligned = ((operand + (alignment - 1)) & ~(alignment - 1));
printf("Aligned memory is: 0x%.8llx [Hex] <--> %lld\n",aligned,aligned);
return 0;
}
But I don't understand this logic at all. How it works?
source to share
Basically, the formula increments an integer operand
(address) to the next address aligned with alignment
.
Expression
aligned = ((operand + (alignment - 1)) & ~(alignment - 1))
basically the same as the formula is a little easier to understand:
aligned = int((operand + (alignment - 1)) / alignment) * alignment
For example, given operand (address) 102 and alignment 10, we get:
aligned = int((102 + 9) / 10) * 10
aligned = int(111 / 10) * 10
aligned = 11 * 10
aligned = 110
First, let's add the address 9
and get it 111
. Then, since our alignment is 10, we basically zero out the last digit, i.e.111 / 10 * 10 = 110
Note that for every 10 power equalization (i.e. 10, 100, 1000, etc.) we basically zero out the last digits.
On most processors, division and multiplication take much longer than bitwise operations, so let's go back to the original formula:
aligned = ((operand + (alignment - 1)) & ~(alignment - 1))
The second part of the formula only makes sense when the alignment is a power of 2. For example:
... & ~(2 - 1) will zero last bit of address.
... & ~(64 - 1) will zero last 5 bits of address.
etc
As with zeroing the last few digits of the address for cardinality 10 alignments, we zero out the last few bits for cardinality 2 alignments.
Hope this makes sense to you now.
source to share