让我试图指定什么我想做的事情开始:OpenGL调用段错误
给定一个灰度图像,我想创建一个256层(假设8位图像),其中每个层图像用灰度i - 也是第i层(如此,i = 0:255)阈值化。对于所有这些层我想计算其他与我的问题不相关的其他事物,但这应该解释我的代码的结构。
问题是我需要经常执行代码,所以我想尽可能地加快速度,使用很短的时间(所以,只是简单的加速技巧)。因此我想我可以使用OpenMP库,因为我有一个四核,而目前一切都基于CPU。
这使我下面的代码,它执行罚款(至少,它看起来不错:)):
#pragma omp parallel for private(i,out,tmp,cc)
for(i=0; i< numLayers; i++){
cc=new ConnectedComponents(255);
out = (unsigned int *) malloc(in->dimX()* in->dimY()*sizeof(int));
tmp = (*in).dupe();
tmp->threshold((float) i);
if(!tmp){ printf("Could not allocate enough memory\n"); exit(-1); }
cc->connected(tmp->data(),out,tmp->dimX(),tmp->dimY(),std::equal_to<unsigned int>(), true);
free(out);
delete tmp;
delete cc;
}
ConnectedComponents只是一些库,实现了2通floodfill,就在那里进行说明,这不是问题的一部分。
此代码用2,3,4,8个线程完成正常(未测试任何其他编号)。
所以,现在是奇怪的部分。我想添加一些视觉反馈,帮助我进行调试。对象tmp
包含一个名为saveAsTexture()
的方法,它基本上为我完成所有工作,并返回纹理ID。这个函数工作正常,单线程,并且2线程也可以正常工作。但是,只要超出2个线程,该方法就会导致分段错误。
即使#pragma omp在其周围(以防万一saveAsTexture()
不是线程安全的),或者只执行一次,它仍会崩溃。这是我加入到以前的循环代码:
if(i==100){
#pragma omp critical
{
tmp->saveToTexture();
}
}
其中只执行一次,因为i
是迭代器,这是一个重要的部分......尽管如此,代码总是出现segfaults在第一的openGL调用(使用printf(),fflush(stdout))进行bruteforce测试)。
所以,只是为了确保我不会离开了相关信息,这里是saveAsTexture
功能:
template <class T> GLuint FIELD<T>::saveToTexture() {
unsigned char *buf = (unsigned char*)malloc(dimX()*dimY()*3*sizeof(unsigned char));
if(!buf){ printf("Could not allocate memory\n"); exit(-1); }
float m,M,avg;
minmax(m,M,avg);
const float* d = data();
int j=0;
for(int i=dimY()-1; i>=0; i--) {
for(const float *s=d+dimX()*i, *e=s+dimX(); s<e; s++) {
float r,g,b,v = ((*s)-m)/(M-m);
v = (v>0)?v:0;
if (v>M) { r=g=b=1; }
else { v = (v<1)?v:1; }
r=g=b=v;
buf[j++] = (unsigned char)(int)(255*r);
buf[j++] = (unsigned char)(int)(255*g);
buf[j++] = (unsigned char)(int)(255*b);
}
}
GLuint texid;
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glDisable(GL_TEXTURE_3D);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texid);
printf("TextureID: %d\n", texid);
fflush(stdout);
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dimX(), dimY(), 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
free(buf);
return texid;
}
这是好事,在这里指出,T
总是在我的程序的浮动。因此,我不明白为什么这个程序在使用1或2个线程(执行〜25次,100%成功)执行时工作正常,但使用更多线程时执行〜段错误(执行〜25次,0%成功)。并总是在第一次openGL调用(例如,如果我删除glPixelStorei(),它在glDisable())segfaults。 我可以忽略一些非常明显的东西,我遇到了一个奇怪的OpenMP错误,或者......发生了什么?
我会说,这是因为你从一个不同于它创建的线程的线程访问OpenGL上下文,但是你声明它对2个线程有效。 – ChrisF 2011-02-28 22:11:52
你在哪里创建了你的GL上下文?你的GL上下文在哪里最新? – genpfault 2011-02-28 22:11:54