2011-07-04 100 views
2

這是此帖子中所選答案的後續問題:Output of cuda program is not what was expectedCuda char *變量賦值

雖然下面的功能原理:

__global__ void setVal(char **word) 
{ 

    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x]; 
    myWord[0] = 'H'; 
    myWord[1] = 'e'; 
    myWord[2] = 'l'; 
    myWord[3] = 'l'; 
    myWord[4] = 'o'; 
} 

爲什麼不這項工作?

__global__ void setVal(char **word) 
{ 

    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x]; 
    myWord = "Hello\0"; 

} 

回答

4

你應該開始支付更多的關注,從編譯器的輸出。你的第二個內核代碼:

__global__ void setVal(char **word) 
{ 
    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x]; 
    myWord = "Hello\0"; 
} 

編譯成什麼也沒有空內核裏面:

$ nvcc -arch=sm_20 -c nullkernel.cu 
nullkernel.cu(3): warning: variable "myWord" was set but never used 

nullkernel.cu(3): warning: variable "myWord" was set but never used 

的原因是因爲你認爲什麼是一個字符串拷貝賦值實際上只是一個指針賦值,並在這種情況下,編譯器足夠聰明,知道myWord沒有寫入內存,所以它只是消除了所有的代碼,並警告你myWord沒有被使用。

如果我要反問,並重新編寫代碼是這樣的:

__global__ void setVal(char **word) 
{ 

    char *myWord = word[(blockIdx.y * gridDim.x) + blockIdx.x]; 
    const char[] mymsg = "Hello\0"; 
    myWord = mymsg; 
} 

會更明顯既爲什麼代碼不能編譯,爲什麼它不可能「隱含」執行字符串複製分配即使它編譯?

+0

那麼,我如何設置一個詞的一個particualr索引到一個字符串。假設我要將word [0]設置爲「hello」 – Programmer

+0

將源字符串中的值複製到目標字符串,就像您發佈的第一個內核版本 - 即。編寫你自己的strcpy實現。請注意,GPU硬件在處理32位類型時比8位類型好得多,所以考慮使用char4向量類型而不是char來使其工作。 – talonmies

4

在你的第二個版本,myWord = "Hello\0";,該"Hello\0"不是存儲在由**word參數給出的空間。該字符串可能存儲在可執行文件的.rodata部分。該任務只更新myWord指針 - 它不執行任何批量數據複製。 (雖然作爲talonmies points out,編譯器可以根本不需要指針更新,並優化了整個函數。)

通常,C不提供任何簡單的批量數據複製機制內置語言 - 設計者認爲昂貴的東西應該看起來昂貴。因此,雖然PL/I爲多維數組中的每個元素指定0非常簡單:A = 0;,C強制在最內部循環中嵌套for()循環,並使用memset()操作,以推動其成本高昂的想法。

(複製struct元素融入函數參數是唯一的例外,以批量複製的規則。)

+0

cuda中是否有strcpy? – Programmer

+1

@程序員:沒有沒有。 – talonmies