I have a memory allocator which allocates in blocks. Each next block size is the previous size plus the page size. Units to store in such blocks are 26 bytes in size, for example, but they may be of any size as long as it’s less than the page size. Therefore, there will usually be some leftover bytes at the end of each block, which introduces an error accumulation when calculating the cumulative number of units up to a certain block N. The goal is to calculate this correctly for any given block index without having to loop through all previous blocks to sum up their unit counts. Is there a way to precalculate some values or tables at compile time for each specific page size and unit size in order to correct this accumulated error and obtain the accurate number of units?
Here’s an example code which calculates the values incorrectly and displays the correct values next to them, as they were found during iteration:
void LogTestFlt(void)
{
const double groupSize = 4096;
const double unitSize = 26;
const double scaleFactor = groupSize / unitSize; // NOTE: Each group will have different amount of leftover bytes which will accumulate the error.
unsigned int cumul = 0;
printf("|%-14s|%-14s|%-14s|n", "WRONG","CORRECT","LEFTOVER");
printf("|%-14s|%-14s|%-14s|n", "--------------","--------------","--------------");
for(int group=1;group < 32;group++)
{
double previousCumulativeUnits = ((group - 1) * group * scaleFactor) / 2.0; // NOTE: Incorrect! Need to correct the accumulated error somehow.
unsigned int leftover = ((unsigned int)groupSize * group) % (unsigned int)unitSize;
printf("|%-14f|%-14u|%-14u|n", previousCumulativeUnits,cumul,leftover);
cumul += (groupSize * group) / unitSize; // This is the correct value
}
}
The result will be:
WRONG | CORRECT | LEFTOVER |
---|---|---|
0.000000 | 0 | 14 |
157.538462 | 157 | 2 |
472.615385 | 472 | 16 |
945.230769 | 944 | 4 |
1575.384615 | 1574 | 18 |
2363.076923 | 2361 | 6 |
3308.307692 | 3306 | 20 |
4411.076923 | 4408 | 8 |
5671.384615 | 5668 | 22 |
7089.230769 | 7085 | 10 |
8664.615385 | 8660 | 24 |
10397.538462 | 10392 | 12 |
12288.000000 | 12282 | 0 |
14336.000000 | 14330 | 14 |
16541.538462 | 16535 | 2 |
18904.615385 | 18898 | 16 |
21425.230769 | 21418 | 4 |
24103.384615 | 24096 | 18 |
26939.076923 | 26931 | 6 |
29932.307692 | 29924 | 20 |
33083.076923 | 33074 | 8 |
36391.384615 | 36382 | 22 |
39857.230769 | 39847 | 10 |
43480.615385 | 43470 | 24 |
47261.538462 | 47250 | 12 |
51200.000000 | 51188 | 0 |
55296.000000 | 55284 | 14 |
59549.538462 | 59537 | 2 |
63960.615385 | 63948 | 16 |
68529.230769 | 68516 | 4 |
73255.384615 | 73242 | 18 |
Victor S. is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
6