Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance OpenGL计算着色器比';相同';OpenCL内核。为什么?_Performance_Opengl_Opencl_Compute Shader - Fatal编程技术网

Performance OpenGL计算着色器比';相同';OpenCL内核。为什么?

Performance OpenGL计算着色器比';相同';OpenCL内核。为什么?,performance,opengl,opencl,compute-shader,Performance,Opengl,Opencl,Compute Shader,我有一个小游戏,我想移植到Android上。PC版本最初使用(现在仍然可以使用)OpenCL进行碰撞检测,在cpu实现上显示了230x(!)的速度。我想将并行编程转移到OpenGL,使用计算着色器剪切ocl,将其全部保留在ogl中。我有我的第一个ogl计算着色器使用的代码在功能上与ocl版本相同,但它比ocl版本慢14倍 我在这里读过一些关于ogl计算着色器性能的帖子,它们通常都是关于访问纹理的。我没有纹理,只有两个SSBO;一个用于输入,一个用于输出 该任务是一个nbody问题,代码(蛮力)检

我有一个小游戏,我想移植到Android上。PC版本最初使用(现在仍然可以使用)OpenCL进行碰撞检测,在cpu实现上显示了230x(!)的速度。我想将并行编程转移到OpenGL,使用计算着色器剪切ocl,将其全部保留在ogl中。我有我的第一个ogl计算着色器使用的代码在功能上与ocl版本相同,但它比ocl版本慢14倍

我在这里读过一些关于ogl计算着色器性能的帖子,它们通常都是关于访问纹理的。我没有纹理,只有两个SSBO;一个用于输入,一个用于输出

该任务是一个nbody问题,代码(蛮力)检查所有内容与其他内容。程序可以有数千个点(每次迭代都可以添加和删除任意数量的点)。我希望有尽可能多的并发点

2000点的时间是:

  • cpu:713.0毫秒
  • ogl计算着色器:44.0毫秒
  • ocl:3.1毫秒
基本上:

for (Point * p1: points) {
    for (Point * p2: points) {      
        // perform collision detection
        // calculate and accumulate any repulsive force on p1
    }
}
并行程序的目的是使顶部循环变平。所以这是一个幼稚的实现,但现在对我来说还不错如果ocl的速度足以达到230倍,那么ogl应该不会落后太多,对吧

< > C++代码:

void Render::compute (int num_stuff, PointCSData * data, PointCSData_Out *& data_out) {

    // data IN
    glBindBuffer (GL_SHADER_STORAGE_BUFFER, csbo);
    glBufferData (GL_SHADER_STORAGE_BUFFER, num_stuff * sizeof(PointCSData), data, GL_DYNAMIC_COPY);
    glUnmapBuffer (GL_SHADER_STORAGE_BUFFER);

    // data OUT - prep space
    glBindBuffer (GL_SHADER_STORAGE_BUFFER, csbo_out);
    glBufferData (GL_SHADER_STORAGE_BUFFER, num_stuff * sizeof(PointCSData_Out), NULL, GL_DYNAMIC_COPY);  
    glUnmapBuffer (GL_SHADER_STORAGE_BUFFER);

    glBindBufferBase (GL_SHADER_STORAGE_BUFFER, 0, csbo);
    glBindBufferBase (GL_SHADER_STORAGE_BUFFER, 1, csbo_out);

    glUseProgram (computeProgram);
    glDispatchCompute (num_stuff / 32, 32, 1);
    glMemoryBarrier (GL_ALL_BARRIER_BITS);

    glBindBuffer (GL_SHADER_STORAGE_BUFFER, csbo_out);

    GLuint bufMask = GL_MAP_READ_BIT;
    data_out = (PointCSData_Out *) glMapBufferRange (GL_SHADER_STORAGE_BUFFER, 0, num_stuff * sizeof(PointCSData_Out), bufMask);

    glUnmapBuffer (GL_SHADER_STORAGE_BUFFER);
    glUseProgram (0);
}
着色器:

#version 430 

struct PointData {
    int is_fixed;
    float posx, posy;
    int thingpntr;

    float friction;     // not used
    float rigidity;
    vec2 vel;           // not used
};

struct PointData_Out {
    vec2 acc;
    vec2 accrig;
};

layout (std430, binding=0) buffer cs_data {
    PointData data [ ];
};

layout (std430, binding=1) buffer cs_data_out {
    PointData_Out data_out [ ];
};

layout (local_size_x = 32, local_size_y = 1, local_size_z = 1) in;

void main () {

    float k = 500.0;    // Hookes_K
    float d = 8.0;      // collision_d

    uint n = gl_NumWorkGroups.x * gl_NumWorkGroups.y;  // num stuff
    uint gid = gl_GlobalInvocationID.x; 

    if (data [gid].thingpntr == -1          // skip if padding point
        || data [gid].is_fixed == 1)        // skip if fixed point
            return;

    float rig = data [gid].rigidity;

    vec2 p1_pos = vec2 (data [gid].posx, data [gid].posy);
    vec2 p2_pos;

    vec2 acc;       // accumulators
    vec2 accrig; 

    float f, h;
    vec2 dif;
    vec2 norm;
    vec2 F; 

    for (uint i=0; i<n; i++) {

        if (data [gid].thingpntr == data [i].thingpntr   // skip if of same thing
            || data [i].thingpntr == -1                 // skip if padding point
            || i == gid)                                // skip if self
                continue;   

        p2_pos = vec2 (data [i].posx, data [i].posy);

        h = distance (p2_pos, p1_pos);
        if (h > d || h == 0.0)  continue;

        f = k * (h - d); 

        dif = p2_pos - p1_pos;      
        norm = dif / h;
        F = norm * f;

        acc += F * (1.0 - rig);
        accrig += F * rig;
    }

    data_out [gid].acc = acc;
    data_out [gid].accrig = accrig;
}
#版本430
结构点数据{
int是固定的;
浮动posx,posy;
国际贸易永久正常贸易关系;
浮动摩擦;//未使用
浮动刚度;
vec2 vel;//未使用
};
结构点数据输出{
vec2 acc;
vec2-accrig;
};
布局(std430,绑定=0)缓冲区cs\U数据{
点数据[];
};
布局(std430,绑定=1)缓冲区cs\U数据\U输出{
点数据输出数据输出[];
};
布局(本地大小x=32,本地大小y=1,本地大小z=1)在中;
空干管(){
浮动k=500.0;//虎克
float d=8.0;//冲突\u d
uint n=gl_NumWorkGroups.x*gl_NumWorkGroups.y;//num stuff
uint gid=gl_globalinovationid.x;
if(数据[gid].thingpntr==-1//跳过填充点
||数据[gid]。是固定的==1)//如果是固定点,则跳过
返回;
浮动钻机=数据[gid]。刚度;
vec2 p1_pos=vec2(数据[gid].posx,数据[gid].posy);
vec2 p2_位置;
vec2 acc;//累加器
vec2-accrig;
浮点数f,h;
vec2-dif;
vec2范数;
vec2f;
对于(uint i=0;id | h==0.0)继续;
f=k*(h-d);
dif=p2_位置-p1_位置;
norm=dif/h;
F=标准*F;
acc+=F*(1.0-钻机);
accrig+=F*钻机;
}
数据输出[gid].acc=acc;
数据输出[gid]。accrig=accrig;
}
调用glBufferData()和glMapBufferRange()时,是否可以使用访问位字段


同样,是什么使得ogl计算着色器版本的运行速度比功能完全相同的ocl verion慢得多?

与pc相比,android的opengl资源会比opencl少吗?例如减少14倍?现在都在同一台电脑上。我“我计划移植到Android,但还没有。我想这就是我设置计算着色器的方式,但不知道。@pawel-为什么在着色器中循环
num\u stuff
次?我的意思是如果在
P1
你发现
P1
P100
相交。那么,当您在
P100时,为什么还要再次检查它呢?因为对于p1,我找到(p1,P100)并将力施加到p1上,对于P100,我找到力(P100,p1)并将力施加到P100上。如果我在p1的两个方向上施加力(方向相同但相反),那么当我到达p100时,我必须以某种方式“知道”p100已经被p1访问过。但因为这一切都是并行的,没有什么可以保证在“做”其他任何事情之前完成,所以我独立地更新每个点。这有点离题了,因为ocl中的相同方法(好或坏)快了14倍——这是重点,也是问题所在。关于你删除的问题,你可能会发现一个讨论平台会是一个更好的家。你试过Reddit吗?IMO,那里有一些很好的开发论坛,他们可能欢迎尝试一种新的图像格式。