2015-09-23 10 views
7

Bối cảnh:C Disk I/O - viết sau khi đọc đồng bù đắp của một tập tin sẽ làm cho đọc thông rất thấp

Tôi đang phát triển một chương trình cơ sở dữ liệu liên quan, và tôi cần phải tuôn ra siêu dữ liệu bẩn từ bộ nhớ vào đĩa tuần tự. /dev/sda1 là định dạng volumn, vì vậy dữ liệu trên/dev/sda1 sẽ được truy cập khối theo khối và các khối liền kề về mặt vật lý nếu được truy cập tuần tự. Và tôi sử dụng I/O trực tiếp, vì vậy I/O sẽ bỏ qua cơ chế lưu bộ nhớ đệm của hệ thống tệp và truy cập trực tiếp vào các khối trên đĩa.

vấn đề:

Sau khi mở/dev/sda1, tôi sẽ đọc một khối, cập nhật các khối và viết các khối lại với cùng bù đắp từ đầu/dev/sda1, lặp đi lặp lại.

Mã này cũng giống như dưới đây -

//block_size = 256KB 
int file = open("/dev/sda1", O_RDWR|O_LARGEFILE|O_DIRECT); 
for(int i=0; i<N; i++) { 
    pread(file, buffer, block_size, i*block_size); 
    // Update the buffer 
    pwrite(file, buffer, block_size, i*block_size); 
} 

Tôi thấy rằng nếu tôi không làm pwrite, đọc thông là 125 MB/s.

Nếu tôi làm pwrite, đọc thông sẽ 21 MB/s, và viết thông là 169 MB/s.

Nếu tôi làm pread sau pwrite, viết thông là 115 MB/s, và đọc thông là 208 MB/s.

Tôi cũng đã thử đọc()/write() và aio_read()/aio_write(), nhưng vấn đề vẫn còn. Tôi không biết tại sao viết sau khi đọc tại cùng một vị trí của một tập tin sẽ làm cho thông lượng đọc rất thấp.

Nếu việc tiếp cận nhiều hơn các khối cùng một lúc, như thế này

pread(file, buffer, num_blocks * block_size, i*block_size); 

Vấn đề sẽ giảm nhẹ, vui lòng xem chart.

+1

Kích thước khối của bạn là gì? Có một cơ hội tốt để bạn nhìn thấy ảnh hưởng của bộ nhớ đệm phần cứng và đọc trước trên đĩa bạn đang truy cập. 'Pwrite()' điền vào bộ đệm, và nếu 'pread()' tiếp theo là cho các dữ liệu khác nhau, không có dữ liệu nào được lưu trữ. Thực hiện 'pread()' sau khi 'pwrite()' cho phép đọc dữ liệu trực tiếp từ bộ nhớ đệm phần cứng của đĩa. –

+0

Tôi không biết kích thước khối vật lý và tôi đã đặt thành 256KB trong chương trình. Cảm ơn bạn đã bình luận của bạn, bây giờ tôi nghĩ rằng nó rất có thể gây ra bởi bộ đệm của đĩa. – Leo

Trả lời

2

Và tôi sử dụng I/O trực tiếp, vì vậy I/O sẽ bỏ qua cơ chế lưu trong bộ nhớ đệm của hệ thống tệp và truy cập trực tiếp vào các khối trên đĩa.

Nếu bạn không có hệ thống tệp trên thiết bị và trực tiếp sử dụng thiết bị để đọc/ghi, thì không có bộ đệm hệ thống tệp nào được đưa vào ảnh.

Hành vi bạn quan sát là điển hình của truy cập đĩa và hành vi IO.

Tôi thấy rằng nếu tôi không làm pwrite, thông đọc là 125 MB/s

Lý do: Người đĩa chỉ đọc dữ liệu, nó không phải quay trở lại để bù đắp và ghi dữ liệu, 1 hoạt động ít hơn.

Nếu tôi viết pwrite, thông lượng đọc sẽ là 21 MB/s và ghi thông lượng là 169 MB/s.

Lý do: Đĩa của bạn có thể có tốc độ ghi tốt hơn, có thể bộ đệm đĩa được lưu vào bộ nhớ đệm thay vì nhấn trực tiếp phương tiện.

Nếu tôi thực hiện sau khi viết pwrite, ghi thông lượng là 115 MB/s và thông lượng đọc là 208 MB/s.

Lý do: Nhiều khả năng dữ liệu được ghi đang được lưu vào bộ nhớ cache ở mức đĩa và do đó đọc lấy dữ liệu từ bộ nhớ cache thay vì phương tiện.

Để có hiệu suất tối ưu, bạn nên sử dụng IO không đồng bộ và số lượng khối cùng một lúc. Tuy nhiên, bạn phải sử dụng số lượng hợp lý các khối và không thể sử dụng số lượng rất lớn. Nên tìm hiểu điều gì là tối ưu bằng thử và sai.

+0

Cảm ơn câu trả lời của bạn, bây giờ tôi nghĩ rằng nó rất có thể gây ra bởi bộ đệm của đĩa. Nhưng tôi vẫn không thể tưởng tượng chỉ tìm kiếm vị trí trước đó sẽ cho phép đọc thông lượng giảm từ 125 MB/s xuống 21 MB/s ... – Leo

+0

@leo, Có, tìm kiếm là tốn kém. Nhìn vào thời gian chờ IO mà sẽ tăng khi thông lượng giảm. – Rohan

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