From c0087b3b65282c4a5576476c1e93bf59a02ee67b Mon Sep 17 00:00:00 2001
From: foreman
Date: Fri, 12 Dec 2014 12:26:52 -0500
Subject: [PATCH] P4 to Git Change 1104993 by gandryey@gera-ubuntu14 on
2014/12/12 12:19:20
EPR #410797 - Specific OCL kernel is 5x slower on Hawaii than on Nvidia K40 GPU when tested under Linux.
- The logic for local workgroup size search was prioritizing ALU utilization, but with multidemensional launches X dimension could affect address calculation and cacheline utlization more than others. Add cacheline size into the consideration.
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.cpp#270 edit
[ROCm/clr commit: 674da4560de6aa5127f7686ee0f0466671640b86]
---
.../rocclr/runtime/device/gpu/gpukernel.cpp | 38 ++++++++++++++-----
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp b/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp
index 25389cbdf5..b97fd9dcca 100644
--- a/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp
+++ b/projects/clr/rocclr/runtime/device/gpu/gpukernel.cpp
@@ -1162,11 +1162,15 @@ Kernel::findLocalWorkSize(
lclWorkSize[d] = div;
tmp /= div;
}
+ // Assuming DWORD access
+ const uint cacheLineMatch = dev().settings().cacheLineSize_ >> 2;
// Check if partial dispatch is enabled and
if (dev().settings().partialDispatch_ &&
- // we couldn't find optimal workload
- (lclWorkSize.product() % workGroupInfo()->wavefrontSize_) != 0) {
+ // we couldn't find optimal workload
+ (((lclWorkSize.product() % workGroupInfo()->wavefrontSize_) != 0) ||
+ // or size is too small for the cache line
+ (lclWorkSize[0] < cacheLineMatch))) {
size_t maxSize = 0;
size_t maxDim = 0;
for (uint d = 0; d < workDim; ++d) {
@@ -1175,16 +1179,30 @@ Kernel::findLocalWorkSize(
maxDim = d;
}
}
- // Check if a local workgroup has the most optimal size
- if (thrPerGrp > maxSize) {
- thrPerGrp = maxSize;
- }
- lclWorkSize[maxDim] = thrPerGrp;
- for (uint d = 0; d < workDim; ++d) {
- if (d != maxDim) {
- lclWorkSize[d] = 1;
+ // Use X dimension as high priority. Runtime will assume that
+ // X dimension is more important for the address calculation
+ if ((maxDim != 0) && (gblWorkSize[0] >= (cacheLineMatch / 2))) {
+ lclWorkSize[0] = cacheLineMatch;
+ thrPerGrp /= cacheLineMatch;
+ lclWorkSize[maxDim] = thrPerGrp;
+ for (uint d = 1; d < workDim; ++d) {
+ if (d != maxDim) {
+ lclWorkSize[d] = 1;
+ }
}
}
+ else {
+ // Check if a local workgroup has the most optimal size
+ if (thrPerGrp > maxSize) {
+ thrPerGrp = maxSize;
+ }
+ lclWorkSize[maxDim] = thrPerGrp;
+ for (uint d = 0; d < workDim; ++d) {
+ if (d != maxDim) {
+ lclWorkSize[d] = 1;
+ }
+ }
+ }
}
}
}