我一直在研究我的应用程序与稀疏纹理相关的AMD和nVidia卡之间的性能差异。我最近发现,在使用AMD GPU时,创建稀疏纹理似乎在CPU内存方面有一些巨大的成本。
在带有R9 390且8 GB GPU内存和16 GB CPU内存的Windows 10计算机上,我运行以下代码附加到定时器设置为每秒触发10次
static std::vector<GLuint> _textures;
static const size_t MAX_TEXTURES = 1000;
static const glm::uvec3 TEXTURE_SIZE(512, 512, 1);
if (_textures.size() < MAX_TEXTURES) {
GLuint texture = 0;
uint16_t mips = evalNumMips(TEXTURE_SIZE);
glCreateTextures(GL_TEXTURE_2D, 1, &texture);
_textures.push_back(texture);
glTextureParameteri(texture, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
glTextureParameteri(texture, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 0);
glTextureStorage2D(texture, mips, GL_RGBA8, TEXTURE_SIZE.x, TEXTURE_SIZE.y);
GLuint maxSparseLevel;
glGetTextureParameterIuiv(texture, GL_NUM_SPARSE_LEVELS_ARB, &maxSparseLevel);
for (uint16_t mip = 0; mip < maxSparseLevel; ++mip) {
auto dims = evalMipDimensions(TEXTURE_SIZE, mip);
glTexturePageCommitmentEXT(texture, mip, 0, 0, 0, dims.x, dims.y, dims.z, GL_TRUE);
}
}
WHERE ...
static const double LOG_2 = log(2.0);
uint16_t evalNumMips(const glm::uvec3& size) {
double dim = glm::compMax(size);
double val = log(dim) / LOG_2;
return 1 + (uint16_t)val;
}
glm::uvec3 evalMipDimensions(const glm::uvec3& size, uint16_t mip) {
auto result = size;
result >>= mip;
return glm::max(result, glm::uvec3(1));
}
据我所知,这应该创建一个纹理,分配虚拟内存,然后提交该内存。它应该以大约每秒10 MB的速度消耗GPU内存。在nVidia卡上,此代码的行为符合预期。但是,在AMD卡上,此代码以大约每秒1 GB的速率开始消耗CPU物理内存。
这可以在这里的进程资源管理器中看到,其中系统提交大小和物理内存大小在我启动应用程序后立即开始飙升。
为什么每当我创建稀疏纹理时AMD驱动程序突然消耗大量的CPU内存?