我的程序讀取一個文件,如下交織它:加速部分讀取Linux應用
要讀取的文件很大。它被分成四部分,然後分成許多塊。我的程序首先讀取第1部分的第1部分,然後跳轉到第2部分的第1部分,依此類推。然後回到第1部分的第2部分,...,就這樣。
性能在測試中下降。我相信其原因是內核的頁面緩存功能在這種情況下無法有效地工作。但是該文件太大而不適合mmap()
,並且該文件位於NFS中。
如何在這種情況下加快閱讀速度?歡迎任何意見和建議。
我的程序讀取一個文件,如下交織它:加速部分讀取Linux應用
要讀取的文件很大。它被分成四部分,然後分成許多塊。我的程序首先讀取第1部分的第1部分,然後跳轉到第2部分的第1部分,依此類推。然後回到第1部分的第2部分,...,就這樣。
性能在測試中下降。我相信其原因是內核的頁面緩存功能在這種情況下無法有效地工作。但是該文件太大而不適合mmap()
,並且該文件位於NFS中。
如何在這種情況下加快閱讀速度?歡迎任何意見和建議。
您可能想要使用posix_fadvise()
爲您的使用提供系統提示,例如。使用POSIX_FADV_RANDOM
來禁用readahead,並可能使用POSIX_FADV_WILLNEED
讓系統在您需要之前嘗試將下一個塊讀入頁面緩存中(如果可以預測的話)。 一旦完成讀取塊以使系統釋放底層緩存頁面,您也可以嘗試使用POSIX_FADV_DONTNEED
,但這可能不是必需的
謝謝你的建議,儘管我沒有采納它。使用'posix_fadvise()'很複雜,我首先生成文件交錯,以便線性讀取。 – LiJunjie
對於每對塊,讀取兩個塊,處理第一個和把第二個推到一個堆棧上。當您到達文件末尾時,開始將值從堆棧底部移開,逐個處理它們。
您可以將讀數分解爲線性塊。例如,如果你的代碼看起來是這樣的:
int index = 0;
for (int block=0; block<n_blocks; ++block) {
for (int part=0; part<n_parts; ++part) {
seek(file,part*n_blocks+block);
data[part] = readChar(file);
}
send(data);
}
它改成這樣:
for (int chunk=0; chunk<n_chunks; ++chunk) {
for (int part=0; part<n_parts; ++part) {
seek(file,part*n_blocks+chunk*n_blocks_per_chunk);
for (int block=0; block<n_blocks_per_chunk; ++block) {
data[block*n_parts+part] = readChar(file);
}
}
send(data);
}
然後優化n_blocks_per_chunk爲緩存。
當然,像你所做的那樣在文件中跳來跳去,就是壓制了性能。無論如何,你可以重構你的算法線性讀取?此外,無論如何,您可以將代碼與包含該文件的框放在一起,而不是像您目前正在做的那樣通過NFS提取內容。 – chrisaycock
你說你不能mmap文件,但你能夠將所有的數據讀入內存? –
@chrisaycock不幸的是,我必須按照標準閱讀和發送上述文件。許多測試的結果表明NFS不是瓶頸。 – LiJunjie