【D3D12学习手记】CPU/GPU Synchronization
由于有两个并行运行的处理器(CPU和GPU),会出现许多同步问题。
假设我们有一些资源R存储了我们希望绘制的某些几何体的位置。 此外,假设CPU更新R的数据以存储位置p1,然后将引用R的绘图命令C添加到命令队列,目的是在位置p1处绘制图形。 将命令添加到命令队列不会阻塞CPU,因此CPU会继续运行。 在GPU执行绘图命令C之前,CPU继续并覆盖R的数据以存储新位置p2将会导致错误(参见下图)。
这种情况的一种解决方案是强制CPU等待GPU完成处理队列中的所有命令直到指定的栅栏点(fence point)。 我们称之为刷新命令队列(flushing the command queue)。 我们可以使用栅栏(fence)来做到这一点。 栅栏由ID3D12Fence接口表示,用于同步GPU和CPU。 可以使用以下方法创建fence对象:
HRESULT ID3D12Device::CreateFence(
UINT64 InitialValue,
D3D12_FENCE_FLAGS Flags,
REFIID riid,
void **ppFence); // Example
ThrowIfFailed(md3dDevice->CreateFence(
,
D3D12_FENCE_FLAG_NONE,
IID_PPV_ARGS(&mFence)));
fence对象维护UINT64值,该值只是一个整数,用于标识栅栏时间点。 我们从零开始,每次我们需要标记一个新的栅栏点时,我们只是递增整数。 现在,以下代码/注释显示了我们如何使用fence来刷新命令队列。
UINT64 mCurrentFence = ;
void D3DApp::FlushCommandQueue()
{
// Advance the fence value to mark commands up to this fence point.
mCurrentFence++; // Add an instruction to the command queue to set a new fence point.
// Because we are on the GPU timeline, the new fence point won’t be
// set until the GPU finishes processing all the commands prior to
// this Signal().
ThrowIfFailed(mCommandQueue->Signal(mFence.Get(), mCurrentFence)); // Wait until the GPU has completed commands up to this fence point.
if(mFence->GetCompletedValue() < mCurrentFence)
{
HANDLE eventHandle = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS); // Fire event when GPU hits current fence.
ThrowIfFailed(mFence->SetEventOnCompletion(mCurrentFence, eventHandle));
// Wait until the GPU hits current fence event is fired.
WaitForSingleObject(eventHandle, INFINITE);
CloseHandle(eventHandle);
}
}
图4.8以图形方式解释了此代码。
图4.8。 在这个快照中,GPU已经处理了直到xgpu之前的命令,而CPU刚刚调用了ID3D12CommandQueue :: Signal(fence,n + 1)方法。 这实质上是在队列末尾添加一条指令,将fence值更改为n + 1.但是,mFence-> GetCompletedValue()将继续返回n,直到GPU处理完队列中在Signal指令之前的所有命令。
因此在前面的示例中,在CPU发出绘图命令C之后,它将在覆盖R的数据之前刷新命令队列以存储新位置p2。 这个解决方案并不理想,因为它意味着CPU在等待GPU完成时处于空闲状态,但它提供了一个简单的解决方案,我们将在第7章之前使用它。您几乎可以在任何时候刷新命令队列(每帧不一定只有一次); 比如如果您有一些初始化GPU命令,则可以在进入主渲染循环之前刷新命令队列以执行初始化。
请注意,刷新命令队列也可用于解决我们在上一节末尾提到的问题; 也就是说,我们可以刷新命令队列,以确保在重置命令分配器之前已经执行了所有GPU命令。
【D3D12学习手记】CPU/GPU Synchronization的更多相关文章
- 【D3D12学习手记】The Command Queue and Command Lists
GPU有一个命令队列,CPU通过Direct3D API将命令提交到队列里来使用命令列表(command lists),如下图.当一套命令(a set of commands)已经被提交到命令队列,他 ...
- 【D3D12学习手记】4.3.8 Create the Depth/Stencil Buffer and View
我们现在需要创建深度/模板缓冲区. 如§4.1.5所述,深度缓冲区只是一个2D纹理,用于存储最近的可见对象的深度信息(如果使用模板(stencil),则也会存储模板信息). 纹理是一种GPU资源,因此 ...
- 【D3D12学习手记】4.1.6 Resources and Descriptors
在渲染过程中,GPU将写资源(resources)(例如,后缓冲区,深度/模板缓冲区),读资源(例如,描述表面外观的纹理,存储场景中几何体3D位置的缓冲区).在我们发出绘图命令之前,我们需要将资源绑定 ...
- 【D3D12学习手记】The Swap Chain and Page Flipping
为了避免动画中的闪烁,最好将整个动画帧绘制到称为后台缓冲区的屏幕外纹理(off-screen texture)中.一旦整个场景被绘制到给定动画帧的后缓冲区,它就作为一个完整的帧呈现给屏幕;以这种方式, ...
- Linux.NET学习手记(7)
前一篇中,我们简单的讲述了下如何在Linux.NET中部署第一个ASP.NET MVC 5.0的程序.而目前微软已经提出OWIN并致力于发展VNext,接下来系列中,我们将会向OWIN方向转战. 早在 ...
- Raspberry Pi B+ 定时向物联网yeelink上传CPU GPU温度
Raspberry Pi B+ 定时向物联网yeelink上传CPU GPU温度 硬件平台: Raspberry Pi B+ 软件平台: Raspberry 系统与前期安装请参见:树莓派(Ros ...
- 舌尖上的硬件:CPU/GPU芯片制造解析(高清)(组图)
一沙一世界,一树一菩提,我们这个世界的深邃全部蕴藏于一个个普通的平凡当中.小小的厨房所容纳的不仅仅是人们对味道的情感,更有推动整个世界前进的动力.要想理解我们的世界,有的时候只需要细细品味一下我们所喜 ...
- CPU/GPU/TPU/NPU...XPU都是什么意思?
CPU/GPU/TPU/NPU...XPU都是什么意思? 现在这年代,技术日新月异,物联网.人工智能.深度学习等概念遍地开花,各类芯片名词GPU, TPU, NPU,DPU层出不穷......都是什么 ...
- 深度学习框架:GPU
深度学习框架:GPU Deep Learning Frameworks 深度学习框架通过高级编程接口为设计.训练和验证深度神经网络提供了构建块.广泛使用的深度学习框架如MXNet.PyTorch.Te ...
随机推荐
- AIX文件系统/var空间100%的问题
一.问题说明/var/spool/mqueue目录下出现了多个df打头的文件,导致/var空间最终100% EBANK_P570_MAIN/var/spool/mqueue#ls -l total 8 ...
- python: 错误处理try详解 ,traceback调用栈, 调试(logging)
摘录:https://www.liaoxuefeng.com/wiki/1016959663602400/1017598873256736 错误处理 调试 错误处理 高级语言都会使用内置的一套try. ...
- 第七章 路由 77 路由-使用children属性实现路由嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- Springboot定时任务实现动态配置Cron参数(从外部数据库获取)
https://blog.csdn.net/qq_35992900/article/details/80429245 我们主要讲解它的动态配置使用方法. 在刚开始使用的时候,我们更改一个任务的执行时间 ...
- hdu1529 Cashier Employment[差分约束+二分答案]
这题是一个类似于区间选点,但是有一些不等式有三个未知量参与的情况. 依题意,套路性的,将小时数向右平移1个单位后,设$f_i$为前$i$小时工作的人数最少是多少,$f_{24}$即为所求.设$c_i$ ...
- java程序连接Liunx服务器并且执行命令
JSch 介绍 JSch 是SSH2的一个纯Java实现.它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等.你可以将它的功能集成到你自己的 程序中.同时该项目也提供一个J2M ...
- Java-Base64工具类
/* * Base64 encoding and decoding. * Copyright (C) 2001-2004 Stephen Ostermiller * http://ostermille ...
- SpringMVC之RequestContextHolder分析(转)
链接:https://blog.csdn.net/zzy7075/article/details/53559902
- 【51nod 1245】Binomial Coefficients Revenge
题目大意 C(M,N) = M! / N! / (M - N)! (组合数).给出M和质数p,求C(M,0), C(M,1)......C(M,M)这M + 1个数中,有多少数不是p的倍数,有多少是p ...
- call和ret指令
call和ret都是用来修改ip或cs:ip,可以用来实现子程序的设计: 1.ret和retf ret ->修改ip的内容,从而实现近转移: retf ->同时修改cs和i ...