2008-10-10 17 views
5

Piszę małą aplikację, która zapisuje obrazy JPEG w stałej cenie na karcie SD. Wybieram system plików EXT3, ale to samo zachowanie zaobserwowano w systemie plików EXT2.Wydajność zapisu na karcie SD

Moje pisanie pętli wygląda następująco:

get_image() 
fwrite() 
fsync() 

Albo tak:

get_image() 
fopen() 
fwrite() 
fsync() 
fclose() 

ja również wyświetlić niektóre statystyki czasowe, i widzę, mój program jest jakiś zablokowany przez kilka sekund. Średnia stawka jest nadal dobra, ponieważ jeśli zatrzymam przychodzące obrazy do kwadratu, to napiszę wiele obrazów w krótkim czasie po takim przeciągnięciu. Czy wiesz, czy jest to problem z systemem operacyjnym, czy jest związany z samą kartą SD? Jak mogę zbliżyć się do czasu rzeczywistego? Nie potrzebuję silnego czasu rzeczywistego, ale utknięcie w miejscu na kilka sekund jest nie do przyjęcia.

Pewna precyzja: Tak, konieczne jest fsync po każdym pliku, ponieważ chcę, aby obraz był na dysku, a nie w jakimś buforze użytkownika lub jądra. Bez fsyncing, mam znacznie lepszą wydajność, , ale nadal niedopuszczalne przeciągnięcie. Nie sądzę, że jest to problem z buforowaniem, ponieważ pierwszy błąd ma miejsce po zapisaniu 50 MB. I zgodnie ze stroną man, fsync jest właśnie tutaj, aby upewnić się, że nie ma buforowanych danych.

Precyzja dotycząca średniej szybkości zapisu: Piszę w tempie, które jest zrównoważone przez kartę, z której korzystam. Jeśli ułożę obraz przychodzący oczekując na ukończenie fsync, to po tej przerwie szybkość transferu zapisu wzrośnie, a ja szybko powrócę do średniej stawki. Średnia szybkość transferu wynosi około 1,4 MB/s.

systeme to nowoczesny laptop z systemem Ubuntu 8.04 z Kee stanie (2.6.24.19)

Odpowiedz

1

Nie jestem kompetentny w tej dziedzinie, ale objawy opisujesz brzmi strasznie dużo jak zapełniać bufor. Być może wypełniasz bufor w programie piszącym pliki lub w urządzeniu we/wy komunikującym się z samą kartą SD. Następnie musisz poczekać, aż faktycznie zapisze dane na karcie (opróżniając bufor), zanim będziesz mógł napisać więcej. Karty SD nie są szczególnie szybkimi programami piszącymi. Jeśli możesz znaleźć sposób sprawdzenia, czy dane rzeczywiście są zapisywane na karcie podczas tych pauz, to zweryfikowałbym moją teorię. Niektóre czytniki kart mają diodę LED, która miga podczas uzyskiwania dostępu do danych - to prawdopodobnie byłby dobry wskaźnik.

prostu przeczucie ... wziąć go z solą :)

3

Czy konieczne fsync() po każdym pliku? Możesz mieć więcej szczęścia, pozwalając systemowi zdecentralizowanemu zdecydować, kiedy nadejdzie odpowiedni czas, aby wypisać wszystkie obrazy z kolejki na kartę SD (amortyzując początkowy koszt manipulowania systemem plików kart SD na wielu obrazach, zamiast ponosić je za każdy obraz).

Czy możesz podać więcej szczegółów na temat swojej platformy? Wolne czasy I/O mogą mieć związek z innymi procesami w systemie, wolnym kontrolerem I/O itp.

Można również rozważyć użycie systemu plików bardziej dostosowanego do działania pamięci flash. FAT32 jest bardziej popularny niż extN, ale system plików skonstruowany specjalnie dla SD może być również w kolejności. JFFS jest tego dobrym przykładem.Prawdopodobnie uzyskasz lepszą wydajność dzięki systemowi plików zaprojektowanemu do flashowania (w przeciwieństwie do wirujących nośników magnetycznych), a także uzyskasz lepsze właściwości niwelowania zużycia (a tym samym żywotność/niezawodność urządzenia).

+0

pleaes pamiętać jffs i tym podobne nie są dobrym pomysłem dla niektórych urządzeń flash, takich jak CompactFlash, co robić swoje wypoziomowanie zużycie. – Hasturkun

+1

Czy to zły pomysł, czy też niwelowanie zużycia CompactFlash po prostu neguje zalety JFFS? To szczere pytanie, nie mam pojęcia. Zgadzam się, że jest to zdecydowanie lepszy wybór dla "surowych" urządzeń flash. –

2

Niektóre dyski Flash mają bardzo niską wydajność zapisu (szczególnie tanie marki). Więc jeśli mierzysz prędkość zapisu swojej aplikacji (w tym czas wymagany na fsync), co otrzymujesz? Może to z łatwością być rzędu kilku megabajtów na sekundę - tylko dlatego, że sprzęt nie działa lepiej.

Co więcej, pisanie może być znacznie wolniejsze, jeśli napiszesz wiele małych bloków zamiast jednego dużego bloku (pamięć flash może uzyskać około 10 zapisów na sekundę, w złych przypadkach). Jest to prawdopodobnie coś, co może być złagodzone przez bufor jądra, więc używanie fsync często może spowolnić pisanie ...

Przy okazji. zmierzyłeś wydajność zapisu na FAT32? Zgaduję, że jest to mniej więcej tak samo, ale jeśli nie, to może jest jeszcze dostępna optymalizacja?

1

Może to pomoże - Benchmarking Filesystems:

... Byłem bardzo zaskoczony, jak powolny ext3 było ogólnie, jak wiele dystrybucji korzystać z tego systemu plików jako domyślny system plików ...

i "ext3 fsync batching":

... Łata mierzy czas potrzebny do popełnienia transakcję na dysk, i śpi na podstawie prędkości bazowego dysku.

4

Spróbuj otworzyć plik za pomocą O_DIRECT i wykonaj buforowanie na poziomie aplikacji.

Spotkaliśmy podobny problem podczas wdrażania funkcji PVR (Personal Video Record) w STB Box. Sztuczka O_DIRECT spełniła naszą potrzebę w ostateczności. (*)

Bez O_DIRECT. Dane z write() zostaną najpierw zapisane w pamięci podręcznej bufora jądra, a następnie zostaną wypróżnione na nośnik po wywołaniu fsync lub gdy bufor bufora jądra jest pełny (**).

Z kodem O_DIRECT .Th jądro zrobi DMA bezpośrednio do pamięci fizycznej wskazanej przez bufor przestrzeni użytkownika przekazany jako parametr do systemów bazowych write. Tak więc nie będzie pamięci procesora i pamięci w kopiach między pamięcią obszaru użytkownika a pamięcią podręczną jądra i nie będzie czasu procesora spędzonego w jądrze w zarządzaniu pamięcią podręczną (np. Wyszukiwanie pamięci podręcznej, blokady na stronie itp.). (skopiowane z here)

Nie jestem pewien, czy to rozwiąże Twój problem, ale możesz spróbować.

* Pomimo Linusa critize z O_DIRECT, rozwiązało to nasze problemy.

** załóżmy, że nie otworzyć plik z O_DSYNC lub O_SYNC

+0

Bardzo interesujące. Myślę, że problem z buforowaniem jest taki, że wszystkie żądania we/wy (w tym konkretnym systemie) przechodzą przez pojedynczą kolejkę. Jeśli urządzenie blokujące (dysk) przepłukuje informacje o czytaniu, wówczas niezwiązane z nim zapisy na innym urządzeniu blokującym (karcie SD) zostaną zablokowane. Spróbuję zrobić rzecz O_DIRECT. – shodanex

0

Dla ktoś czyta to i za pomocą jądra 2.6.28 powyżej, zaleca się, aby używać zamiast ext3 ext4, który jest systemem plików, który cię można dostroić dla lepszej wydajności. Najlepsza wydajność jest uzyskiwana w trybie data = writeback, w którym dane nie są kronikowane. Przeczytaj sekcję o trybach danych z .

Jeśli masz partycję już utworzone, powiedzmy /dev/sdb1, następnie są pewne kroki, które mogą być używane do formatowania go z ext4 bez dziennika:

mkfs.ext4 /dev/sdb1 -L jp # Creates the ext4 filesystem 
tune2fs -o journal_data_writeback /dev/sdb1 # Set to writeback mode 
tune2fs -O ^has_journal /dev/sdb1 # Disable journaling 
sudo e2fsck -f /dev/sdb1 # Filesystem check is required 

Następnie można zamontować tę partycję (lub ustawić wpis /etc/fstab jeśli wiesz co robisz) z odpowiednimi flagami:

mount -t ext4 -O noatime,nodirame,data=writeback /dev/mmcblk0p1 /mnt/sd 

Przejście z ext3 na ext4 zoptymalizowanej plików powinny być drastyczna różnica. I oczywiście, jeśli twoja karta SD jest szybsza, co powinno pomóc (np. Klasa 10).

Zobacz także https://developer.ridgerun.com/wiki/index.php/High_performance_SD_card_tuning_using_the_EXT4_file_system