簡體   English   中英

OpenCL C ++-線程64之后數組的內存管理錯誤

[英]OpenCL C++ - memory management error for array after thread 64

在使用openCL C ++時,我遇到了這個非常奇怪的問題。 問題是我有100個線程正在訪問100個大小數組中的每個元素。 從0到63,沒有問題,每個線程都在正確計算和更新數組元素的值。 但是當它進入線程64時,它搞砸了,並用其他一些值更新了這些值...

這是我所謂的內核:

kernelGA(cl::EnqueueArgs(queue[iter],
                        cl::NDRange(200 / numberOfDevices)),
                        d_value,
                        d_doubleParameters,
                        buf_half_population, and so on...)

在內核方面,我正在使用以下方法訪問每個線程:

__kernel void kernelGA (__global double * value,
                        __global double * doubleParameters,
                        __global double * population,
                        __global double * scores, and so on...)

int idx = get_global_id(0); // This gives me 100 threads for each device. (I have two devices)
int size_a = 50;
double tempValue[size_a];

// Copying the global "value" into local array so each thread has its own copy.
for (int i = 0; i < size_a; i++) {
    tempValue[i] = value[i];
}

此時,每個線程現在都有其自己的tempValue []數組,它們具有相同的值。 然后我對每個線程的tempValue []數組的值應用一些計算和公式...

// Applying some computations on tempValue and changing the values for each  copy of tempValue for each thread.
tempValue[i] = some calculations for each thread...

此后,我為每個線程訪問tempValue []數組的每個元素,並將它們連續放回到更大的大小數組(線程數* size_a)中。 請記住,數組的索引如下:0,1,2,3,...依此類推...

for (int i = 0; i < size_a; i++) {
    totalArray[(idx * size_a) + i] = tempvalue[i];
} 

因此,當我在內核外部獲取totalArray的答案並打印出來時,前64個線程(從0-63)正確地將它們的值放入totalArray []中。 但是從64開始,索引混亂了。 我的意思不是完全索引,因為我只打印出索引,並且索引是所有線程的正確訪問。 但是價值觀似乎一團糟...

例如:線程0-63的第3,第4,第5和第6個元素的值分別為50、60、70和80。 但是對於線程64之前的版本,第3,第4,第5和第6個元素的值為80、90、100、110。就好像這些值已向后移動了幾個元素。 為什么? 這里發生了什么?

如果多個設備在同一陣列上工作,則會出現問題,

你把

cl::NDRange(200 / numberOfDevices)

作為范圍

但是你不放

cl::NDRange((200 / numberOfDevices)*deviceIndex)

作為每個設備的偏移量。

所有試圖寫入同一位置而不是相鄰組的設備。

另外,您不檢查內核中的總線程數是否少於數組長度,因此某些線程可能會嘗試寫越界。

因此,我找到了解決問題的方法:

問題在於,即使每個線程都有存儲在tempValue[]數組中的value[]數組的副本:

// Copying the global "value" into local array so each thread has its own copy.
for (int i = 0; i < size_a; i++) {
    tempValue[i] = value[i];
}

線程64之后,數組中的值被弄亂了。所以我要做的是在主機代碼中創建了一個更大的值外部數組( sizeOf(value) * 100 ),然后將數組的第一部分復制到剩下99個零件,我寄給了設備。 然后,我使每個線程都使用索引訪問它自己的value []數組部分。

它解決了問題!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM