You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求Win32无高内核开销的异步/重叠文件读取方案

关于Win32重叠I/O(Overlapped I/O)的性能问题与替代方案需求

我对Win32的ReadFile()重叠I/O(Overlapped I/O)并不满意,它不仅不可靠,读取400MB文件时,在Visual Studio的DEBUG配置下内核开销达8-10毫秒,RELEASE配置下更是25-30毫秒,且内核开销与读取字节数成正比。我已提交相关反馈。

复现步骤

  • 在Visual Studio中新建控制台应用项目
  • 将下方代码复制到项目中
  • 将代码中的“Here could be your file!!!”替换为大小大于或等于READ_SIZE宏的文件路径
  • 在DEBUG模式下多次运行,获取重叠读取请求的平均耗时
  • 在RELEASE模式下多次运行,获取重叠读取请求的平均耗时
  • 对比平均耗时……
#include <iostream>
#include <chrono>
#include <Windows.h>

#define READ_SIZE 400000000

int main()
{
    // init
    void* data = new unsigned char[READ_SIZE];

HANDLE file = CreateFileW(L"Here could be your file!!!", // set file path to file with size of READ_SIZE 
        GENERIC_READ,
        NULL,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,
        NULL);

if (file == INVALID_HANDLE_VALUE)
    {
        std::cout << "failed to CreateFile!\n";
        std::cin.ignore();
        return 1;
    }

// request overlapped read
    OVERLAPPED overlapped{};
    
std::chrono::high_resolution_clock::time_point begin = std::chrono::high_resolution_clock::now();
    ReadFile(file, data, READ_SIZE, NULL, &overlapped);
    if (GetLastError() != ERROR_IO_PENDING)
    {
        std::cout << "failed to request overlapped file read\n";
        std::cin.ignore();
        return 1;
    }
    std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
    
int readFile_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();

// wait for overlapped read to complete
    begin = std::chrono::high_resolution_clock::now();
    DWORD bytesRead;
    GetOverlappedResult(file, &overlapped, &bytesRead, TRUE);
    end = std::chrono::high_resolution_clock::now();

int getOverlappedResult_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();

// print results
    std::cout << readFile_duration + getOverlappedResult_duration << "(ms) for " << bytesRead / 1000000 << "(mb)\n";
    std::cout << readFile_duration << "(ms) to request overlapped file read\n";
    std::cout << getOverlappedResult_duration << "(ms) for overlapped read to complete\n";

// cleanup
    CloseHandle(file);
    std::cin.ignore();
}

但我认为该问题不会很快得到修复,且8毫秒的内核开销对我而言仍过高。我希望找到一种无需内核干预,直接向SSD/HDD/M.2等设备的驱动器发送指令的方法。

我了解到可通过IRP(I/O Request Package)实现,但这需要代码运行在内核模式,而我认为这并非良策。

若您知晓Win32下低内核开销的异步/重叠文件读取方法,或跨平台方案,还请不吝赐教!


内容的提问来源于stack exchange,提问作者Schrottiy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:20:21