質問編集履歴

4

コードの修正

2020/03/15 09:11

投稿

shukrin
shukrin

スコア14

test CHANGED
File without changes
test CHANGED
@@ -102,11 +102,17 @@
102
102
 
103
103
  //ホスト側の配列を用意
104
104
 
105
- a = (float*)malloc(N * sizeof(float));
105
+ //a = (float*)malloc(N * sizeof(float));
106
-
106
+
107
- b = (float*)malloc(N * sizeof(float));
107
+ //b = (float*)malloc(N * sizeof(float));
108
-
108
+
109
- c = (float*)malloc(N * sizeof(float));
109
+ //c = (float*)malloc(N * sizeof(float));
110
+
111
+ cudaMallocHost(&a, N * sizeof(float));
112
+
113
+ cudaMallocHost(&b, N * sizeof(float));
114
+
115
+ cudaMallocHost(&c, N * sizeof(float));
110
116
 
111
117
 
112
118
 
@@ -138,73 +144,107 @@
138
144
 
139
145
  std::chrono::system_clock::time_point start, memcpyh2d, memcpyd2h, gpus, gpue, cpu;
140
146
 
141
- start = std::chrono::system_clock::now();
142
-
143
147
  std::cout << "-----TimeStart-----" << std::endl;
144
148
 
145
149
 
146
150
 
147
- //ホスト側の配列の内容をデバイス側にコピー
148
-
149
- cudaMemcpy(d_a, a, N * sizeof(float), cudaMemcpyHostToDevice);
150
-
151
- cudaMemcpy(d_b, b, N * sizeof(float), cudaMemcpyHostToDevice);
152
-
153
- cudaMemcpy(d_c, c, N * sizeof(float), cudaMemcpyHostToDevice);
154
-
155
-
156
-
157
- //ホストの配列をデバイス側にコピーするのにかかった時間
158
-
159
- memcpyh2d = std::chrono::system_clock::now();
160
-
161
-
162
-
163
- //スレッドの設定
164
-
165
- int blocksize = 512;
166
-
167
-
168
-
169
- //ブロックあたりのスレッド数(blocksize)を512、
170
-
171
- //ブロ総数(gridsize)をN/512用意する
172
-
173
- //したがって総スレッド数は blocksize × gridsize = N 個
174
-
175
- dim3 block(blocksize, 1, 1);
176
-
177
- dim3 grid(N / block.x, 1, 1);
178
-
179
-
180
-
181
- //GPUの計算時間計測開始
182
-
183
- gpus = std::chrono::system_clock::now();
184
-
185
-
186
-
187
- // カーネル関数の呼び出し
188
-
189
- vec_sum_k <<<grid, block>>>(2.0f, d_a, d_b, d_c);
190
-
191
- cudaDeviceSynchronize();
192
-
193
-
194
-
195
- //GPU計算時間計測終了
196
-
197
- gpue = std::chrono::system_clock::now();
198
-
199
-
200
-
201
- //計算結果をホストへコピー
202
-
203
- cudaMemcpy(c, d_c, N * sizeof(float), cudaMemcpyDeviceToHost);
204
-
205
-
206
-
207
- //計算結果をホストにコピー。GPUの計算終わり。CPUの計算時間計測開始
151
+ for (int i = 0; i < 10; i++) {
152
+
153
+
154
+
155
+ start = std::chrono::system_clock::now();
156
+
157
+
158
+
159
+ //ホスト側の配列の内容をデバイス側にコピー
160
+
161
+ cudaMemcpy(d_a, a, N * sizeof(float), cudaMemcpyHostToDevice);
162
+
163
+ cudaMemcpy(d_b, b, N * sizeof(float), cudaMemcpyHostToDevice);
164
+
165
+ cudaMemcpy(d_c, c, N * sizeof(float), cudaMemcpyHostToDevice);
166
+
167
+
168
+
169
+ //ホストの配列をデバイス側にコピーするのにかかった時間
170
+
171
+ memcpyh2d = std::chrono::system_clock::now();
172
+
173
+
174
+
175
+ //スレ設定
176
+
177
+ int blocksize = 256;
178
+
179
+
180
+
181
+ //ブロックあたりのスレッド数(blocksize)を512、
182
+
183
+ //ブロックの総数(gridsize)をN/512用意する
184
+
185
+ //したがって総スレッド数は blocksize × gridsize = N 個
186
+
187
+ dim3 block(blocksize, 1, 1);
188
+
189
+ dim3 grid(N / block.x, 1, 1);
190
+
191
+
192
+
193
+ //GPUの計算時間計測開始
194
+
195
+ gpus = std::chrono::system_clock::now();
196
+
197
+
198
+
199
+ // カーネル関数呼び出し
200
+
201
+ vec_sum_k << <grid, block >> > (2.0f, d_a, d_b, d_c);
202
+
203
+ cudaDeviceSynchronize();
204
+
205
+
206
+
207
+ //GPUの計算時間計測終了
208
+
209
+ gpue = std::chrono::system_clock::now();
210
+
211
+
212
+
213
+ //計算結果をホストへコピー
214
+
215
+ cudaMemcpy(c, d_c, N * sizeof(float), cudaMemcpyDeviceToHost);
216
+
217
+
218
+
219
+ //計算結果をホストにコピー。GPUの計算終わり。
220
+
221
+ memcpyd2h = std::chrono::system_clock::now();
222
+
223
+
224
+
225
+ // 計測時間の表示
226
+
227
+ std::cout << "-------GPULoop: " << i << " -------" << std::endl;
228
+
229
+ double HtDtime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(memcpyh2d - start).count());
230
+
231
+ std::cout << "memcpy(HtD): " << HtDtime << " microsec" << std::endl;
232
+
233
+ double gputime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(gpue - gpus).count());
234
+
235
+ std::cout << "gpu: " << gputime << " microsec" << std::endl;
236
+
237
+ double DtHtime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(memcpyd2h - gpue).count());
238
+
239
+ std::cout << "memcpy(DtH): " << DtHtime << " microsec" << std::endl;
240
+
241
+
242
+
243
+ }
244
+
245
+
246
+
247
+ //計算結果をホストにコピー。GPUの計算終わり。CPUの計算開始
208
248
 
209
249
  memcpyd2h = std::chrono::system_clock::now();
210
250
 
@@ -234,17 +274,7 @@
234
274
 
235
275
  //計測時間の表示
236
276
 
237
- double HtDtime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(memcpyh2d - start).count());
238
-
239
- std::cout << "memcpy(HtD): " << HtDtime << " microsec" << std::endl;
240
-
241
- double gputime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(gpue - gpus).count());
242
-
243
- std::cout << "gpu: " << gputime << " microsec" << std::endl;
277
+ std::cout << "-------CPU-------" << std::endl;
244
-
245
- double DtHtime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(memcpyd2h - gpue).count());
246
-
247
- std::cout << "memcpy(DtH): " << DtHtime << " microsec" << std::endl;
248
278
 
249
279
  double cputime = static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(cpu - memcpyd2h).count());
250
280
 

3

タイトルの修正

2020/03/15 09:11

投稿

shukrin
shukrin

スコア14

test CHANGED
@@ -1 +1 @@
1
- 【CUDA】cudaMemcpyに時間がかかり思ったほど速度が出ないときの対処法
1
+ 【CUDA】cudaMemcpyに時間がかかり速度が出ないときの対処法
test CHANGED
File without changes

2

コードの修正

2020/03/14 17:53

投稿

shukrin
shukrin

スコア14

test CHANGED
File without changes
test CHANGED
@@ -66,7 +66,7 @@
66
66
 
67
67
  for (int i = 0; i < N; i++) {
68
68
 
69
- c[0] = k * a[i] + b[i];
69
+ c[i] = k * a[i] + b[i];
70
70
 
71
71
  }
72
72
 

1

「実現したいこと」を一部修正

2020/03/14 17:48

投稿

shukrin
shukrin

スコア14

test CHANGED
File without changes
test CHANGED
@@ -284,7 +284,7 @@
284
284
 
285
285
  メモリコピーの時間を含めてCPUより高速で動作するようなCUDAプログラムを作成するためにはどのような方法があるでしょうか?
286
286
 
287
- また計算自体は高速化されているとはいえ、期待したほど(十倍~数百倍以上)ではないのも気になります。計算の高速化のためにはどのような工夫ができるでしょうか?
287
+ また計算自体は高速化されているとはいえ、期待したほど(十倍~数百倍以上)ではないのも気になります。上記サイトの結果では少なくとも3000倍の高速化に成功していたようです。私のプログラムがそれほど高速化されていない理由は何でしょうか? また計算の高速化のためにはどのような工夫ができるでしょうか?
288
288
 
289
289
 
290
290