【问题标题】:Writing to multiple VA locations with a single write operation使用单个写入操作写入多个 VA 位置
【发布时间】:2014-06-11 20:54:25
【问题描述】:

我正在编写一个带有黑盒库的接口(称为“A”),并且需要将void* 分配传递给它。我想用来自其他两个库的两个单独的分配(称为“X”和“Y”)来支持这个分配,将所有写入复制到两个分配中。本质上,我想将所有写入“分叉”到两个现有的 VA 范围。诀窍是这些分配可能非常大,但只有几个字节稀疏地写入,因此复制整个分配不是一种选择。目前,我正在使用write-watch memory 和我自己创建的第三个分配来完成此任务,但是否有更有效的方法来做到这一点?或者,有没有办法将 write-watch 属性添加到由库 X 或 Y 创建的现有分配?

基本上,这就是我今天正在做的事情(半伪代码):

void* x = LibraryX.Allocate(size);
void* y = LibraryY.Allocate(size);

void* a = VirtualAlloc(size, WRITE_WATCH);

LibraryA.WriteSomeStuffToRandomLocations(a);

addresses = GetWriteWatch(a);
for(auto p : addresses)
{
    memcpy(x, p, size);
    memcpy(y, p, size);
}

理想情况下,我可以有这样的东西:

void* x = LibraryX.Allocate(size);
void* y = LibraryY.Allocate(size);

void* a = GetVARangeThatDuplicatesAllWritesTo(x, y);

LibraryA.WriteABunchOfStuff(a);

【问题讨论】:

    标签: c++ winapi memory


    【解决方案1】:

    如果那些外部库正在分配内存,那么您无能为力。如果您控制分配和格式,您可以使用 VirtualProtect 让两个地址指向相同的物理内存位置。如果数据稀疏,这将特别有吸引力,因为您只能根据需要提交页面。

    所以简短的回答是“不采用那种设计。”

    我建议您仔细检查 WriteWatch 的成本以及触发频率。您可能会对最终调用的 memcpy() 的费用和数量感到惊讶。

    【讨论】:

      【解决方案2】:

      如果你可以自己控制物理分配,你可以让两个虚拟地址指向同一个物理页面。但是,没有办法获取两个物理页面并使它们相同,并且由于您的 LibraryY 和 LibraryX 大概分配了正常的虚拟内存,每个分配都有自己独特的物理页面(换句话说,内存分配是通过某些东西完成的)如HeapAllocmallocrealloc、C++ 的new 等函数)。

      【讨论】:

        猜你喜欢
        • 2022-01-07
        • 2012-04-15
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 2019-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多