2009-11-04 73 views
9

Tôi cần ghi dữ liệu vào ổ đĩa. Tôi có hai lựa chọn:Nhanh hơn, ghi dữ liệu thô vào ổ đĩa hoặc ghi vào một tệp?

  1. viết thành phần thô (_ write (xử lý, pBuffer, kích thước);)
  2. ghi vào một tập tin (fwrite (pBuffer, kích thước, đếm, pfile);)
.

Cách nào nhanh hơn?

Tôi đã dự kiến ​​chức năng viết thuộc lĩnh vực thô, _write, để có hiệu quả hơn. Tuy nhiên, kết quả thử nghiệm của tôi không thành công! fwrite nhanh hơn. _write chi phí thời gian lâu hơn.

Tôi đã dán đoạn trích của mình; có lẽ mã của tôi là sai. Bạn có thể giúp tôi không? Dù bằng cách nào cũng được tôi, nhưng tôi nghĩ rằng viết thô là tốt hơn, bởi vì có vẻ như dữ liệu trong ổ đĩa được mã hóa ít nhất ....

#define SSD_SECTOR_SIZE 512 
int g_pSddDevHandle = _open("\\\\.\\G:",_O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE); 
TIMER_START(); 
while (ulMovePointer < 1024 * 1024 * 1024) 
{ 
    _write(g_pSddDevHandle,szMemZero,SSD_SECTOR_SIZE); 
    ulMovePointer += SSD_SECTOR_SIZE; 
} 
TIMER_END(); 
TIMER_PRINT(); 
FILE * file = fopen("f:\\test.tmp","a+"); 
TIMER_START(); 
while (ulMovePointer < 1024 * 1024 * 1024) 
{ 
    fwrite(szMemZero,SSD_SECTOR_SIZE,1,file); 
    ulMovePointer += SSD_SECTOR_SIZE; 
} 
TIMER_END(); 
TIMER_PRINT(); 
+4

Viết dữ liệu thô không được mã hóa chút nào - nó chỉ gây nhầm lẫn cho người dùng ... – bdonlan

+3

+1 cho lược tả. (Mặc dù câu hỏi này nằm phía trên đầu của tôi) – GManNickG

+0

Để bdonlan: Tôi chỉ muốn nó trông giống như được mã hóa ... ẩn với người dùng –

Trả lời

6

Trong trường hợp _write(), giá trị của SSD_SECTOR_SIZE vấn đề. Trong trường hợp fwrite, kích thước của mỗi ghi sẽ thực sự là BUFSIZ. Để có được một so sánh tốt hơn, hãy đảm bảo kích thước bộ đệm cơ bản là giống nhau.

Tuy nhiên, điều này có lẽ chỉ là một phần của sự khác biệt.

Trong trường hợp fwrite, bạn đang đo tốc độ bạn có thể lấy dữ liệu vào bộ nhớ. Bạn chưa xả bộ đệm stdio vào hệ điều hành và bạn chưa yêu cầu hệ điều hành xóa bộ đệm của nó thành bộ nhớ vật lý. Để so sánh chính xác hơn, bạn nên gọi fflush() trước khi dừng bộ hẹn giờ.

Nếu bạn thực sự quan tâm đến việc đưa dữ liệu vào đĩa thay vì chỉ nhận dữ liệu vào bộ đệm hệ điều hành, bạn nên đảm bảo rằng bạn gọi fsync()/FlushFileBuffers() trước khi dừng hẹn giờ.

khác biệt rõ ràng khác:

  • Các ổ đĩa khác nhau. Tôi không biết khác nhau.

  • Ngữ nghĩa của việc ghi vào thiết bị khác với ngữ nghĩa của ghi vào hệ thống tệp; hệ thống tập tin được phép trì hoãn việc ghi để cải thiện hiệu suất cho đến khi được yêu cầu không rõ ràng (ví dụ: với một tay cầm chuẩn, một cuộc gọi đến FlushFileBuffers()); viết trực tiếp vào thiết bị không nhất thiết phải được tối ưu hóa theo cách đó. Mặt khác, hệ thống tập tin phải làm thêm I/O để quản lý siêu dữ liệu (phân bổ khối, mục thư mục vv)

Tôi nghi ngờ rằng bạn đang nhìn thấy một khác nhau trong chính sách về những thứ nhanh như thế nào thực sự vào đĩa.Hiệu suất đĩa thô có thể rất nhanh, nhưng bạn cần viết lớn và tốt nhất là nhiều hoạt động nổi bật đồng thời. Bạn cũng có thể tránh sao chép bộ đệm bằng cách sử dụng các tùy chọn phù hợp khi mở tay cầm.

+0

Kết quả là fwrite nhanh hơn 10 lần so với _write ... SSD_SECTOR_SIZE là 512 –

+0

Nếu bạn gọi fflush() sau mỗi cuộc gọi đến fwrite, hiệu năng sẽ xuất hiện tương đương. Tuy nhiên, như janm đã đề cập, có các biến khác có liên quan ở đây là tốt, chẳng hạn như bộ nhớ cache hệ điều hành. –

+1

Nếu bạn thực sự quan tâm đến hiệu suất, tôi sẽ cố gắng viết lớn hơn, nói 1MB mỗi lần. Hoặc thậm chí chỉ là một cuộc gọi duy nhất đến chức năng ghi và sau đó là một cuộc gọi đến chức năng xả. Ổ đĩa hiện đại không viết các lĩnh vực, họ viết bài hát. Để so sánh chính xác, bạn nên xóa bộ đệm. – janm

18

Có thể vì ghi trực tiếp không được đệm. Khi bạn gọi fwrite, bạn đang thực hiện việc ghi đệm có xu hướng nhanh hơn trong hầu hết các trường hợp. Về cơ bản, mỗi bộ xử lý FILE* có bộ đệm trong được chuyển sang đĩa định kỳ khi nó đầy, điều này có nghĩa là bạn sẽ thực hiện các cuộc gọi hệ thống ít hơn, vì bạn chỉ ghi vào đĩa trong các khối lớn hơn.

Để đặt nó theo một cách khác, trong vòng lặp đầu tiên của bạn, bạn đang thực sự viết SSD_SECTOR_SIZE byte vào đĩa trong mỗi lần lặp. Trong vòng lặp thứ hai của bạn, bạn không. Bạn chỉ đang viết SSD_SECTOR_SIZE byte vào bộ nhớ đệm, tùy thuộc vào kích thước của bộ đệm, sẽ chỉ được xóa sạch mọi lần lặp thứ N.

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