Successive blocks reading memory from initial blocks
所以这是我的程序的一部分,我为两个班级做了一个减少总和。我用共享数组 __shared__ int nrules[max_threads * MAX_CLASSES]; 的一半对类进行索引,因此第一类从 nrules[0] 开始,第二类从 nrules[blockDim.x or max_threads] 开始。对两半进行了减少。总和保存在作为参数传递的全局数组中,该数组将保留每个块的总和,因此由 blockIdx.x.
索引
我有一个测试用例的大小,用MAX_SIZE表示,所有测试首先从1处理到MAX_SIZE,每个块的总和在全局数组中累加。
我想调用一个块数等于我的测试数(10000)的内核,但是总和有一些问题,所以我改为逐步进行。
我找不到解决方案,但是每当我调用块数超过 max_threads 的内核时,它就会开始从初始块中求和。如果您执行代码,您将看到它将打印每个块的值,在这种情况下为 64,每个块有 64 个线程。如果我再执行至少 1 个块,则总和将改为 128。这用于第一类总和。就好像偏移变量什么都不做,而写入再次发生在第一个块中。在 MAX_SIZE = 3 的情况下,第一个块的第二类总和更改为 192。
此处的 Cuda 功能是 2.0,即 GT 520 卡。使用 CUDA 6.5 编译。
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
#include <stdio.h>
#include <cuda.h> #include <cuda_runtime.h> #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } } #define MAX_CLASSES 2 __device__ __constant__ int d_MAX_SIZE; __device__ void rules_points_reduction(float points[max_threads * MAX_CLASSES], int nrules[max_threads * MAX_CLASSES]){ float psum[MAX_CLASSES]; for (int i = 0; i < MAX_CLASSES; i++){ __syncthreads(); if (blockDim.x >= 1024) { } __syncthreads(); if (threadIdx.x < 32) } __device__ void d_get_THE_prediction(short k, float* finalpoints, int* gn_rules) __shared__ float points[max_threads * MAX_CLASSES]; for (int i = 0; i < MAX_CLASSES; i++) if (threadIdx.x == 0) { //max = max2; //d_induce_rules(items, ele, n_items, k, max, nrules, points); __syncthreads(); rules_points_reduction(points, nrules); if (threadIdx.x == 0){ for (int i = 0; i < MAX_CLASSES; i++){ } } __global__ void lazy_supervised_classification_kernel(int k, float* finalpoints, int* n_rules){ d_get_THE_prediction( k, finalpoints, n_rules); }
int main() { int N_TESTS = 10000; float *finalpoints = (float*)calloc(MAX_CLASSES * N_TESTS, sizeof(float)); int *d_nruls = 0; gpuErrchk(cudaMalloc(&d_finalpoints, MAX_CLASSES * N_TESTS * sizeof(float))); gpuErrchk(cudaMalloc(&d_nruls, MAX_CLASSES * N_TESTS * sizeof(int))); gpuErrchk(cudaMemcpyToSymbol(d_MAX_SIZE, &MAX_SIZE, sizeof(int), 0, cudaMemcpyHostToDevice)); int step = max_threads, ofset = 0; for (int k = 1; k < MAX_SIZE; k++){ //N_TESTS-step gpuErrchk(cudaMemcpyToSymbol(offset, &ofset, sizeof(int), 0, cudaMemcpyHostToDevice)); gpuErrchk(cudaMemcpyToSymbol(offset, &ofset, sizeof(int), 0, cudaMemcpyHostToDevice));//comment these lines } gpuErrchk(cudaDeviceReset()); |
我不相信这个索引是你想要的:
|
1
2 |
gn_rules[(blockIdx.x + offset) + i * blockDim.x] += …;
finalpoints[(blockIdx.x + offset) + i * blockDim.x] += …; |
对于 MAX_CLASSES = 2,每个块需要存储 2 个 finalpoints 值和 2 个 gn_rules 值。因此,当 offset 非零时,它需要按 MAX_CLASSES 值缩放,以便索引到该块的正确存储的开始。
所以如果你把上面的代码行改成:
|
1
2 |
gn_rules[(blockIdx.x + (offset*MAX_CLASSES)) + i * blockDim.x] += nrules[i * blockDim.x];
finalpoints[(blockIdx.x + (offset*MAX_CLASSES)) + i * blockDim.x] += points[i * blockDim.x]; |
我相信你会得到你期望的输出。
- 确实现在输出是正确的,谢谢。但我只想启动一个带有 N_TESTS 块的内核,而不是按步骤进行。它刚刚出现在我的脑海中,对于 n_rules 并指向它的 i * blockDim.x,但对于我使用 gridDim.x 的 finalpoints 和 G_nrules,我最终混淆了两者试图匹配它们的索引。
来源:https://www.codenong.com/26539459/
