MCPcopy Create free account
hub / github.com/arrayfire/arrayfire / genBlocks

Method genBlocks

src/backend/cuda/threadsMgt.hpp:215–327  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

213// executed in the kernel
214template<typename T>
215inline dim3 threadsMgt<T>::genBlocks(const dim3& threads,
216 const unsigned nrInputs,
217 const unsigned nrOutputs,
218 const size_t totalSize,
219 const size_t sizeofT) {
220 // The bottleneck of anykernel is dependent on the type of memory
221 // used.
222 // a) For very small arrays (elements < maxParallelThreads), each
223 // element receives it individual thread.
224 // b) For arrays (in+out) smaller than 3/2 L2cache, memory access no
225 // longer is the bottleneck, because enough L2cache is available at any
226 // time. Threads are limited to reduce scheduling overhead.
227 // c) For very large arrays and type sizes (<long double), 1 thread will
228 // not generate enough data to keep the memory sync mechanism
229 // saturated, so we start loooping inside each thread.
230 dim3 blocks{1};
231 const int activeDeviceId{getActiveDeviceId()};
232 const unsigned* maxGridSize{
233 reinterpret_cast<const unsigned*>(getMaxGridSize(activeDeviceId))};
234 const size_t L2CacheSize{getL2CacheSize(activeDeviceId)};
235 const unsigned cacheLine{getMemoryBusWidth(activeDeviceId)};
236 const unsigned multiProcessorCount{getMultiProcessorCount(activeDeviceId)};
237 const unsigned maxThreads{maxParallelThreads *
238 (sizeofT * nrInputs * nrInputs > 8 ? 1 : 2)};
239
240 if (ndims == 1) {
241 if (d0 > maxThreads) {
242 if (totalSize * 2 > L2CacheSize * 3) {
243 // General formula to calculate best #loops
244 // Dedicated GPUs:
245 // 32/sizeof(T)**2/#outBuffers*(3/4)**(#inBuffers-1)
246 // Integrated GPUs:
247 // 4/sizeof(T)/#outBuffers*(3/4)**(#inBuffers-1)
248 unsigned largeVolDivider{cacheLine == 64
249 ? sizeofT == 1 ? 4
250 : sizeofT == 2 ? 2
251 : 1
252 : (sizeofT == 1 ? 32
253 : sizeofT == 2 ? 8
254 : 1) /
255 nrOutputs};
256 for (unsigned i{1}; i < nrInputs; ++i)
257 largeVolDivider = largeVolDivider * 3 / 4;
258 if (largeVolDivider > 1) {
259 blocks.x = d0 / (largeVolDivider * threads.x);
260 if (blocks.x == 0) blocks.x = 1;
261 loop0 = true;
262 }
263 } else {
264 // A reduction to (1|2*)maxParallelThreads will be
265 // performed
266 blocks.x = maxThreads / threads.x;
267 if (blocks.x == 0) blocks.x = 1;
268 loop0 = true;
269 }
270 }
271 if (!loop0) { blocks.x = divup(d0, threads.x); }
272 } else {

Callers 3

evalNodesFunction · 0.80
memcopyFunction · 0.80
copyFunction · 0.80

Calls 5

getMaxGridSizeFunction · 0.85
getMultiProcessorCountFunction · 0.85
getActiveDeviceIdFunction · 0.70
getL2CacheSizeFunction · 0.70
getMemoryBusWidthFunction · 0.70

Tested by

no test coverage detected