【问题标题】:Analyzing read operation using Procmon使用 Procmon 分析读取操作
【发布时间】:2015-11-19 18:40:29
【问题描述】:

我正在尝试使用 ifstream 和 Procmon 分析基本读取操作。

用于读取操作的部分代码,我试图从文件中读取 16kb 大小的数据:

char * buffer = new char[128000];
ifstream fileHandle("file.txt");
fileHandle.read(buffer, 16000);
cout << buffer << endl;
fileHandle.close();

在 Procmon 中有 4 个 ReadFile 操作,详细信息如下:

偏移量:0,长度:4,096,优先级:正常
偏移:4,096,长度:4,096
偏移:8,192,长度:4,096
偏移:12,288,长度:4,096

这是否意味着每个 4kb 大小有 4 个操作?如果是这样,为什么会发生这种情况,而不是只有一个 16 kb 大小的 ReadFile 操作。

【问题讨论】:

    标签: c++ file-io procmon


    【解决方案1】:

    那么是否意味着每个 4kb 大小有 4 个操作?

    是的。

    如果是这样,为什么会发生这种情况,而不是只有一个 16 kb 大小的 ReadFile 操作。

    可能是因为编译器附带的标准库将文件流缓冲区的默认大小设置为 4 KB;由于read 操作必须通过缓冲区,因此必须填充(通过操作系统调用)并清空 4 次才能满足您的请求。请注意,您可以使用 fileHandle.rdbuf-&gt;pubsetbuf 更改 fstream 的内部缓冲区。

    【讨论】:

    • 我将通过更改内部缓冲区进行更多实验,看看它是如何工作的。
    • 对于 16 KB,我怀疑你会设法看到任何显着差异......初始 IO 成本将完全隐藏两个额外系统调用的成本,如果你想要性能@987654325 @ 无论如何都是死胡同。
    • 谢谢。我能够使用 fileHandle.rdbuf 在一次操作中读取 16 Kb。
    【解决方案2】:

    那么是否意味着每个 4kb 大小有 4 个操作?

    这正是它所说的。

    如果是这样,为什么会发生这种情况,而不是只有一个 16 kb 大小的 ReadFile 操作。

    仅仅因为要求16000字节并不意味着ifstream实际上可以在一次操作中读取16000字节。文件系统通常不允许如此大的读取,通常有一个上限。即使您增加了ifstream 在内部使用的内部缓冲区的大小,仍然不能保证文件系统将支持更大的读取大小。

    read() 的约定是它返回请求的字节数,除非遇到 EOF/错误。它如何实现内部读取是一个实现细节。在这种情况下,ifstream 必须读取四个 4KB 块才能返回 16000 字节。

    【讨论】:

    • 我认为,在这个级别上,文件系统的实现除了建议 CRT 的设计者使用 4096 作为默认块大小之外,没有任何其他意义。 ReadFile 本身是一个相当高级的 API,你可以向它询问任何大小(并传递任何类型的文件句柄),它会很高兴地接受,阻塞直到它获取所有请求的数据;文件系统驱动程序的限制远低于它。
    猜你喜欢
    • 2014-02-11
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    相关资源
    最近更新 更多