windows - Effektiv sparsom adgang til stor memory-mapped fil

Indlæg af Hanne Mølgaard Plasc

Problem



Vi har billeddata i en stor fil (f.eks. 700 MB). Filerne er hukommelse kortlagt på Windows 7 64-bit.


Nogle operationer på billeddata involverer os at læse et par bytes fra hver linje af billedet. Dette kan være langsomt - ingen linje er større end en side, så vi får en sidefejl for hver linje, selvom vi kun læser et par bytes. Der er ingen måde vi kan se på at komme rundt i denne nuværende implementering, men vi vil gerne sørge for, at vi kan presse mest ud af disksystemet.


For at opnå den bedst mulige ydelse håber vi, at vi kan hint på VM-systemet for at hente den næste billedlinje (muligvis forårsage en sidefel), mens vi behandler data i den nuværende. Dette ville parallelisere vores behandling og sidefejlene. Der ser ikke ud til at være en indlysende måde at gøre dette på Windows!


Så spørgsmålene:



  • Er der tilsvarende i Windows 7 til madvise( MADV\_WILLNEED )?

  • Er der en måde at asynkront røre ved en side, der udløser en side
    fejl uden at vente på, at siden bliver tilgængelig?



Den rigtige langsigtede løsning er at gemme vores data på en anden måde (fx i fliser), men vi kan ikke gøre det lige nu. Vi skal også holde den hukommelseskortede tilgang lige nu.

Bedste reference


Jeg tror ikke, du kan hint VM-systemet, men du kan forudindlæse data bare ved at indlæse næste linjedata, mens du behandler tidligere. Du kan gøre dette parallelt med behandlingen. Du skal nok hente mere end 1 foran, da behandlingen sandsynligvis er meget hurtigere end læsning fra filen.


Dette passer faktisk ret pænt ind i producent-forbrugermønster. Gør billedlæseren og dataprocessoren køre på separate tråde og brug en slags blokering af samling (som C # BlockingCollection) med kapacitetsgrænse for at videregive data fra læseren til processoren.

Andre referencer 1


Selvom dette er noget gammelt emne allerede, giver jeg et praktisk eksempel på en implementering, som kun skal bruges som designreference, hvis du forstår det store billede godt nok.


Vi havde en udfordring i en 'big data' telco-applikation, hvor vi ny bedre end virtuel hukommelsesleder, hvilke sider der skal indlæses i fra sparsomme 'store filer'. Hvad vi gjorde var at vi havde en dedikeret tråd ('inmemadvisor') for at modtage 'behov' -anmodninger, som hver havde en prioritet. Denne tråd opretholder den prioriterede liste over anmodninger og sender hukommelsestestet 'hints' til pulje af tråde, hvor størstedelen af ​​tråde håndterer høj prioritetsanmodninger og den mindste del af puljen håndterer laveste prioritet (du får sikkert ideen).


Så har vi parametre til at styre antallet af tråde i poolen og nogle andre nifty detaljer.


Fordele ved denne implementering er:



  • Vi overgår 10x VMs standardpersonsmodel (i Windoze Server 2008/2012)

  • så længe paging bliver 'blød', og vi kan glemme de data, vi ikke har brug for igen (ingen øjeblikkelig brug for at indlægge en hård fejl), er resultatet bedre end godt.

  • Vi kan bruge hele ledig gratis fysisk RAM-hukommelse til at fremskynde beregningen

  • Hver ny MB hukommelse du tilføjer kan øge ydeevnen



Ulemper:



  • Hvis du løber tør for RAM (lokalitet brudt), vil ydeevnen være en gris ... det ville være det samme selv uden denne implementering

  • Dette kræver noget omhyggeligt design og god implementering, der er værd at gøre det

  • I nogle programmer skal du muligvis tilføje yderligere overvågnings- og kontrollogik for at kontrollere 'inmemadvisor' for at være en god borger



Så kort sagt: Dette er noget, man heller ikke ville gøre, men på den anden side er det de ting, der gør programmeringen en positiv udfordring ;-) Btw: Vores implementering slår Linux madvice () i performance med vores ansøgning, men er ikke så generisk som den er.


Skål,//Jari