Pointers OpenCL无效指针算法-奇怪的行为

Pointers OpenCL无效指针算法-奇怪的行为,pointers,opencl,gpu,gpgpu,amd-processor,Pointers,Opencl,Gpu,Gpgpu,Amd Processor,我编写了一个OpenCL内核,它使用OpenCL opengl互操作性来读取顶点和索引,但这可能并不重要,因为我只是在做简单的指针加法,以便通过索引获得特定的顶点 uint pos = (index + base)*stride; 这里我以字节为单位计算绝对位置,在我的示例中,pos是28643328,步幅为28,index=0,base=1022976。嗯,这似乎是正确的 不幸的是,我不能直接使用vload3,因为offset参数不是以字节为单位计算的绝对地址。因此,我只需将pos添加到指针

我编写了一个OpenCL内核,它使用OpenCL opengl互操作性来读取顶点和索引,但这可能并不重要,因为我只是在做简单的指针加法,以便通过索引获得特定的顶点

uint pos = (index + base)*stride;
这里我以字节为单位计算绝对位置,在我的示例中,pos是28643328,步幅为28,index=0,base=1022976。嗯,这似乎是正确的

不幸的是,我不能直接使用
vload3
,因为offset参数不是以字节为单位计算的绝对地址。因此,我只需将
pos
添加到指针
void*vertices\u gl

void* new_addr = vertices_gl+pos;
new_addr
在我的示例中=0x2f90000,这就是奇怪部分的开始

顶点\u gl
=0x303f000


结果(
new_addr
)应为0x4B90000(0x303f000+28643328)

我不明白为什么地址会减少716800(0xAF000)


我的目标是GPU:AMD Radeon HD5830


Ps:对于那些想知道的人,我正在使用printf来获取这些值:)(无法使CodeXL工作)

对于
void*
指针没有指针算法。使用
char*
指针执行字节指针计算

或者比这更好:使用指针指向的实际类型,并且不要乘以偏移量。只需编写
vertex[index+base]
假设
vertex
指向包含28字节数据的类型

性能考虑事项:将顶点属性调整为二的幂,以便合并内存访问。这意味着,在每个顶点条目后添加4字节的填充。要自动执行此操作,如果属性都是浮点值,请使用
float8
作为顶点类型。我假设您使用的是位置和法线数据或类似数据,因此最好编写一个自定义结构,以方便和自我解释的方式封装这两个向量:

//定义顶点数据的类型。这是32字节大。
//你可以在头文件中共享这个代码,以包含在OpenCL和C/C++中!
类型定义结构{
浮动4位;
正常4例;
}顶点数据;
//示例内核
__内核void computeNormalKernel(uu全局顶点数据*顶点,uint基){
uint索引=获取全局id(0);
VertexData thisVertex=vertex[index+base];//再简单不过了!
这个标准=计算正常(…);/或者像你在C/C++中那样做!
顶点[index+base]=thisVertex;//写入时也是如此
}
注意:如果您只是将
float4
s中的一个更改为
float3
,则此代码不适用于您的步幅为28的情况,因为
float3
也会消耗4个浮点内存。但您可以这样编写,这样不会添加填充(但请注意,这会影响内存访问带宽):


void*
指针没有指针算法。使用
char*
指针执行字节指针计算

或者比这更好:使用指针指向的实际类型,并且不要乘以偏移量。只需编写
vertex[index+base]
假设
vertex
指向包含28字节数据的类型

性能考虑事项:将顶点属性调整为二的幂,以便合并内存访问。这意味着,在每个顶点条目后添加4字节的填充。要自动执行此操作,如果属性都是浮点值,请使用
float8
作为顶点类型。我假设您使用的是位置和法线数据或类似数据,因此最好编写一个自定义结构,以方便和自我解释的方式封装这两个向量:

//定义顶点数据的类型。这是32字节大。
//你可以在头文件中共享这个代码,以包含在OpenCL和C/C++中!
类型定义结构{
浮动4位;
正常4例;
}顶点数据;
//示例内核
__内核void computeNormalKernel(uu全局顶点数据*顶点,uint基){
uint索引=获取全局id(0);
VertexData thisVertex=vertex[index+base];//再简单不过了!
这个标准=计算正常(…);/或者像你在C/C++中那样做!
顶点[index+base]=thisVertex;//写入时也是如此
}
注意:如果您只是将
float4
s中的一个更改为
float3
,则此代码不适用于您的步幅为28的情况,因为
float3
也会消耗4个浮点内存。但您可以这样编写,这样不会添加填充(但请注意,这会影响内存访问带宽):


乍一看,我觉得应该是
base+index*stride
。但除此之外,假设
顶点\u gl
是一个指针,指针算法在OpenCL中的工作原理与在C中的相同。乍一看,我觉得它应该是
base+index*stride
。但除此之外,假设
顶点\u gl
是一个指针,指针算法在OpenCL中的工作原理与在C中的相同。谢谢你的回答:)但是opengl是否做了一些自动缓冲区对齐之类的事情?正如您所说,我现在使用的是顶点类型数组,但仍然得到错误的值。。当我使用
VertexType vertex1=texts\u gl[index.x+base]时我得到错误的值,但是当我在C++程序中使用同样的方法(使用原始指针到同一个缓冲区)时,我得到正确的结果KaY原来打印的错误值是:(现在它可以工作了吗?请记住:在对齐属性时,请确保在主机上使用相同的对齐方式,在OpenCL和OpenGL中。感谢您的回答:)但是OpenGL是否会执行一些自动缓冲区对齐或类似的操作?正如您所说,我现在使用的是顶点类型数组,b
typedef struct {
    float pos[4];
    float normal[3];  // Assuming you want 3 floats here
} VertexData;