Autor Wątek: Przyoptymalizowanie operacji wczytania pliku z dysku  (Przeczytany 2799 razy)

Offline fitt

  • Użytkownik

# Marzec 29, 2013, 12:51:53
Czy sa jakies sposoby na 'przyoptymalizowanie' operacji wczytania pliku z dysku. (przede wszystkim interesuje mnie platforma windows) Czy sa jakies
tricki pozwalajace przyspieszyć ta operacje chocby
o jakis procent (jakies szybsze api) czy tez
nie? co jest najszybsze do wczytywania plikow?
 

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xender

  • Użytkownik

# Marzec 29, 2013, 13:29:42
Tricków nie ma. Są poprawne sposoby obchodzenia się z I/O ;).

Nie używaj formatowanego wejścia, bo jest bardzo wolne - wczytuj duże kawałki pliku na raz i obrabiaj w pamięci. Tyczy się to szczególnie danych binarnych.

Offline Xion

  • Redaktor
    • xion.log

# Marzec 29, 2013, 13:44:10
Cytuj
wczytuj duże kawałki pliku na raz i obrabiaj w pamięci
Jeśli to rzeczywiście pomaga, to czemu nie używać po prostu memory mapped files?

Offline Xirdus

  • Redaktor

# Marzec 29, 2013, 13:44:29
Jeśli chodzi o gry komputerowe, to czas wczytywania danych z pliku jest jednym z najmniejszych problemów (chyba że robisz cały świat jako jeden ciągły teren bez żadnych loadingów (GTA, Skyrim, inne sandboxy)).

Offline fitt

  • Użytkownik

# Marzec 29, 2013, 13:56:08
Tricków nie ma. Są poprawne sposoby obchodzenia się z I/O ;).

Nie używaj formatowanego wejścia, bo jest bardzo wolne - wczytuj duże kawałki pliku na raz i obrabiaj w pamięci. Tyczy się to szczególnie danych binarnych.

Dokonałem pewnych prostych testów i wyniki mnie zszokowały :U (mam w domu naprawde starego kompa i stary dysk tak ze to sa dane dla mojego sprzetu, mam nadzieje ze nic z testem nie zbabrałem ale chyba nie)

wczytanie pilku 1MB przec fgetc - mw 11 milisekund    (powtarzane kilka razy, wiec z cache)


pierwszy szok bo mz jest to nieslychanie szybko, wydawalo mi sie ze to powinno byc z 10 razy wolniej

wczytanie pilku 300 bajtow przec fgetc - mw 0.2 milisekundy



wczytanie pilku 10MB przec fgetc - mw 120 milisekundy (kolene uruchomienia) - pierwsze uruchomienie 1.2 sekundy


szybko, widac ze z cache działa 10x szybciej niz
bez

wczytanie pilku 1MB przec fread - mw 3 ms  (kolene uruchomienia)


kojejny szok, wczytywanie przez fread jest 3-4 razy szybsze niz przez fgetc - w zyciu bym sie  nie spodziewal bo przeciez wydaje sie ze fgetc mozna zrobic jako b lekki wrapper na fread i powinno byc to samo a tu tymczasem jednak nie :/

wczytanie pilku 10MB przec fread - mw 31 ms  (kolene uruchomienia)


« Ostatnia zmiana: Marzec 29, 2013, 13:59:02 wysłana przez fitt »

Offline Avaj

  • Użytkownik

  • +1
# Marzec 29, 2013, 14:47:07
ee? fgetc wczytuje po jednym znaczku a fread może za jednym zamachem cały plik łyknąć, nie dziwne, że jest szybszy

Offline ShadowDancer

  • Redaktor

  • +2
# Marzec 29, 2013, 14:48:43
VFS przyśpieszy trochę wczytywanie dużej ilości plików.

Offline Witek9002

  • Użytkownik

# Marzec 29, 2013, 15:43:43
Możesz jeszcze poeksperymentować z CreateFile(). O jedną warstwę API mniej, poza tym możesz tam ustawiać dodatkowe flagi np. FILE_FLAG_SEQUENTIAL_SCAN, przez co masz większą kontrolę nad wczytywaniem pliku.

Offline fitt

  • Użytkownik

# Marzec 29, 2013, 15:51:16
Możesz jeszcze poeksperymentować z CreateFile(). O jedną warstwę API mniej, poza tym możesz tam ustawiać dodatkowe flagi np. FILE_FLAG_SEQUENTIAL_SCAN, przez co masz większą kontrolę nad wczytywaniem pliku.

sprawdziłem dla

    const int tab_max = 11000000;
    static char tab[tab_max];

    DWORD counter = 0;

   HANDLE hFile = CreateFile("file.dat",               // file to open
                       GENERIC_READ,          // open for reading
                       FILE_SHARE_READ,       // share for reading
                       NULL,                  // default security
                       OPEN_EXISTING,         // existing file only
                       FILE_ATTRIBUTE_NORMAL, // normal file
                       NULL);                 // no attr. template

    if (hFile == INVALID_HANDLE_VALUE)
       ERROR_("file not found");


    if( FALSE == ReadFile(hFile, tab, tab_max, &counter, NULL) )
    {
        ERROR_("file read error");
       CloseHandle(hFile);
        return;
    }

    CloseHandle(hFile);


I jest mw tak samo tak dla fread, na ile mozna to dokladnie sprawdzic bo czasy oscylują a sredniej nie liczylem - ale mw to samo co fread

//add

Dododanie FILE_FLAG_SEQUENTIAL_SCAN robi z cacheowych 31 ms około 100, 200 ms a czy robi to tez z niecacheowych 1200 mz to nie wiem bo jakos nie chce mi sie recznie probwac rozwalac cache, a probowanie wylaczenia go programowo nie działa (jak właczam FILE_FLAG_NO_BUFFERING to create file zwraca bład :c  )
« Ostatnia zmiana: Marzec 29, 2013, 16:15:53 wysłana przez fitt »

Offline Xirdus

  • Redaktor

# Marzec 30, 2013, 01:13:23
Temat zamykam, bo problem jest, że tak powiem, wyimaginowany, więc dyskusja zbędna, a autor wątku to nowe konto zbanowanego usera, o czym napisano już parę wiadomości (które z przyjemnością skasowałem).