【发布时间】:2022-05-04 13:55:19
【问题描述】:
我在执行 opencl 内核时遇到了一个奇怪的错误,当我尝试使用 clBuildProgram() 执行构建 opencl 内核时
err = clBuildProgram(program, 1, &ocl->device, "", NULL, NULL);
我的进程开始使用越来越多的内存,直到达到 13GB(通常它使用大约 400MB),然后产生:
“0xC0000005:访问冲突执行位置”
奇怪的是,只有当我使用集成卡时才会发生这种情况,即 Intel HD 4000。如果选择其他设备,如 GTX 960 或 CPU,它工作正常。
另外一个奇怪的事情是,如果有任何语法错误,clBuildProgram 函数会正常结束,给出编译错误,只有在没有任何错误的情况下才会出现。另外,如果我对我的代码的一部分进行注释,它会继续。
这是我的功能:
__kernel void update(__global struct PhysicsComponent_ocl_t* vecPhy, __constant struct BoxCollider_ocl_t* vecBx, __constant ulong* vecIdx, __constant float* deltaTime) {
unsigned int i = get_global_id(0);
unsigned int j = get_global_id(1);
if (j > i) { //From size_t j = i + 1; i < vec.size()...
//Copy data to local memory to avoid race conditions
struct AuxPhy_ocl_t phy1;
copyPhyGL(&vecPhy[vecIdx[i]], &phy1);
struct AuxPhy_ocl_t phy2;
copyPhyGL(&vecPhy[vecIdx[j]], &phy2);
if (collide(&phy1, &phy2, &vecBx[i], &vecBx[j])) {
////Check speed correction for obj 1
struct mivec3_t speed1 = phy1.speed;
struct mivec3_t speed2 = phy2.speed;
modifySpeedAndVelocityOnCollision(&phy1, &phy2, &vecBx[i], &vecBx[j], *deltaTime); //Comprobar los dos objetos, por eso se le da la vuelta a los parametros
modifySpeedAndVelocityOnCollision(&phy2, &phy1, &vecBx[j], &vecBx[i], *deltaTime);
//Make the objects not move
struct mivec3_t auxSub;
multiplyVectorByScalarLL(&speed1, *deltaTime, &auxSub);
substractVectorsLL(&phy1.position, &auxSub, &phy1.position);
multiplyVectorByScalarLL(&speed2, *deltaTime, &auxSub);
substractVectorsLL(&phy2.position, &auxSub, &phy2.position);
//Copy data back to global
copyPhyLG(&phy1, &vecPhy[vecIdx[i]]);
copyPhyLG(&phy2, &vecPhy[vecIdx[j]]);
}
}
}
例如。如果我注释最后两个函数,则构建程序。
//Copy data back to global
//copyPhyLG(&phy1, &vecPhy[vecIdx[i]]);
//copyPhyLG(&phy2, &vecPhy[vecIdx[j]]);
但它们不是造成这种情况的原因,因为如果我把这个函数放在身体的注释部分,它也可以工作。
__kernel void update(__global struct PhysicsComponent_ocl_t* vecPhy, __constant struct BoxCollider_ocl_t* vecBx, __constant ulong* vecIdx, __constant float* deltaTime) {
unsigned int i = get_global_id(0);
unsigned int j = get_global_id(1);
if (j > i) { //From size_t j = i + 1; i < vec.size()...
//Copy data to local memory to avoid race conditions
struct AuxPhy_ocl_t phy1;
copyPhyGL(&vecPhy[vecIdx[i]], &phy1);
struct AuxPhy_ocl_t phy2;
copyPhyGL(&vecPhy[vecIdx[j]], &phy2);
//Removed code was here
copyPhyLG(&phy1, &vecPhy[vecIdx[i]]);
copyPhyLG(&phy2, &vecPhy[vecIdx[j]]);
}
}
我对此感到震惊,我唯一想到的就是代码占用了太多空间。
这是完整的内核code。
【问题讨论】:
-
您是否尝试过添加诸如
-Werror或-g之类的编译选项,指定诸如-cl-std=CL1.2或-cl-std=CL1.1之类的OpenCL 版本?您是否还检查过您是否可以在系统中的 Intel HD 4000 上实际运行任何 OpenCL 内核?您的系统报告的 Intel HD 4000 的 OpenCL 版本是什么?也许您需要更新 GPU 驱动程序?您是否尝试过使用英特尔 OpenCL SDK?有很多可能出错的地方......几年前,我曾经使用 Intel HD 4000 在 Windows 上进行 OpenCL 工作,它工作正常。 -
我尝试使用 -Werror 和 -g 进行编译,还将 opencl 版本设置为 1.2 和 1.1(包括将其传递给 clBuildProgram(program, 1, &ocl->device, "-cl- std=CL1.2", NULL, NULL); ) 但没有运气。是的,我使用的是英特尔 OpenCL SDK。而且我的驱动程序也更新了。
-
运行简单的 OpenCL 程序来检查是否可以运行,怎么样?
-
正如我在问题中所说,如果我评论部分代码,它可以正常工作。
-
如果你删除最后两个函数,那么我会说内核代码是一个死代码 - 优化器很可能会删除其余的内核实现,因此它会构建。但是,如果您在这两个函数之前删除代码并且它可以工作,那么这意味着问题出在某个地方。逐一删除函数调用以缩小可能导致问题的函数。
标签: exception kernel gpu opencl access-violation