這個問題是涉及到由我發佈了幾個星期前的現有問題之間的最小:TERCOM algorithm - Changing from single thread to multiple threads in CUDA查找線程
簡要說明,每個內核線程的計算MAD價值,我想知道最小的和它的位置。
我試着使用atomicMin這樣
__global__ void kernel (int m, int n, int h, int N, int *f, float heading, float *measurements, int *global_min)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.y * blockDim.y + threadIdx.y;
float MAD=0;
float pos[2];
float theta=heading*(PI/180);
float fval = 0;
// Calculate how much to move in x and y direction
float offset_x = h*cos(theta);
float offset_y = -h*sin(theta);
//Calculate Mean Absolute Difference
if(idx < n && idy < m)
{
for(float g=0; g<N; g++)
{
float fval = tex2D (tex, idx+(g-2)*offset_x+0.5f, idy+(g-2)*offset_y+0.5f);
MAD += abs(measurements[(int)g]-fval);
}
}
cuPrintf("%.2f \n",MAD);
atomicMin(global_min, MAD);
pos[0]=idx;
pos[1]=idy;
f[0]=*global_min;
f[1]=pos[0];
f[2]=pos[1];
}
而且它產生正確的結果,但atomicMin是無法找到最低的位置。
我還試圖用推力庫
__global__ void kernel (int m, int n, int h, int N, int *f, float heading, float *measurements, int *global_min, float *dev_MAD)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.y * blockDim.y + threadIdx.y;
float theta=heading*(PI/180);
float fval = 0;
// Calculate how much to move in x and y direction
float offset_x = h*cos(theta);
float offset_y = -h*sin(theta);
//Calculate Mean Absolute Difference
if(idx < n && idy < m)
{
for(float g=0; g<N; g++)
{
float fval = tex2D (tex, idx+(g-2)*offset_x+0.5f, idy+(g-2)*offset_y+0.5f);
*dev_MAD += abs(measurements[(int)g]-fval);
}
}
cuPrintf("%.2f \n",MAD);
}
並調用內核這樣
kernel <<< dimGrid,dimBlock >>> (m, n, h, N, dev_results, heading, dev_measurements, global_min, dev_MAD);
thrust::device_ptr<float> dev_ptr(dev_MAD);
thrust::device_ptr<float> min_pos = thrust::min_element(dev_ptr, dev_ptr + n*m);
int abs_pos = min_pos - dev_ptr;
float min_val=min_pos[0];
cudaMemcpy(&min_val, dev_MAD+abs_pos, sizeof(float), cudaMemcpyDeviceToHost);
// Print out the result
printf("Min=%.2f pos=%d\n",min_val,abs_pos);
但這個方案打印出來:最小= -207521258711807190000000000000000000000.00 POS = 0
我我們看過很多縮減的例子,但是似乎在每個人中他們都將值存儲在一個數組中,而不是在每個單獨的線程中。
所以對這些問題:
- 是否有可能使atomicMin函數返回的位置?
- 任何人都可以給我一個關於如何解決推力庫問題的提示嗎?
你已經理解正確:)我想實現你提到的第一種方式。據我所知,必須先使用thrust :: device_vector dev_MAD(n * m)聲明矢量,然後將其轉換爲原始指針float * dev_ptr = thrust :: raw_pointer_cast(dev_MAD.data()); 但是,如何索引向量。我嘗試過使用標準符號dev_MAD [idx * n + idy],但似乎沒有用所有值填充數組 –
user2594166
沒關係。得到它的工作:)非常感謝你! – user2594166