關於CUDA實現最值問題

2021-07-15 11:57:31 字數 4081 閱讀 4585

一轉眼一周就過去了,算來入職已經半個月了,專案也進行了十來天,感覺這一周受到最糾結的莫過於尋最值問題了。

聽起來尋最值應該是個很簡單的問題,當時的思路是這樣的,並行規約尋最值,並記錄下標,於是有了第一版的程式:

__global__ void max_reduce(int *d_array, int array_len, int *max_value, int *max_idx)

__share__ int temp_value_share[warp_size];

__share__ int temp_idx_share[warp_size];

int tid=thread.x+blockdim.x*blockidx.x;

int i,temp_value,temp_value1,temp_idx,temp_idx1;

int warpid=thread.x/warp_size,laneid=thread.x%warp_size;

if(tidtemp_value=d_array[tid];

temp_idx=thread.x;

for(i=warp_size/2;i>=1;i/=2)

temp_value1=shft_xor(temp_value,i,warp_size);

temp_idx1=shft_xor(temp_idx,i,warp_size);

if(temp_valuetemp_value=temp_value1;

temp_idx=temp_idx1;

}if(!laneid)

temp_value_share[warpid]=temp_value;

temp_idx_share[warpid]=temp_idx;

}__sychthreads();

if(thread.xtemp_value=temp_value_share[thread.x];

temp_idx=temp_idx_share[thread.x];

for(i=warp_size/2;i>=1;i/=2)

temp_value1=shft_xor(temp_value,i,warp_size);

temp_idx1=shft_xor(temp_idx,i,warp_size);

if(temp_valuetemp_value=temp_value1;

temp_idx=temp_idx1;}}

if(!thread.x)

max_value[blockidx.x]=temp_value;

max_idx[block.x]=temp_idx;

}}用例測試發現當陣列存在超過長度n,可能存在尋找的資料超過n的情況,在師兄的提示下,有了第二版:

__global__ void max_reduce(int *d_array, int array_len, int *max_value, int *max_idx)

__share__ int temp_value_share[warp_size];

__share__ int temp_idx_share[warp_size];

int tid=thread.x+blockdim.x*blockidx.x;

int i,temp_value,temp_value1,temp_idx,temp_idx1;

int warpid=thread.x/warp_size,laneid=thread.x%warp_size;

temp_value=-1e30;

temp_idx=thread.x;

if(tidtemp_value=d_array[tid];

}for(i=warp_size/2;i>=1;i/=2)

temp_value1=shft_xor(temp_value,i,warp_size);

temp_idx1=shft_xor(temp_idx,i,warp_size);

if(temp_valuetemp_value=temp_value1;

temp_idx=temp_idx1;

}if(!laneid)

temp_value_share[warpid]=temp_value;

temp_idx_share[warpid]=temp_idx;

}__sychthreads();

if(thread.xtemp_value=temp_value_share[thread.x];

temp_idx=temp_idx_share[thread.x];

for(i=warp_size/2;i>=1;i/=2)

temp_value1=shft_xor(temp_value,i,warp_size);

temp_idx1=shft_xor(temp_idx,i,warp_size);

if(temp_valuetemp_value=temp_value1;

temp_idx=temp_idx1;}}

if(!thread.x)

max_value[blockidx.x]=temp_value;

max_idx[block.x]=temp_idx;

}這個感覺應該沒問題了吧,可事實令我發狂,專案中剛開始是對的,可後面就錯了,為此,除錯了很久,結果發現最大值是對的,而下標是錯的,很顯然,存在相等的下標,這個讓我吃透了苦,於是有了第三版:

__global__ void max_reduce(int *d_array, int array_len, int *max_value, int *max_idx)

__share__ int temp_value_share[warp_size];

__share__ int temp_idx_share[warp_size];

int tid=thread.x+blockdim.x*blockidx.x;

int i,temp_value,temp_value1,temp_idx,temp_idx1;

int warpid=thread.x/warp_size,laneid=thread.x%warp_size;

temp_value=-1e30;

temp_idx=thread.x;

if(tidtemp_value=d_array[tid];

}for(i=warp_size/2;i>=1;i/=2)

temp_value1=shft_xor(temp_value,i,warp_size);

temp_idx1=shft_xor(temp_idx,i,warp_size);

if(temp_valuetemp_value=temp_value1;

temp_idx=temp_idx1;

else if(temp_value=temp_value1)

if(temp_idx>temp_idx1)

temp_idx=temp_idx1;}}

if(!laneid)

temp_value_share[warpid]=temp_value;

temp_idx_share[warpid]=temp_idx;

}__sychthreads();

if(thread.xtemp_value=temp_value_share[thread.x];

temp_idx=temp_idx_share[thread.x];

for(i=warp_size/2;i>=1;i/=2)

temp_value1=shft_xor(temp_value,i,warp_size);

temp_idx1=shft_xor(temp_idx,i,warp_size);

if(temp_valuetemp_value=temp_value1;

temp_idx=temp_idx1;

else if(temp_value=temp_value1)

if(temp_idx>temp_idx1)

temp_idx=temp_idx1;

}                                         }

}if(!thread.x)

max_value[blockidx.x]=temp_value;

max_idx[block.x]=temp_idx;

}

區間最值問題

實驗任務 已知乙個有 n 個數序列 a i 在序列 a 中的區間 l,r 中的最小值為 a p 求 a p a l a l 1 a r 的最大值為多少?資料輸入 第一行是乙個整數 n 第二行為 n 個整數對應 a i 對於 50 資料 1 n 5000 對於 100 資料 1 n 100 000 1...

區間最值問題

問題描述 給定m及n個數 1輸出每m個數中的最大數,即1m中的最大數,2m 1中的最大數 n m 1 n中的最大數,共n m 1個。陣列 將讀入的資料放到乙個線性表f陣列中,然後列舉開始點i,遍歷求出區間 i,i m 1 中最大值。堆 將資料組織成樹型結構,即將讀入的數值設計成乙個大根堆,則堆頂元素...

陣列問題之陣列最值問題 Java實現》

尋找陣列的最大值和最小值問題 author sking package 陣列問題 public class 陣列最值 if array.length 2 0 return new int 遞迴分治方法查詢陣列中的最大值和最小值 效能 比較次數為1.5 n 2 param array 當前考慮陣列段 ...