Bạn cũng nên xem tiểu sử cũng thấy nút cổ chai ở đâu.
Có lẽ nó nằm trong hạt nhân, có thể là do giới hạn phần cứng của bạn. Cho đến khi bạn hồ sơ nó để tìm ra bạn đang stumbling trong bóng tối.
EDIT:
Ok, một câu trả lời thấu đáo hơn thời gian này, sau đó. Theo tài liệu Boost.Iostreams basic_file_source
chỉ là một trình bao bọc xung quanh std::filebuf
, lần lượt được xây dựng trên std::streambuf
. Để trích dẫn tài liệu:
CopyConstructible and Assignable wrapper cho tiêu chuẩn :: basic_filebuf mở ở chế độ chỉ đọc.
streambuf
không cung cấp một phương pháp pubsetbuf (không phải là tài liệu tham khảo tốt nhất có lẽ, nhưng google đầu tiên bật lên) mà bạn có thể, rõ ràng, sử dụng để kiểm soát kích thước bộ đệm.
Ví dụ:
#include <fstream>
int main()
{
char buf[4096];
std::ifstream f;
f.rdbuf()->pubsetbuf(buf, 4096);
f.open("/tmp/large_file", std::ios::binary);
while(!f.eof())
{
char rbuf[1024];
f.read(rbuf, 1024);
}
return 0;
}
Trong thử nghiệm của tôi (tối ưu hóa off, mặc dù) tôi thực sự có hiệu suất tồi tệ hơn với một bộ đệm 4096 byte hơn 16 byte đệm nhưng YMMV - một ví dụ tốt về lý do tại sao bạn nên luôn luôn hồ sơ đầu tiên :)
Nhưng, như bạn nói, các basic_file_sink
không cung cấp bất kỳ phương tiện để truy cập này vì nó ẩn các filebuf
cơ bản trong private part của nó.
Nếu bạn nghĩ rằng điều này là sai bạn có thể:
- Đôn đốc các nhà phát triển Boost để lộ chức năng như vậy, sử dụng danh sách gửi thư hoặc trac.
- Tự tạo
filebuf
trình bao bọc của bạn để lộ kích thước bộ đệm. Có một số section trong hướng dẫn giải thích cách viết các nguồn tùy chỉnh có thể là điểm khởi đầu tốt.
- Viết nguồn tùy chỉnh dựa trên mọi thứ, điều đó thực hiện tất cả bộ nhớ đệm bạn ưa thích.
Hãy nhớ rằng ổ cứng của bạn cũng như hạt nhân đã lưu vào bộ nhớ đệm và lưu vào bộ đọc tệp, tôi không nghĩ rằng bạn sẽ tăng hiệu suất từ bộ nhớ đệm nhiều hơn.
Và kết thúc, một từ về lược tả. Có rất nhiều công cụ định hình mạnh mẽ có sẵn cho Linux, tôi thậm chí không biết một nửa tên của chúng, nhưng ví dụ có iotop là loại gọn gàng vì nó rất dễ sử dụng. Nó khá giống với hàng đầu nhưng thay vào đó chỉ ra các số liệu liên quan đến đĩa. Ví dụ:
Total DISK READ: 31.23 M/s | Total DISK WRITE: 109.36 K/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
19502 be/4 staffan 31.23 M/s 0.00 B/s 0.00 % 91.93 % ./apa
cho tôi biết rằng progam của tôi dành hơn 90% thời gian chờ IO, tức là IO bị ràng buộc. Nếu bạn cần thứ gì đó mạnh mẽ hơn, tôi chắc chắn rằng google có thể giúp bạn.
Và hãy nhớ rằng điểm chuẩn trên bộ nhớ cache nóng hoặc lạnh ảnh hưởng rất lớn đến kết quả.
Có thể đây là câu hỏi cho một bài đăng khác, nhưng làm cách nào để tôi đăng tiểu sử? Tôi biết làm thế nào để sử dụng gprof, nhưng nó chỉ cho tôi biết về thời gian CPU, và ở đây tôi khá chắc chắn nút cổ chai là đĩa I/O. Hoặc nếu ai đó có thể cho tôi biết cách đặt kích thước bộ đệm chính xác, tôi có thể thử và xem nó có giúp ích không. – user387250
@jwfoley: Tôi thích [Valgrind's] (http://valgrind.org/) callgrind profiler. Theo như kinh nghiệm của tôi đi (đọc như: Tôi không thể đảm bảo bất cứ điều gì) nó báo cáo thời gian dành cho các cuộc gọi hạt nhân là tốt, một cái gì đó tôi không bao giờ có thể nhận được gprof để làm. Tôi sử dụng nó để cấu hình một ứng dụng với OpenGL ví dụ, và nó báo cáo chính xác thời gian dành cho mã trình điều khiển video. Nó rất dễ sử dụng (valgrind --tool = callgrind ./your-app). Sử dụng [KCachegrind] (http://kcachegrind.sourceforge.net/html/Home.html) để diễn giải kết quả. Điểm duy nhất là ứng dụng của bạn sẽ chạy chậm hơn 20 lần trong khi định hình. – Staffan
@Staffan: Được rồi, tôi đã thử callgrind + KCachegrind và tôi rất ấn tượng với hồ sơ, nhưng tôi vẫn không biết mình đang tìm gì. Kết quả trông khá giống với kết quả của gprof. Một cái gì đó gọi là T.3577 có một "Incl" cao. nhưng thấp "Tự"; hầu hết thời gian của nó dường như được chi tiêu trong std :: basic_ios. Có lẽ đó là đĩa I/O? Tôi vẫn muốn có câu trả lời cho câu hỏi ban đầu về cách đặt kích thước bộ đệm. Nếu nó dễ dàng, thì tôi có thể thử nó và xem nó có giúp ích gì không, nhưng dù sao thì cũng có ích. – user387250