[En-Nut-Discussion] Improvement for faster mounting of large SD cards
Malte Marwedel
m.marwedel at onlinehome.de
Tue Mar 2 12:52:42 CET 2010
Rob van Lieshout (PragmaLab) schrieb:
> Mixing up the code like you did by saving calls doesn't sound like a good
> idea to me and I would not encourage you to put the code in NutOS. The
> FS-module in the current NutOS benefits from functional separated parts
> within that module.
> I did not found the time yet to optimize the counting of the free clusters
> but it sure is on my list.
I later realized, that my improvement only speed up the mounting
process, but not the time needed for the first write. A lot CPU time is
used by the
static void PhatTableLoc(PHATVOL * vol, uint32_t clust, int tabnum,
uint32_t * sect, uint32_t * pos)
{
uint32_t tabpos = clust * 4;
*sect = vol->vol_tab_sect[tabnum] + tabpos / vol->vol_sectsz;
*pos = tabpos % vol->vol_sectsz;
}
because for every PhatTableLoc() calculation, the function __udivmodsi4
is called twice (each call needs 604 CPU clocks). This alone consumes
1/3 of the CPU time for finding free clusters on an AVR.
By assuming that vol_sectsz is always something 2^n this could be made a
lot faster. (Anyone using a memory where this is not the case?)
static void PhatTableLocNew(PHATVOL * vol, uint32_t clust, int tabnum,
uint32_t * sect, uint32_t * pos)
{
uint32_t tabpos = clust * 4;
uint16_t sectsz = vol->vol_sectsz;
*sect = tabpos;
while(sectsz > 1) {
*sect >>= 1;
sectsz >>= 1;
}
*sect += vol->vol_tab_sect[tabnum];
*pos = tabpos & ((vol->vol_sectsz)-1);
}
This does not make mounting as fast as my first suggestion, but does not
mix up the functional separation and improves the time for the first
write too.
To show that my code works, I ran a test program
int main(void) {
PHATVOL vol;
vol.vol_tab_sect[0] = 42;
uint32_t clust, sectsz;
for (sectsz = 1; sectsz < 16000; sectsz *= 2) {
vol.vol_sectsz = sectsz;
printf("\rtesting %i sector size\r", sectsz);
fflush(stdout);
for (clust = 0; clust < 10000000; clust++) {
uint32_t poso, posn, secto, sectn;
PhatTableLoc(&vol, clust, 0, §o, &poso);
PhatTableLocNew(&vol, clust, 0, §n, &posn);
if ((secto != sectn) || (poso != posn)) {
printf("Fail: sect: should %u is %u, pos: should %u is %u\n", secto,
sectn, poso, posn);
return 1;
}
}
}
puts("Test success ");
return 0;
}
on my computer.
Malte
More information about the En-Nut-Discussion
mailing list