在我的虚拟现实程序中,我受到内存带宽的严重限制:
func toAnyObject() -> AnyObject {
return [
"name": title,
"addedByUser": subtitle,
"completed": imageURL
] as NSDictionary
}
你可以看到我在#version 320 es
precision lowp float;
const int n_pool = 30;
layout(local_size_x = 8, local_size_y = 16, local_size_z = 1) in;
layout(rgba8, binding = 0) writeonly uniform lowp image2D image;
layout(rgba8, binding = 1) readonly uniform lowp image2DArray pool;
uniform mat3 RT[n_pool]; // <- this is a rotation-translation matrix
void main() {
uint u = gl_GlobalInvocationID.y;
uint v = gl_GlobalInvocationID.x;
vec4 Ir = imageLoad(pool, ivec3(u,v,29));
float cost = 1.0/0.0;
for (int j = 0; j < 16; j++) {
float C = 0.0;
for (int i = 0; i < n_pool; i++) {
vec3 w = RT[i]*vec3(u,v,j);
C += length(imageLoad(pool, ivec3(w[0],w[1],i)) - Ir);
}
}
cost = C < cost ? C : cost;
}
imageStore(image, ivec2(u,v), vec4(cost, cost, cost, 1.0));
}
上有很多随机访问(宽度= 320,高度= 240,图层= 30)。但是,访问不是随机,因为它将在 u,v 附近。
以下是我的想法:
你有什么想法?
答案 0 :(得分:0)
您是否有任何实际数据显示您遇到的问题是纹理 带宽,还是只是一个假设?
我可以看到一些问题,这些问题可能实际上不是你的问题。例如:
vec3 w = RT[i]*vec3(u,v,j);
...你的内部循环中有一个mat3数组加载,所以在大多数架构中,我知道你可能是统一的获取绑定,而不是纹理绑定。这应该在GPU数据缓存中很好地缓存,但是每次循环迭代可能仍然会被重新获取,这比单个imageLoad()
要贵得多,除非你的纹理格式异常宽......
如果使用fp16或fp32 RGBA纹理输入,则较窄的8位unorm格式总是会更快(fp32特别昂贵)。
对于以下内容:
cost = C < cost ? C : cost;
...在代码生成方面使用min()
内置函数可能更可靠。
答案 1 :(得分:0)
更新1
更新2
更新3
mat3/vec4/vec3
创建带来了2倍的加速。非常令我惊讶的是,在循环中创建向量非常昂贵。现在我已经深入实时并实现了我的目标......