2015-07-10 24 views
5

我已經使用opencl實現了一個項目。我有一個包含內核函數和內核使用的函數的文件包含在一個單獨的頭文件中,但是當我更改包含的文件時,有時會應用這些更改,有時它們不會,這會讓我感到困惑如果應用程序有bug或沒有。OpenCL clBuildProgram緩存源文件,並且在#include被修改的源文件時不會重新編譯

我檢查了stackoverflow中的其他帖子,並看到nvidia傳遞-I{include directory}嚴重的問題,所以我改變它,並給出頭文件地址明確,但仍然opencl編譯器無法找到頭文件中的錯誤包含在內核文件名中。

此外,我採用了NVIDIA GTX 980,我還龍頭安裝CUDA 7.0我的電腦上。

任何人有同樣的經歷?我該如何解決它?

所以,假設我有一個這樣的內核:

#include "../../src/cl/test_kernel_include.cl" 

void __kernel test_kernel(
    __global int* result, 
    int n 
) 
{ 
    int thread_idx = get_global_id(0); 
    result[thread_idx] = test_func(); 
} 

其中test_kernel_include.cl如下:

int test_func() 
{ 
    return 1; 
} 

然後我運行代碼,我得到一個數組,其所有成員都正如我們所預期的那樣等於1。現在,我改變test_kernel_include.cl到:

int test_func() 
{ 
    return 2; 
} 

,但結果仍然是一個數組,其所有成員都等於1應改爲2,但事實並非如此。

回答

6

爲了提高內核的編譯時間,NVIDIA實現一個緩存機制,從而編譯的內核二進制文件存儲到磁盤並加載相同的內核編譯下一次。一些散列是在內核源代碼上計算出來的,然後用作編譯內核緩存的索引。

不幸的是,這些散列不包括主內核源代碼包含的任何頭文件。這意味着當你在一個包含的頭文件中改變某些東西時,驅動程序將基本上忽略這個改變,並從磁盤上重新載入以前的內核二進制文件(除非在主內核源文件中有更改)。

在Linux系統中,內核緩存可以~/.nv/ComputeCache找到。如果在對其中一個包含文件進行更改後刪除此目錄,則應該強制驅動程序實際重新編譯OpenCL內核。

+0

此外,在Windows中可以找到'%AppData%\ NVIDIA \ ComputeCache'。這種愚蠢的東西是否也適用於AMD和英特爾,或者它是針對nvidia編譯器的? – mmostajab

+1

我只注意到NVIDIA的這個問題。其他人也可能實施緩存方案,但也許他們考慮到包含的標題。 – jprice

+0

我簡單地在visual studio中爲我的prebuild事件添加了'del/Q/S%APPDATA%\ NVIDIA \ ComputeCache *',現在它總是在重新運行應用程序之前刪除編譯器的緩存:) – mmostajab

8

平臺初始化之前:

setenv("CUDA_CACHE_DISABLE", "1", 1); 

則會取消對構建緩存機制。 它也適用於OpenCL平臺,即使它說CUDA。

+0

它也在windows中工作嗎?因爲我試過了,但是'setenv'沒有定義。 – mmostajab

+2

@mmostajab Windows等價物將是'_putenv_s(「CUDA_CACHE_DISABLE」,「1」);' – jprice

相關問題