1

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_memalignto get more alignment than integer types可以实现更好的解决方案吗?

4

1 回答 1

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