CopyDeviceMemory 函数
CopyDeviceMemory 函数在开发人员需要进一步确保访问设备内存时不会产生对齐错误的情况下,将内存从一个位置复制到另一个位置,且不会受编译器优化的干扰。
重要
一些信息与预发布产品相关,在商业发行之前可能会发生实质性修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。
参数
参数 Destination [输出]
指向复制块的目标起始地址的指针。
参数 Source [输入]
指向要复制的内存块起始地址的指针。
参数 Length [输入]
要复制的内存块的大小(以字节为单位)。
语法
volatile void*
__cdecl
CopyDeviceMemory (
_Out_writes_bytes_all_(Length) volatile void* Destination,
_In_reads_bytes_(Length) volatile const void* Source,
SIZE_T Length
);
备注
在开发人员需要进一步确保访问设备内存时不会产生对齐错误的情况下,此 API 用于提供 CopyVolatileMemory 行为(即,将内存从一个位置复制到另一个位置,且不会受编译器优化的干扰)。 此 API 具有以下属性:
- 此 API 不会被识别为编译器内部函数,因此编译器永远不会优化调用(完全去除或用“等效”指令序列替换调用)。 这不同于 CopyMemory,后者受多项编译器优化的影响。
- 当调用返回时,数据已从源复制到目标。 此函数内存对源和目标的访问只在函数中执行(即编译器无法在此函数外访问内存)。
- 仅当 CPU 支持设备内存上的未对齐内存访问时,API 才能执行未对齐内存访问。 如果 CPU 不支持未对齐的设备内存访问,则只会执行对齐的访问。
- API 在复制操作期间可以多次访问内存位置。
- 当源和目标相互重叠时,不支持复制操作。 如果提供了重叠缓冲区,则会快速失败并显示错误代码 FAST_FAIL_INVALID_ARG。
注意
此函数仅保证 CPU 访问映射为设备内存的内存这一要求得到满足。 如果特定设备对访问有自己的特定要求,则不应使用此功能(相反,开发人员必须实现自己的访问器功能)。 例如,此函数无法保证生成的内存访问大小(除非 CPU 本身强制执行这些要求)。
注意
此函数适用于所有版本的 Windows,而不仅仅是最新版本。 需要使用最新的 SDK 从 winbase.h
标头获取函数声明。 还需要最新 SDK 中的库 (volatileaccessu.lib
)。 但是,生成的二进制文件将在较旧版本的 Windows 上运行。
示例
UCHAR* CopyBuffer;
// In this scenario we are copying data from memory mapped
// as "device memory" (i.e. memory not backed by RAM). On
// some platforms like ARM64, device memory cannot tolerate
// memory accesses that are not naturally aligned (i.e. a 4-byte
// load must be 4-byte aligned). Functions like mempcy, CopyMemory,
// and even CopyVolatileMemory may perform unaligned memory accesses
// because it is typically faster to do this.
// To ensure only naturally aligned accesses happen, use CopyDeviceMemory.
CopyDeviceMemory(CopyBuffer, DeviceMemoryBuffer, 100);
要求
支持的最低客户端:Windows 11 Insider 预览版(待定)
标头:winbase.h(包括 Winbase.h)
Kernel-mode 库:volatileaccessk.lib
User-mode 库:volatileaccessu.lib