window 显示驱动开发-分页视频内存资源
与 Microsoft Windows 2000 显示驱动程序模型不同,Windows Vista 显示驱动程序模型允许创建比可用物理视频内存总量更多的视频内存资源,然后根据需要分页进出视频内存。 换句话说,并非所有视频内存资源都同时位于视频内存中。
GPU 的管道中可以有多个 DMA 缓冲区。 这些活动 DMA 缓冲区引用的视频内存资源必须位于视频内存中。 其他空闲视频内存资源可以分页到系统内存。
在 GPU 计划程序调用显示微型端口驱动程序的 DxgkDdiSubmitCommand 函数以将 DMA 缓冲区提交到 GPU 之前,计划程序必须确保 DMA 缓冲区使用的所有视频内存资源实际上都在视频内存中。 如果某些资源不在视频内存中,则必须从系统内存中分页。 GPU 计划程序必须调用视频内存管理器来查找视频内存中的空间,以便将必要的视频内存资源数据从系统内存传输到视频内存。 当视频内存需求较高时,GPU 计划程序必须调用视频内存管理器,以将空闲视频内存资源数据传输到系统内存,以便为所需的视频内存资源数据腾出空间。 包含用于在视频和系统内存之间传输数据的命令的特殊用途 DMA 缓冲区称为分页缓冲区。 视频内存管理器调用显示微型端口驱动程序的 DxgkDdiBuildPagingBuffer 函数来创建分页缓冲区,驱动程序将硬件特定的数据传输命令写入该缓冲区。
1. 内存虚拟化架构对比
Windows 2000 (XPDM) 模型
- 静态分配:资源一旦创建即永久占用显存
- 硬性限制:总资源大小 ≤ 物理显存容量
- 问题:多应用竞争显存时需频繁切换上下文
Windows Vista+ (WDDM) 模型
- 虚拟化池:所有应用共享的虚拟显存空间(物理显存 + 系统内存)
- 按需分页:仅活跃资源占用物理显存
- 优势:支持的总资源量 >> 物理显存容量
2. 关键组件协作流程
(1) 分页触发条件
当 GPU 调度器准备提交 DMA 缓冲区时:
BOOL CheckResourceResidency(DMA_BUFFER* dmaBuffer) {foreach (Resource* res in dmaBuffer->ReferencedResources) {if (!res->IsResidentInVRAM()) { // 检查物理显存驻留TriggerPaging(res); // 触发分页操作return FALSE;}}return TRUE;
}
(2) 分页缓冲区构建
(3) 分页缓冲区示例内容
// AMD GPU 的分页命令示例
struct PAGE_COMMAND {uint64_t srcSysMemAddr; // 系统内存源地址uint64_t dstVramAddr; // 显存目标地址uint32_t size; // 传输数据大小uint32_t tilingFlags; // 块状排列参数
};void BuildPagingBuffer(PAGE_COMMAND* buffer, Resource* res) {buffer->srcSysMemAddr = res->sysMemBacking;buffer->dstVramAddr = VidMmAllocVram(res->size);buffer->size = res->size;buffer->tilingFlags = res->tilingMode;
}
3. 内存管理策略
(1) 驻留集管理
- 活动集(Working Set):当前 DMA 缓冲区引用的资源必须驻留
- LRU 策略:非活跃资源按最近使用时间排序逐出
void VidMmEvictResources(uint64_t requiredSize) {while (freeVram < requiredSize) {Resource* victim = FindLRUResource();CopyToSystemMemory(victim); // 回写系统内存FreeVram(victim->vramAddr);}
}
(2) 并发控制
栅栏(Fence)同步:确保分页操作完成前 GPU 不访问资源
void SubmitPagingBuffer(DMA_BUFFER* pagingBuf) {uint64_t fenceVal = InsertFence();QueueToGpu(pagingBuf, fenceVal);WaitForFence(fenceVal); // 等待传输完成
}
4. 开发者注意事项
用户模式驱动(UMD)
// 创建资源时应考虑分页开销
HRESULT CreateTexture(UINT size, bool isFrequentlyUsed) {D3DDDI_ALLOCATIONINFO info = {0};if (isFrequentlyUsed) {info.Flags.PreferContiguous = 1; // 提示VidMm优先驻留}return pfnAllocateCb(&info);
}
内核模式驱动(KMD)
// 必须正确处理分页失败
NTSTATUS DxgkDdiBuildPagingBuffer(IN_PDXGKARG_BUILDPAGINGBUFFER pArgs)
{if (!CheckHwCapability(pArgs->SizeRequired)) {return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;}// ...生成硬件命令
}
5. 性能优化技巧
技术 | 适用场景 | 实现方式 |
---|---|---|
预加载(Preload) | 关键帧资源加载 | 在Present前异步提交分页请求 |
批量传输 | 大量小资源迁移 | 合并多个资源到单个分页缓冲区 |
压缩分页 | 带宽受限系统 | 实现驱动级内存压缩/解压 |
智能驻留 | 开放世界游戏地形 | 使用D3DDDI_ALLOCATIONFLG_PERSISTENT 标记 |
6. 调试与问题排查
常见问题症状
- GPU 挂起:分页操作未完成导致依赖等待
- 帧率骤降:频繁分页引发带宽瓶颈
- 纹理闪烁:分页同步错误导致部分更新
诊断工具
# Windows Performance Analyzer (WPA)
wpaexporter.exe -d Graphics.gpuperf -o trace.csv# WinDbg 命令
!dxgkd_ext.vidmm -stats # 显示内存分布统计
!dxgkd_ext.resource 0xADDR # 检查资源状态
演进与现状
Windows 10+ 改进:
- 内存优先级:支持资源优先级分层管理
- 直接存储:绕过CPU直接分页(GPU←→NVMe)
- UMA优化:统一内存架构下的零拷贝分页
开发者适配建议:
// 使用DX12内存池提示
D3D12_HEAP_PROPERTIES heapProps = {.Type = D3D12_HEAP_TYPE_DEFAULT,.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE,.MemoryPoolPreference = D3D12_MEMORY_POOL_L1 // 显存优先
};
WDDM 的内存虚拟化机制通过精细的分页策略和硬件加速,实现了 GPU 内存资源的弹性管理,为现代图形应用提供了更大的资源池和更高的内存利用率,同时也对驱动开发者的内存管理能力提出了更高要求。
相关文章:

window 显示驱动开发-分页视频内存资源
与 Microsoft Windows 2000 显示驱动程序模型不同,Windows Vista 显示驱动程序模型允许创建比可用物理视频内存总量更多的视频内存资源,然后根据需要分页进出视频内存。 换句话说,并非所有视频内存资源都同时位于视频内存中。 GPU 的管道中可…...

【笔记】记一次PyCharm的问题反馈
#工作记录 最近更新至 PyCharm 社区版的最新版本后,我遇到了多个影响使用体验的问题。令人感到不便的是,一些在旧版本中非常便捷的功能,在新版本中却变得操作复杂、不够直观。过去,我一直通过 PyCharm 内置的故障报告与反馈机制反…...

uniapp中vue3和pinia安装依赖npm install失败
目录 一、问题描述 二、问题原因 三、问题解析及解决方案 一、问题描述 用uni-app开发小程序的时候,使用了vue3pinia,安装依赖的时候发现vue和pinia的版本问题,安装失败, npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve np…...
MySQL 8.0 OCP 1Z0-908 131-140题
Q131.You have upgraded the MySQL binaries from 5.7.28 to 8.0.18 by using an in-place upgrade. Examine the message sequence generated during the first start of MySQL 8.0.18: 。。。[System]。。。/usx/sbin/mysqld (mysqld 8.0.18-commercial) starting as process…...
Spring-messaging-Message接口/环境依赖
参考文档1:https://docs.spring.io/spring-integration/reference/index.html 参考文档2:https://www.jackssybin.cn/articles/2021/03/16/1615897840354.html#b3_solo_h4_44 环境配置 由于我使用的是spring boot,所以只有一个依赖…...
WPF自定义控件开发全指南:多内容切换与动画集成
WPF自定义控件开发全指南:多内容切换与动画集成 一、控件基础架构设计1.1 选择控件基类1.2 定义关键属性 二、动画系统集成2.1 淡入淡出动画实现2.2 滑动动画实现 三、视觉状态管理四、完整使用示例4.1 XAML声明4.2 动画触发逻辑 五、扩展与优化5.1 性能优化建议5.2…...
ECMAScript标准:JavaScript的核心
什么是ECMAScript? ECMAScript(简称ES)是一个由ECMA国际(欧洲计算机制造商协会)制定的脚本语言标准,它为JavaScript、JScript和ActionScript等脚本语言提供了基础规范。JavaScript 可以视为 ECMAScript 的…...
qtc++ qdebug日志生成
本文介绍了将qdebug注册到日志系统,这样qdebug打印的信息将记录在日志文本文件,方便观看程序运行中的历史信息,但是需要注意的是,注册后qdebug的信息将不会打印在qtcreator的输出中,所以作者建议,在开发的时…...
【分布式锁通关指南 10】源码剖析redisson之MultiLock的实现
引言 本期我们将把目光聚焦在 Redisson 中另一个颇具代表性的分布式锁实现——MultiLock。它的核心思想是:一次性对多个独立的 RLock 进行加锁或解锁操作,只有当多个锁都成功加锁时才算真正完成锁的获取,一旦有任何一个失败,整体操…...

DBF Converter:高效转换DBF文件,满足多样化数据处理需求
DBF Converter 是一款功能强大的数据转换工具,专为需要将DBF文件转换为其他格式的用户设计。它支持将DBF文件转换为CSV、Excel、HTML、SQL等多种常见格式,满足用户在不同场景下的数据处理需求。无论是数据迁移、报表生成还是日常数据处理,DBF…...
Java—— 方法引用 : :
方法引用是什么 把已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体 方法引用符 :: 方法引用的条件 1.需要有函数式接口 2.被引用方法必须已经存在 3.被引用方法的形参和返回值需要跟抽象方法保持一致 4.被引用方法的功能要满足当前…...

Jmeter 安装包与界面汉化
Jmeter 安装包: 通过网盘分享的文件:CSDN-apache-jmeter-5.5 链接: https://pan.baidu.com/s/17gK98NxS19oKmkdRhGepBA?pwd1234 提取码: 1234 Jmeter界面汉化:...
6 任务路由与负载均衡
一、任务路由核心机制 1.1 静态路由配置 # celeryconfig.pytask_routes {# 精确匹配任务路径payment.process_order: {queue: priority_payment},# 通配符匹配任务类型report.*: {queue: low_priority_reports},# 正则表达式匹配re.compile(r^video\.(encode|compress)): {q…...

【C++】 —— 笔试刷题day_29
一、排序子序列 题目解析 一个数组的连续子序列,如果这个子序列是非递增或者非递减的;这个连续的子序列就是排序子序列。 现在给定一个数组,然后然我们判断这个子序列可以划分成多少个排序子序列。 例如:1 2 3 2 2 1 可以划分成 …...
Ruby 循环与迭代器
Ruby 循环与迭代器 循环迭代器timesuptostep 循环 。。。。 迭代器 迭代器本质上可以理解为是循环的一种类型 times 3.times do print "Ho! " end begin Ho! Ho! Ho! end上述代码表示我们对当前 block 部分中的内容循环三次。最终,我们打印出了三个…...
力扣-39.组合总和
题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被…...
优化 Element UI 表格样式,隐藏滚动条但保持滚动功能
优化 Element UI 表格样式,隐藏滚动条但保持滚动功能 前言 在基于 Element UI 的项目中,el-table 是非常常用的表格组件。默认情况下,表格的滚动条可能影响页面的美观,特别是在视觉设计上希望更简洁时。本文分享一段优化的 CSS …...
线程池(ThreadPoolExecutor)实现原理和源码细节是Java高并发面试和实战开发的重点
一、线程池核心流程图 ----------------- | 提交任务 | submit/execute -----------------|v ----------------- | 判断核心线程数 | < corePoolSize? -----------------|Yes |Nov v [创建新线程] -----------------| 队列是否满&a…...

MongoTemplate 基础使用帮助手册
前言 MongoDB 是一种流行的 NoSQL 数据库,适合存储大量的非结构化数据。MongoTemplate 是 Spring Data MongoDB 中的一个核心组件,它提供了一组丰富的 API 来与 MongoDB 进行交互。它封装了许多常见的数据库操作,使开发者能够轻松执行 CRUD 操…...

图像处理:预览并绘制图像细节
前言 因为最近在搞毕业论文的事情,要做出一下图像细节对比图,所以我这里写了两个脚本,一个用于框选并同时预览图像放大细节,可显示并返回框选图像的坐标,另外一个是输入框选图像的坐标并将放大的细节放置在图像中&…...

力扣热题——最长相邻不相等子序列 |
题目要求从字符串数组 words 中选出一个最长的子序列,使得该子序列中相邻字符串对应的 groups 数组中的值不同。通过贪心算法,可以高效地解决该问题。具体步骤为:初始化一个结果列表,遍历 words 数组,检查当前字符串的…...
【抽丝剥茧知识讲解】引入mybtis-plus后,mapper实现方式
目录 前言一、传统 Mapper 接口方式二、继承 BaseMapper 的方式三、自定义通用 Mapper 的方式四、使用 MyBatis-Plus 的 ActiveRecord 模式五、使用 MyBatis-Plus 的 IService 接口六、使用建议 前言 mapper文件,作为Mybatis框架中定义SQL语句和映射关系的配置文件&…...

ssti刷刷刷
[NewStarCTF 公开赛赛道]BabySSTI_One 测试发现过滤关键字,但是特殊符号中括号、双引号、点都能用 可以考虑拼接或者编码,这里使用拼接 ?name{{()["__cla"~"ss__"]}}?name{{()["__cla"~"ss__"]["__ba&…...

java+selenum专题(一)
环境搭建部署篇-> 1.简介 java版的selenium,介绍一下java selenium自动化测试。大致和pythonselenium自动化测试差不多。基于java和selenium做自动化测试,因此你必须会搭建基本的开发环境,掌握python基本的语法和一个IDE来进行开发&…...
物体雅克比、空间雅克比、解析雅克比、几何雅克比
在机器人学中,雅可比矩阵是连接广义坐标速度与末端执行器速度的关键工具。根据应用场景和参考系的不同,雅可比矩阵可分为物体雅可比(Body Jacobian)、空间雅可比(Space Jacobian)、解析雅可比(A…...

[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)
[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五) 引言:一个“幽灵”般的日志问题 你是否在使用 DebugView 排查系统问题时,发现日志中频繁出现 WPS 相关模块(如 k…...

ACM模式用Scanner和System.out超时的解决方案和原理
Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:笔试强训 📚本系列文章为个人学…...

Java注解详解:从入门到实战应用篇
1. 引言 Java注解(Annotation)是JDK 5.0引入的一种元数据机制,用于为代码提供附加信息。它广泛应用于框架开发、代码生成、编译检查等领域。本文将从基础到实战,全面解析Java注解的核心概念和使用场景。 2. 注解基础概念 2.1 什…...

QML 属性动画、行为动画与预定义动画
目录 引言相关阅读本文使用的动画属性工程结构示例解析示例1:属性动画应用示例2:行为动画实现示例3:预定义动画 总结工程下载 引言 QML动画系统为界面元素提供了流畅的过渡效果。本文通过三个示例,结合属性动画(PropertyAnimatio…...

window nvidia-smi命令 Failed to initialize NVML: Unknown Error
如果驱动目录下的可以执行,那可能版本原因 "C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi"复制"C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe"替换 C:\Windows\System32\nvidia-smi.exe 或者 把C:\Windows\System3…...