讓我試圖指定什麼我想做的事情開始: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