如何防止编译器优化内存访问基准读取()vs mmap()性能?

时间:2014-11-11 18:15:28

标签: c io mmap

我想对读取10GB数据的C程序的read()vs mmap()性能进行基准测试。如果我已经将数据读取或mmap到缓冲区,应该做些什么来确保数据实际读取?

目前我在每次读取()之后和一次mmap()操作之后使用以下函数来确保数据实际上在内存中:

void use_data(void *data, size_t length) {
    volatile int c = 0;
    for (size_t i = 0; i < length; i++) {
        c += *((char *) data + i);
    }
}

然而,我觉得这甚至会引入开销?也许人们甚至可以区分read()和mmap():

在read()情况下,我认为不需要显式数据访问,因为read()调用无论如何都会将数据复制到缓冲区。但是,对于mmap(),我认为需要执行某种求和/计数才能使内核加载每一页。

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

您不需要为您处理的每个字节访问volatile变量。将所有字节汇总到本地。然后,将总和写入volatile变量。

实际上你不需要一个volatile变量。您可以使用编译器无法证明不需要的任何不透明接收器。将总和写入临时文件也可以保证也能正常工作。

请注意,这不仅仅是让编译器合作的黑客行为。这可以保证触及每个字节(因为它可能会影响结果)。外部IO需要结果。这不能在标准下进行优化。

如果对齐允许,则以更大的单位求和,例如32位或64位。使用无符号类型可以避免UB溢出。您希望是内存/ IO绑定,而不是ALU绑定。您可以通过使用多个本地累加器变量对多个独立流求和来创建指令级并行。