2012-01-16 27 views
8

Tôi đang ở phía trước một đoạn mã sao chép tệp vào thiết bị usb. phần sau là quan trọng nhất:Hiệu suất sao chép tệp bằng fread/fwrite sang USB

while((bytesRead = fread(buf, 1, 16*1024, m_hSource)) && !bAbort) { 
    // write to target 
    long bytesWritten = fwrite(buf, 1, bytesRead, m_hTarget); 

    m_lBytesCopied += bytesWritten; 

Điều, khách hàng nói, nó khá chậm so với pc < bình thường -> tốc độ usb. Tôi đã không viết mã này, vì vậy đó là công việc của tôi, để tối ưu hóa.

Vì vậy, tôi đã tự hỏi, nếu đó là một cách tiếp cận tốt hơn để lần đầu tiên đọc các tập tin hoàn chỉnh và sau đó viết các tập tin trong một bước. Nhưng tôi không biết làm thế nào dễ bị lỗi này. Mã cũng kiểm tra sau mỗi copystep nếu tất cả các byte được viết chính xác, do đó cũng có thể làm chậm quá trình.

Tôi không phải là C++ & chuyên gia phần cứng, vì vậy tôi hỏi các bạn, cách tôi có thể tăng tốc mọi thứ và giữ sao chép thành công.

+2

Tìm nơi khác để biết nút cổ chai. Bạn có thể nhận được một cải tiến nhỏ thay đổi kích thước bộ đệm, nhưng vấn đề của bạn có lẽ là một cái gì đó khác. –

+0

Vâng, đó là phần duy nhất đang làm điều gì đó với vấn đề cụ thể này. Vì vậy, nó có thể chỉ là mã. –

+0

Xóa kiểm tra xem các byte đã được viết chính xác chưa. Nếu bạn không thể tin tưởng vào chữ viết đầu tiên, thì bạn không thể tin tưởng những điều bạn đọc sau đây để sử dụng để xác minh. (Tôi cho rằng bạn đang kiểm tra byteWritten cho lỗi.) –

Trả lời

3
  1. Hãy thử để đọc/ghi trong đoạn lớn. 16M, 32M không tệ cho việc sao chép tệp.
  2. Nếu bạn chỉ muốn sao chép tệp, bạn luôn có thể gọi system() Nó sẽ nhanh hơn.
  3. Mã cũng kiểm tra sau mỗi copystep nếu tất cả các byte được viết chính xác để có thể làm chậm quá trình.

    Bạn có thể kiểm tra bằng cách tạo băm của đoạn lớn hơn. Giống như tách tệp thành các khối 64M. Sau đó, kết hợp băm của những khối. Giao thức Bittorrent có tính năng này.

  4. Nếu bạn có mmap hoặc MapViewOfFile có sẵn, hãy ánh xạ tệp trước. Sau đó ghi nó vào usb. Bằng cách này, thao tác đọc sẽ được xử lý bằng hạt nhân.

  5. Kerrek vừa nhận xét về việc sử dụng memcpy trên mmap. memcpy với 2 mmap tệp ed có vẻ tuyệt vời.

Cũng lưu ý rằng, Hệ điều hành gần đây nhất ghi vào thẻ USB khi chúng bị xóa. Trước khi xóa, nó chỉ ghi dữ liệu vào bộ đệm. Vì vậy, sao chép từ hệ điều hành có thể xuất hiện nhanh hơn.

+1

# 4 âm thanh tốt: bộ nhớ-bản đồ và sử dụng 'memcpy'. –

+0

@KerrekSB +1. 'memcpy' với tập tin 2' mmap'ed có vẻ là một lựa chọn tuyệt vời. Đã cập nhật câu hỏi của tôi. –

1

Điều gì về việc đọc và ghi chồng chéo?

Trong mã hiện tại, tổng thời gian là time(read original) + time(write copy), nếu bạn đọc khối đầu tiên, sau đó viết nó bắt đầu đọc khối thứ hai, vv tổng thời gian của bạn sẽ là max(time(read original), time(write copy)) (cộng với thời gian đọc/ghi đầu tiên và khối cuối cùng sẽ không được pipelined).

Có thể gần một nửa thời gian nếu việc đọc và viết mất nhiều hơn hoặc ít hơn cùng một lúc.

Bạn có thể làm điều đó với hai luồng hoặc với IO không đồng bộ. Thật không may, chủ đề và async IO là nền tảng phụ thuộc, vì vậy bạn sẽ phải kiểm tra hệ thống của bạn bằng tay hoặc chọn thư viện di động thích hợp.

+0

AFAIK, USB I/O cũng chủ yếu phụ thuộc vào nền tảng, phải không? –

+0

@ AndréCaron Tôi đoán có nếu bạn đang xây dựng một trình điều khiển, nhưng trong trường hợp này tôi nghĩ rằng nó chỉ là truy cập vào hệ thống tập tin, vì vậy bạn có thể 'fopen' tập tin (và đó là tiêu chuẩn). – fortran

0

Tôi sẽ chỉ đi với một số chức năng cụ thể của hệ điều hành để chắc chắn làm điều này nhanh hơn mà bất cứ điều gì chỉ được viết bằng các hàm c/C++.

Đối với Linux, đây có thể là chức năng sendfile. Đối với Windows CopyFile sẽ thực hiện công việc.

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