2008-10-10 46 views
5

Tôi đang viết một ứng dụng nhỏ, viết các hình ảnh jpeg với tốc độ không đổi trên thẻ SD. Tôi chọn một hệ thống tệp EXT3, nhưng hành vi tương tự đã được quan sát với hệ thống tệp EXT2.Hiệu suất ghi thẻ SD

viết vòng lặp của tôi trông như thế này:

get_image() 
fwrite() 
fsync() 

Hoặc như thế này:

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

Tôi cũng hiển thị một số liệu thống kê thời gian, và tôi có thể thấy chương trình của tôi là đôi khi bị chặn trong vài giây. Tỷ lệ trung bình vẫn tốt, bởi vì nếu tôi giữ hình ảnh đến vào năm mươi, thì tôi sẽ viết nhiều hình ảnh trong một khoảng thời gian ngắn sau một gian hàng như vậy. Bạn có biết nếu nó là một vấn đề với hệ điều hành hoặc nếu nó có liên quan đến chính thẻ SD? Làm cách nào để di chuyển đến gần hơn với thời gian thực? Tôi không cần thời gian thực mạnh mẽ, nhưng bị đình trệ trong vài giây là không thể chấp nhận được.

Một số độ chính xác: Có cần thiết phải đồng bộ hóa sau mỗi tệp, vì tôi muốn hình ảnh nằm trên đĩa, không phải trong bộ đệm người dùng hoặc hạt nhân. Nếu không có fsyncing, tôi có thông lượng tốt hơn nhiều, nhưng vẫn không thể chấp nhận gian hàng. Tôi không nghĩ rằng đó là một vấn đề đệm, kể từ khi gian hàng đầu tiên xảy ra sau khi 50 Mbytes đã được viết. Và theo trang người đàn ông, fsync là ở đây chính xác để đảm bảo không có dữ liệu đệm.

Độ chính xác về tỷ lệ ghi trung bình: Tôi đang viết với tốc độ bền vững bằng thẻ tôi đang sử dụng. Nếu tôi đống hình ảnh đến trong khi chờ đợi một fsync hoàn thành, sau đó sau khi gian hàng này tốc độ ghi sẽ tăng lên và tôi sẽ nhanh chóng quay trở lại mức trung bình. Tốc độ truyền trung bình là khoảng 1,4 MByte/s.

Các Systeme là một máy tính xách tay hiện đại chạy ubuntu 8.04 với chứng khoán kee (2.6.24.19)

Trả lời

1

Tôi không rất am hiểu trong lĩnh vực này, nhưng các triệu chứng bạn mô tả âm thanh một awful nhiều như lấp đầy một bộ đệm. Bạn có thể đang làm đầy bộ đệm trong bộ ghi tệp hoặc trong thiết bị I/O giao tiếp với chính thẻ SD. Sau đó bạn phải chờ cho đến khi nó thực sự ghi dữ liệu vào thẻ (do đó làm trống bộ đệm) trước khi bạn có thể viết thêm. Thẻ SD không phải là các nhà văn đặc biệt nhanh. Nếu bạn có thể tìm cách kiểm tra xem liệu dữ liệu có thực sự được ghi vào thẻ trong các lần tạm dừng này hay không, điều đó sẽ xác minh lý thuyết của tôi. Một số đầu đọc thẻ có đèn LED nhấp nháy khi dữ liệu đang được truy cập - đó có thể là một chỉ báo tốt.

Chỉ cần một linh cảm ... mang nó theo một số muối :)

3

Có cần phải fsync() sau mỗi tập tin? Bạn có thể có may mắn hơn cho phép hệ điều hành quyết định thời điểm thích hợp để ghi lại tất cả các hình ảnh đính kèm vào thẻ SD (khấu hao chi phí khởi động thao tác hệ thống tệp thẻ SD qua nhiều hình ảnh, thay vì phát sinh nó cho mọi hình ảnh).

Bạn có thể cung cấp thêm một số chi tiết về nền tảng của mình không? Thời gian I/O chậm có thể phải thực hiện với các quy trình khác trên hệ thống, bộ điều khiển I/O chậm, vv ..

Bạn cũng có thể cân nhắc sử dụng hệ thống tập tin phù hợp hơn với cách hoạt động của bộ nhớ flash. FAT32 phổ biến hơn extN, nhưng hệ thống tệp được tạo riêng cho SD cũng có thể được sắp xếp theo thứ tự. JFFS là một ví dụ điển hình về điều này.Bạn có thể sẽ có được hiệu suất tốt hơn với hệ thống tập tin được thiết kế cho flash (trái ngược với phương tiện kéo sợi từ), và bạn sẽ có được các đặc tính hao mòn tốt hơn (và do đó tuổi thọ/độ tin cậy của thiết bị).

+0

pleaes lưu ý JFFS và như thế không phải là một ý tưởng tốt cho một số thiết bị đèn flash, chẳng hạn như CompactFlash, mà làm san lấp mặt bằng mặc riêng của họ. – Hasturkun

+1

Chúng có phải là một ý tưởng tồi hay không, mức độ hao mòn của CompactFlash chỉ phủ nhận lợi ích của JFFS? Đó là một câu hỏi trung thực, tôi không biết. Tôi đồng ý rằng nó chắc chắn là một lựa chọn tốt hơn cho các thiết bị flash 'nguyên'. –

2

AFAIK một số đĩa flash có hiệu suất ghi thực sự tồi (đặc biệt là các nhãn hiệu giá rẻ). Vì vậy, nếu bạn đo tốc độ ghi của ứng dụng của bạn (bao gồm cả thời gian cần thiết cho fsync), bạn sẽ nhận được gì? Nó có thể dễ dàng theo thứ tự rất ít megabyte mỗi giây - chỉ vì phần cứng không hoạt động tốt hơn.

Ngoài ra, rõ ràng việc viết có thể chậm hơn nhiều nếu bạn viết nhiều khối nhỏ thay vì một khối lớn (đĩa flash có thể chỉ nhận được khoảng 10 lần viết mỗi giây được thực hiện, trong trường hợp xấu). Đây có lẽ là một cái gì đó có thể được giảm thiểu bởi bộ đệm hạt nhân, do đó, sử dụng fsync thường xuyên có thể làm chậm văn bản ...

Btw. bạn có đo hiệu suất ghi trên FAT32 không? Tôi đoán nó là như nhau, nhưng nếu không, có lẽ có một số tối ưu hóa vẫn có sẵn?

1

Có thể điều này sẽ giúp - Benchmarking Filesystems:

... Tôi đã khá ngạc nhiên như thế nào chậm ext3 là tổng thể, như nhiều bản phân phối sử dụng hệ thống tập tin này như hệ thống tập tin mặc định của họ ...

"ext3 fsync batching":

... vá này đo thời gian cần thiết để thực hiện một giao dịch vào đĩa, và ngủ dựa trên tốc độ của đĩa cơ bản.

4

Hãy thử mở tệp bằng O_DIRECT và lưu bộ nhớ cache ở cấp ứng dụng.

Chúng tôi đã gặp sự cố tương tự khi chúng tôi triển khai tính năng PVR (Quay video cá nhân) trong STB Box. Thủ thuật O_DIRECT thỏa mãn nhu cầu của chúng tôi. (*)

Nếu không có O_DIRECT. Dữ liệu của write() trước hết sẽ được lưu trong bộ nhớ đệm hạt nhân và sau đó được chuyển sang phương tiện khi bạn gọi fsync hoặc khi bộ đệm cache hạt nhân đầy. (**).

Với O_DIRECT. Hạt nhân sẽ làm DMA trực tiếp đến bộ nhớ vật lý được chỉ bởi bộ đệm vùng người dùng được chuyển làm tham số cho các tòa nhà chọc trời write. Vì vậy sẽ không có băng thông CPU và mem nào được dùng trong các bản sao giữa bộ nhớ không gian người dùng và bộ đệm hạt nhân, và sẽ không có thời gian CPU dành cho nhân trong việc quản lý bộ đệm (như tra cứu bộ nhớ cache, khóa trên mỗi trang vv ..). (được sao chép từ here)

Bạn không chắc chắn nó cũng có thể giải quyết vấn đề của bạn, nhưng bạn có thể muốn thử.

* Mặc dù sốcủa Linus là O_DIRECT, nó đã giải quyết được sự cố của chúng tôi.

** giả sử bạn không mở file với O_DSYNC hoặc O_SYNC

+0

Rất thú vị. Tôi nghĩ rằng vấn đề với bộ nhớ đệm là tất cả các yêu cầu I/O (trên hệ thống cụ thể này) đi qua một hàng đợi duy nhất. Nếu một thiết bị khối (đĩa) đang xả, đó là thông tin journalling, sau đó không liên quan đến một thiết bị khối (thẻ SD) sẽ bị chặn. Tôi sẽ thử điều O_DIRECT này. – shodanex

0

Đối với bất cứ ai đọc bài viết này và sử dụng một hạt nhân trên 2.6.28, khuyến cáo là sử dụng ext4 thay vì ext3, mà là một hệ thống tập tin mà bạn có thể điều chỉnh cho hiệu suất tốt hơn. Hiệu suất tốt nhất thu được ở chế độ dữ liệu = writeback, nơi dữ liệu không được ghi nhật ký. Đọc phần Chế độ dữ liệu từ https://www.kernel.org/doc/Documentation/filesystems/ext4.txt.

Nếu bạn có một phân vùng đã tạo ra, nói /dev/sdb1, sau đó đây là một số bước mà có thể được sử dụng để định dạng nó với ext4 mà không ghi nhật ký:

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 

Sau đó, bạn có thể gắn kết phân vùng này (hoặc thiết lập một entry /etc/fstab nếu bạn biết những gì bạn đang thực hiện) với những lá cờ tương ứng:

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

Chuyển từ ext3 đến một hệ thống tập tin ext4 được tối ưu hóa nên một sự khác biệt mạnh mẽ. Và, tất nhiên, nếu thẻ SD của bạn nhanh hơn sẽ giúp (ví dụ: lớp 10).

Xem thêm https://developer.ridgerun.com/wiki/index.php/High_performance_SD_card_tuning_using_the_EXT4_file_system

Các vấn đề liên quan