2012-07-23 20 views
4

由於我懷疑「黑匣子」(GPU)未在某些較大代碼(others perhaps too)中完全關閉,因此我會在main()的末尾包含cudaDeviceReset()。可是等等!這將Segmentation faultmain()中靜態創建的類的所有實例與析構函數中的非平凡CUDA代碼,對吧?例如。正確使用cudaDeviceReset()

class A { 
public: 
    cudaEvent_t tt; 
    cudaEvent_t uu; 
    A() { 
    cudaEventCreate(&tt); 
    cudaEventCreate(&uu); 
    } 
    ~A(){ 
    cudaEventDestroy(tt); 
    cudaEventDestroy(uu); 
    } 
}; 

靜態實例:在退出

int main() { 
    A t; 
    cudaDeviceReset(); 
    return 0; 
} 

段錯誤。問題:或許cudaDeviceReset()main()退出時自動調用?

否則整個有用的代碼main()應該轉移到run()cudaDeviceReset()應該是main()的最後一個命令,對吧?

+1

cudaDeviceReset顯式銷燬進程或調用它的線程所持有的活動設備上的任何上下文。但是,它只有這樣。如果您的CUDA API調用需要上下文才能在析構函數代碼中工作,那麼在上下文已經被銷燬之後(當流程終止時它將被運行時自動銷燬)後,您無法調用它們。 – talonmies 2012-07-23 09:15:57

回答

3

正如Talonmies所示,類A的析構函數在調用cudaDeviceReset()函數後調用,即main(..)函數完成時調用。

我想,你可以把cudaDeviceReset()放到一個atexit(..)函數中。

void myexit() { 
    cudaDeviceReset(); 
} 

int main(...) { 
    atexit(myexit); 
    A t; 
    return 0; 
} 
+0

mmm ...這並沒有解決我的問題... – JackOLantern 2013-05-30 20:33:04

+1

所以你可能會嘗試在另一個括號中聲明「t」。然後在此pandanthesis結束後調用cudaDeviceReset。所以它可能會強制在設備重置之前破壞「t」。「」「」int main(..){{A t; t.someoperation();} cudaDeviceReset();}「」「 – phoad 2013-06-03 20:33:18

+0

謝謝。我認爲這是一個好點。我會盡快檢查並告訴你。 – JackOLantern 2013-06-04 20:18:33