[英]How can I use shared memory here in my CUDA kernel?
我有以下CUDA內核:
__global__ void optimizer_backtest(double *data, Strategy *strategies, int strategyCount, double investment, double profitability) {
// Use a grid-stride loop.
// Reference: https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/
for (int i = blockIdx.x * blockDim.x + threadIdx.x;
i < strategyCount;
i += blockDim.x * gridDim.x)
{
strategies[i].backtest(data, investment, profitability);
}
}
TL; DR我想找到一種在共享( __shared__
)內存中存儲data
的方法。 我不明白的是如何使用多個線程來填充共享變量。
我曾見過這樣的例子這樣一個地方data
被線程復制到共享內存的線程(如myblock[tid] = data[tid]
但我不知道如何在我的情況下做到這一點。 問題在於,每個線程都需要通過數據集的每次迭代訪問整個“行”(平整的)數據(請參見下文中調用內核的更多信息)。
我希望這樣的事情:
__global__ void optimizer_backtest(double *data, Strategy *strategies, int strategyCount, int propertyCount, double investment, double profitability) {
__shared__ double sharedData[propertyCount];
// Use a grid-stride loop.
// Reference: https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/
for (int i = blockIdx.x * blockDim.x + threadIdx.x;
i < strategyCount;
i += blockDim.x * gridDim.x)
{
strategies[i].backtest(sharedData, investment, profitability);
}
}
以下是更多詳細信息(如果需要更多信息,請詢問!):
strategies
是一個指向列表Strategy
對象,並且data
是指向所分配的扁平數據數組。
在backtest()
我這樣訪問數據:
data[0]
data[1]
data[2]
...
未展平的數據是固定大小的2D數組,類似於此:
[87.6, 85.4, 88.2, 86.1]
84.1, 86.5, 86.7, 85.9
86.7, 86.5, 86.2, 86.1
...]
至於內核調用,我遍歷數據項並為n個數據行(約350萬)調用n次:
int dataCount = 3500000;
int propertyCount = 4;
for (i=0; i<dataCount; i++) {
unsigned int dataPointerOffset = i * propertyCount;
// Notice pointer arithmetic.
optimizer_backtest<<<32, 1024>>>(devData + dataPointerOffset, devStrategies, strategyCount, investment, profitability);
}
正如您的評論中確認的那樣,您想對3.5m數據中的每一個應用20k(此數字來自您先前的問題)並檢查20k x 3.5m的結果。
如果沒有共享內存,則必須從全局內存讀取20k次所有數據或3.5m次所有策略。
共享內存可以通過減少全局內存訪問來加速程序。 假設您每次可以讀取1k策略和1k數據以共享mem,檢查1k x 1k的結果,然后重復進行直到所有內容都經過檢查。 這樣,您可以將全局內存訪問減少到所有數據的20倍和所有策略的3.5k倍。 這種情況類似於矢量-矢量叉積。 您可以找到一些參考代碼以獲取更多詳細信息。
但是,您的每個數據都很大(838-D矢量),也許策略也很大。 您可能無法在共享內存中緩存很多緩存(根據設備類型,每個塊只能緩存約48k)。 因此情況變成了矩陣矩陣乘法之類的東西。 為此,您可以從矩陣乘法代碼中獲得一些提示,如以下鏈接所示。
http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory
對於以后尋求類似答案的人們,這是我最終為我的內核函數准備的:
__global__ void optimizer_backtest(double *data, Strategy *strategies, int strategyCount, double investment, double profitability) {
__shared__ double sharedData[838];
if (threadIdx.x < 838) {
sharedData[threadIdx.x] = data[threadIdx.x];
}
__syncthreads();
// Use a grid-stride loop.
// Reference: https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/
for (int i = blockIdx.x * blockDim.x + threadIdx.x;
i < strategyCount;
i += blockDim.x * gridDim.x)
{
strategies[i].backtest(sharedData, investment, profitability);
}
}
請注意,我在應用程序中同時使用了.cuh和.cu文件,並將其放在.cu文件中。 另請注意,編譯目標文件時,我在Makefile中使用--device-c
。 我不知道這是應該怎么做,但這對我有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.