2011-12-25 87 views
4

我正在嘗試Linux libaio以在服務器應用程序中優化IO性能。我相信我已經做了所有必要的事情(使用O_DIRECT,將緩衝區與內存頁面對齊...)。我在等待io_submit立即返回,但一個簡單的測試顯示它實際上需要80微秒左右的時間才能在我的核心i7筆記本電腦上返回。我是否期望過多或者測試計劃有問題? (編譯G ++ --std =的C++ 0x -laio)具有libaio性能問題的Linux異步IO

#include <unistd.h> 
#include <fcntl.h> 
#include <libaio.h> 
#include <errno.h> 
#include <cstdlib> 
#include <cstdio> 
#include <iostream> 
#include <chrono> 

// Open the file for write, return the file descriptor 
int open_write(char const* file) 
{ 
    int fd = open(file, O_DIRECT|O_CREAT|O_WRONLY, S_IRWXU|S_IRWXG|S_IROTH); 
    if (fd < 0) { 
    perror("open_write"); 
    exit(1); 
    } 
} 

// Make a buffer of _size_ byte, fill with 'a', return the buffer, it should be aligned to memory page 
void* make_write_buffer(size_t size) 
{ 
    void* buf = 0; 
    int ret = posix_memalign((void**)&buf, sysconf(_SC_PAGESIZE), size); 
    if (ret < 0 || buf == 0) { 
    perror("make_write_buffer"); 
    exit(1); 
    } 
    memset(buf, 'a', size); 
    return buf; 
} 

int main (int argc, char *argv[]) 
{  
    static const size_t SIZE = 16 * 1024; 

    // Prepare file and buffer to write 
    int write_fd = open_write("test.dat"); 
    void* buf = make_write_buffer(SIZE); 

    // Prepare aio 
    io_context_t ctx; 
    memset(&ctx, 0, sizeof(ctx)); 
    const int maxEvents = 32; 
    io_setup(maxEvents, &ctx); 

    iocb *iocbpp = new iocb; 
    io_prep_pwrite(iocbpp, write_fd, buf, SIZE, 0); 

    using namespace std::chrono; 
    // Submit aio task 
    auto start = monotonic_clock::now(); 
    int status = io_submit(ctx, 1, &iocbpp); 
    if (status < 0) { 
    errno = -status; 
    perror("io_submit"); 
    exit(1); 
    } 
    auto dur = duration_cast<microseconds>(monotonic_clock::now() - start); 
    std::cout << "io_submit takes: " << dur.count() << " microseconds." << std::endl; 

    io_event events[10]; 
    int n = io_getevents(ctx, 1, 10, events, NULL); 

    close(write_fd); 
    io_destroy(ctx); 
    delete iocbpp; 
    free(buf); 
    return 0; 
} 
+0

80微秒,慢? :p最佳猜想:你的過程已經安排完畢。如果你增加你的緩衝區大小呢? – fge 2011-12-25 13:07:38

+0

另外,測量幾百(或幾千)個調用,對該函數的第一次調用進行計時似乎不是一個好主意。 – Mat 2011-12-25 13:08:37

+0

謝謝,馬特。我做了幾次,80微秒是平均水平。 「冷」操作有時可能需要400微秒。 – 2011-12-25 21:36:25

回答

4

簡而言之:io_submit塊,並沒有什麼,你可以做短固定的內核。

here是kernel-aio的一個線程。

如該線程所指出的,你可以嘗試增加/sys/block/xxx/queue/nr_requests

+0

我試圖寫入500MB左右,並且它也在io_submit中封鎖(如3秒)。這也是預料之中嗎? – Marenz 2014-02-03 15:27:07

0

多久io_getevents走?如果大部分時間都用於io_submit而不是io_getevents,那麼在io_submit期間,io實際上可能已經被執行。 (在我的情況下,我懷疑這是ext4s故障...)

你可以嘗試的另一件事是固定你的過程到核心使用taskset

順便說一句,你也可以使用strace -T得到這些時間。

編輯:我懷疑是在懷疑ext4,結果是缺乏O_DIRECT標誌導致了同步行爲。