OpenCL-全局内存读取性能优于本地
我有一个内核,我在NVidia GTX 680上运行,当从使用全局内存切换到本地内存时,它的执行时间增加了 我的内核是有限元光线跟踪器的一部分,现在在处理之前将每个元素加载到本地内存中。每个元素的数据存储在具有以下定义的struct fastTriangle中:OpenCL-全局内存读取性能优于本地,opencl,gpgpu,Opencl,Gpgpu,我有一个内核,我在NVidia GTX 680上运行,当从使用全局内存切换到本地内存时,它的执行时间增加了 我的内核是有限元光线跟踪器的一部分,现在在处理之前将每个元素加载到本地内存中。每个元素的数据存储在具有以下定义的struct fastTriangle中: typedef struct fastTriangle { float cx, cy, cz, cw; float nx, ny, nz, nd; float ux, uy, uz, ud; float
typedef struct fastTriangle {
float cx, cy, cz, cw;
float nx, ny, nz, nd;
float ux, uy, uz, ud;
float vx, vy, vz, vd;
} fastTriangle;
我将这些对象的数组传递给内核,编写如下(为了简洁起见,我删除了不相关的代码:
__kernel void testGPU(int n_samples, const int n_objects, global const fastTriangle *objects, __local int *x_res, __global int *hits) {
// Get gid, lid, and lsize
// Set up random number generator and thread variables
// Local storage for the two triangles being processed
__local fastTriangle triangles[2];
for(int i = 0; i < n_objects; i++) { // Fire ray from each object
event_t evt = async_work_group_copy((local float*)&triangles[0], (global float*)&objects[i],sizeof(fastTriangle)/sizeof(float),0);
//Initialise local memory x_res to 0's
barrier(CLK_LOCAL_MEM_FENCE);
wait_group_events(1, &evt);
Vector wsNormal = { triangles[0].cw*triangles[0].nx, triangles[0].cw*triangles[0].ny, triangles[0].cw*triangles[0].nz};
for(int j = 0; j < n_samples; j+= 4) {
// generate a float4 of random numbers here (rands
for(int v = 0; v < 4; v++) { // For each ray in ray packet
//load the first object to be intesected
evt = async_work_group_copy((local float*)&triangles[1], (global float*)&objects[0],sizeof(fastTriangle)/sizeof(float),0);
// Some initialising code and calculate ray here
// Should have ray fully specified at this point;
for(int w = 0; w < n_objects; w++) { // Check for intersection against each ray
wait_group_events(1, &evt);
// Check for intersection against object w
float det = wsDir.x*triangles[1].nx + wsDir.y*triangles[1].ny + wsDir.z*triangles[1].nz;
float dett = triangles[1].nd - (triangles[0].cx*triangles[1].nx + triangles[0].cy*triangles[1].ny + triangles[0].cz*triangles[1].nz);
float detpx = det*triangles[0].cx + dett*wsDir.x;
float detpy = det*triangles[0].cy + dett*wsDir.y;
float detpz = det*triangles[0].cz + dett*wsDir.z;
float detu = detpx*triangles[1].ux + detpy*triangles[1].uy + detpz*triangles[1].uz + det*triangles[1].ud;
float detv = detpx*triangles[1].vx + detpy*triangles[1].vy + detpz*triangles[1].vz + det*triangles[1].vd;
// Interleaving the copy of the next triangle
evt = async_work_group_copy((local float*)&triangles[1], (global float*)&objects[w+1],sizeof(fastTriangle)/sizeof(float),0);
// Complete intersection calculations
} // end for each object intersected
if(objectNo != -1) atomic_inc(&x_res[objectNo]);
} // end for sub rays
} // end for each ray
barrier(CLK_LOCAL_MEM_FENCE);
// Add all the local x_res to global array hits
barrier(CLK_GLOBAL_MEM_FENCE);
} // end for each object
}
\uuu内核无效测试GPU(int n\u样本、const int n\u对象、全局const fastTriangle*对象、局部int*x\u res、全局int*hits){
//获取gid、lid和lsize
//设置随机数生成器和线程变量
//正在处理的两个三角形的本地存储
__局部快速三角形[2];
对于(int i=0;i
当我第一次编写这个内核时,我并没有在本地内存中缓冲每个对象,而是从全局内存中访问它,即不是三角形[0]。cx我将使用对象[I]。cx
当开始优化时,我切换到使用上面列出的本地内存,但随后观察到执行运行时间增加了约25%
当使用本地内存缓冲对象而不是直接访问全局内存时性能会更差?
如果本地内存有助于更快地运行,它实际上取决于程序。在使用本地内存时需要考虑两件事:当您在计算中多次读取数据时,本地内存非常好。但是快速读取和写入需要获得比复制和同步更高的性能增益。对我来说,这很清楚。他正在从全局复制到本地,使用一次并删除数据。Fr此目的最好是一次性访问。