gpt4 book ai didi

c - C中的别名内存

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:04:31 24 4
gpt4 key购买 nike

如果我有像这样的绳状数据结构:

struct rope {
struct { char *buf; size_t len; } *segments;
size_t len;
}

有没有一种方法可以将每个段的缓冲区连续映射到虚拟内存空间,而无需复制?我的用例是以最有效的方式将绳索转换为字符串。

这是一个如何使用它的例子:

char *s = rope_flatten(r);
printf("%s\n", s);
r.segments[0].buf[4] = 'x';
printf("%s\n", s); // The 5th character is now replaced with 'x'

不用说,缓冲区(至少,映射的位)不会以 NUL 终止。

我知道这可能非常特定于平台。如果有符合 POSIX 标准的东西那就太棒了。如果没有,Linux 是我的主要目标,如果不支持,我可以回退到 malloc 和 memcpy。

最佳答案

在一个完美的世界中,您可以像往常一样创建您的绳索并再次重新映射每个部分,这样您就可以在第二个 View 中看到它们是连续的。如果您编辑一个片段,没问题,它会镜像到另一个 View 。如果您扩大一个段,缓冲区会透明地更新。

虽然有几个问题使这不可行:

  • 虚拟内存的粒度不是按字节而是按页,通常为 4KiB,并且它们作为一个整体进行映射。您的代码单元可能比那个小一点。
  • 添加和删除段仍然需要修改页表
  • 修改时必须调用内核来更新映射,这很容易使您希望获得的任何性能优势相形见绌。
  • 可移植性问题:API 是特定于操作系统的。需要 MMU。与 VIVT 缓存结合使用时的有趣效果

尽管如此,仍有将多个 View 映射到地址空间的用例,即当数据发生变化但数据结构发生变化时,例如环形缓冲区:

通常,您必须在软件中实现环绕逻辑,但如果您之后直接重新映射环形缓冲区的页面,您将获得一个环形缓冲区,您只需memcpy在。 GNU Radio 采用了这种机制,并且有一篇很好的博客文章: https://www.gnuradio.org/blog/buffers/

这篇博文让我感到好奇,所以我在 libvas 中重新实现了适用于 Linux、Windows 和 macOS 的机制。 .喜欢的可以看看。

关于c - C中的别名内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49793391/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com