文件读/写缓冲区的最佳类型

时间:2012-09-06 20:49:24

标签: c alignment

很长一段时间,我在读写文件时使用了简单的char[]缓冲区。

我们假设我有一个非常简单的功能,如:

int f(int fd_in, int fd_out)
{
    char buf[4096];
    char* bufp = buf;
    ssize_t ret, wr;

    ret = read(fd_in, buf, sizeof(buf));
    /* ... */

    while (ret > 0)
    {
        wr = write(fd_out, bufp, ret);
        /* ... */
    }

    return wr;
}

现在,我更加了解对齐问题,我开始认为这实际上不是最理想的,因为缓冲区将与char对齐。

为缓冲区使用不同的(更大的)整数类型以获得更强大的'是否合理。对准?它会使读/写更优化吗?福利到底有多远?使用posix_memalign来获得更多的对齐比积分类型可以实现更好的解决方案吗?

1 个答案:

答案 0 :(得分:3)

  • 不要高估memcpy()的成本。在当前的机器上,memcpy运行“比总线更快”,并花费大量时间等待高速缓存插槽被拉入。
  • 4096大小的缓冲区跨越多个缓存槽(64字节大小,IIRC)。
  • 操作系统也有自己的缓冲区。 (必须从网络缓冲区复制块,或从磁盘存储器复制磁盘)
  • 在部分读取+写入时,无论如何都要搞砸了。您的代码已准备好接收并发送13个字节。或者是大于或等于4095.或4096.在大多数情况下, next 读/写将无法很好地对齐。好消息:对于磁盘文件,无论如何,大小可能是512的倍数。
  • 两个系统调用(读取+写入)的成本远远高于memcpy(对齐或未对齐)(在Gray& Reuter书的封面内有一个很好的估计成本表。可能有点过时,但是仍然非常有启发性)
  • (在Linux中)有一个内核无缓冲区函数(copyfd等) UPDATE sendfile()是名称,实现为系统调用
  • 你总是可以尝试衡量差异:int buff [4096 / sizeof(int)];至少是整齐的。最好的方法是使用int数组和char数组的并集。工会总是与最挑剔的成员的要求保持一致。