【发布时间】:2021-10-31 04:39:27
【问题描述】:
我正在学习 DirectX 和 OpenGL 中的计算着色器
我写了一些代码来测试计算着色器并检查执行时间。
但 DirectX 的执行时间和 Opengl 的有一些差异
和上图表示相差多少(左边是DirectX,右边是Opengl,时间代表纳秒)
甚至 DirectX 计算着色器都比 cpu 慢
这是我计算两个向量总和的代码 一个用于计算着色器,一个用于 cpu
std::vector<Data> dataA(32);
std::vector<Data> dataB(32);
for (int i = 0; i < 32; ++i)
{
dataA[i].v1 = glm::vec3(i, i, i);
dataA[i].v2 = glm::vec2(i, 0);
dataB[i].v1 = glm::vec3(-i, i, 0.0f);
dataB[i].v2 = glm::vec2(0, -i);
}
InputBufferA = ShaderBuffer::Create(sizeof(Data), 32, BufferType::Read, dataA.data());
InputBufferB = ShaderBuffer::Create(sizeof(Data), 32, BufferType::Read, dataB.data());
OutputBufferA =ShaderBuffer::Create(sizeof(Data), 32, BufferType::ReadWrite);
computeShader->Bind();
InputBufferA->Bind(0, ShaderType::CS);
InputBufferB->Bind(1, ShaderType::CS);
OutputBufferA->Bind(0,ShaderType::CS);
// Check The Compute Shader Calculation time
std::chrono::system_clock::time_point time1 = std::chrono::system_clock::now();
RenderCommand::DispatchCompute(1, 1, 1);
std::chrono::system_clock::time_point time2 = std::chrono::system_clock::now();
std::chrono::nanoseconds t =time2- time1;
QCAT_CORE_INFO("Compute Shader time : {0}", t.count());
// Check The Cpu Calculation time
std::vector<Data> dataC(32);
time1 = std::chrono::system_clock::now();
for (int i = 0; i < 32; ++i)
{
dataC[i].v1 = (dataA[i].v1 + dataB[i].v1);
dataC[i].v2 = (dataA[i].v2 + dataB[i].v2);
}
time2 = std::chrono::system_clock::now();
t = time2 - time1;
QCAT_CORE_INFO("CPU time : {0}", t.count() );
这里是 glsl 代码
#version 450 core
struct Data
{
vec3 a;
vec2 b;
};
layout(std430,binding =0) readonly buffer Data1
{
Data input1[];
};
layout(std430,binding =1) readonly buffer Data2
{
Data input2[];
};
layout(std430,binding =2) writeonly buffer Data3
{
Data outputData[];
};
layout (local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
void main()
{
uint index = gl_GlobalInvocationID.x;
outputData[index].a = input1[index].a + input2[index].a;
outputData[index].b = input1[index].b + input2[index].b;
}
和 hlsl 代码
struct Data
{
float3 v1;
float2 v2;
};
StructuredBuffer<Data> gInputA : register(t0);
StructuredBuffer<Data> gInputB : register(t1);
RWStructuredBuffer<Data> gOutput : register(u0);
[numthreads(32,1,1)]
void CSMain(int3 dtid : SV_DispatchThreadID)
{
gOutput[dtid.x].v1 = gInputA[dtid.x].v1 + gInputB[dtid.x].v1;
gOutput[dtid.x].v2 = gInputA[dtid.x].v2 + gInputB[dtid.x].v2;
}
很简单的代码不是吗?
但 Opengl 的性能时间比 DirectX 的时间快 10 倍
我不明白为什么会发生这种情况,有什么东西会降低性能吗??
这是当我创建 RWStructuredBuffer 时唯一与 StructuredBuffer 不同的代码是 BindFlags = D3D11_BIND_SHADER_RESOURCE
desc.Usage = D3D11_USAGE_DEFAULT;
desc.ByteWidth = size * count;
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
desc.CPUAccessFlags = 0;
desc.StructureByteStride = size;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = 0;
uavDesc.Buffer.NumElements = count;
在 opengl 中我以这种方式创建 SSBO
glGenBuffers(1, &m_renderID);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_renderID);
glBufferData(GL_SHADER_STORAGE_BUFFER, int(size * count), pData, GL_STATIC_DRAW);
这是两个 API 中执行计算着色器的所有代码
每个结果都表明 opengl 比 directx 好
是什么属性造成了这种差异?
是在 Buffer 还是 ShaderCode 中?
【问题讨论】:
-
您根本没有测量 GPU 执行着色器所需的时间,您只测量了 GPU 驱动程序执行您的命令所需的时间。你得到的数字完全没有意义。
-
即使 如果 你会测量 GPU 时间,这些数字仍然没有意义,因为你基本上只测量调度一个计算命令的开销,这是 巨大的 与着色器的实际工作量相比(实际上什么都没有)
-
@derhass 我们可以重新提出这个问题吗?实际上有很多话要说,这将使整个社区受益
-
@mrvux yo 获得了我的重新投票,不知道为什么它首先获得了近距离投票,因为它在很大程度上是负责任的。
标签: c++ opengl directx directx-11