2017-09-04 43 views
0

我在下面的代码(它是一个模式减少)获取启动错误,并且经过一段时间后,我注意到对于较小的值比39的q是好的,但如果它变得更高,我会得到启动错误。内核上的嵌套循环上的可能的堆栈溢出

在开始我认为它是嵌套循环的数量过多,但在底部,我注意到即使使用附加的嵌套循环,较低的值q也可以。

在cuda调试模式下,不报告错误。

问题

  • 它是一个堆栈错误?
  • 假设q的最大值等于最大值 无符号短小它仍然可行吗?

所作的代码简单越好:

#include "device_launch_parameters.h" 
#include "stdlib.h" 
#include "cuda.h" 
#include <helper_functions.h> // includes cuda.h and cuda_runtime_api.h 
#include <helper_cuda.h>   // helper functions for CUDA error check 
#include <stdio.h> 
#include <cuda_runtime.h> 
#include <stdio.h> 

__global__ void loopTest(int q, int *ops, short* best) { 
    int i, j, k, l, m, n, o, p; 
    const int off(8); 
    int maxSum(0), sum; 
    const int qi = (q - blockDim.x * blockIdx.x + threadIdx.x); 
    if (qi < 0) return; 
    // qi, the upper for limit reduces as threadId increases 
    for (i = 0; i < qi - off + 0; i++) 
     for (j = i + 1; j < qi - off + 1; j++) 
      for (k = j + 1; k < qi - off + 2; k++) 
       for (l = k + 1; l < qi - off + 3; l++) 
        for (m = l + 1; m < qi - off + 4; m++) 
         for (n = m + 1; n < qi - off + 5; n++) 
          for (o = n + 1; o < qi - off + 6; o++) 
           for (p = o + 1; p < qi - off + 7; p++) 
            { 
             sum = i + j + k + l + m + n + o + p; 
             if (sum > maxSum) { 
              best[0] = i; 
              best[1] = j; 
              best[2] = k; 
              best[3] = l; 
              best[4] = n; 
              best[5] = m; 
              best[6] = o; 
              best[7] = p; 
              maxSum = sum; 
             } 
            } 
    ops[0] = maxSum; 
    printf("max %d:", maxSum); 
} 

int main() { 
    int *d_ops; 
    short *d_best; 
    cudaError_t cudaStatus; 
    cudaStatus = cudaMalloc((void**)(&d_ops), sizeof(int)); 
    cudaStatus = cudaMalloc((void**)(&d_best), sizeof(short) * 8); 

    // any q value smaller than 39 is fine, no error, but anything higher there is launch error 

    loopTest << <1, 1 >> > (38, d_ops, d_best); 

    cudaDeviceSynchronize(); 
    cudaStatus = cudaGetLastError(); 
    if (cudaStatus != cudaSuccess) { 
     fprintf(stderr, "failure: %s", cudaGetErrorString(cudaStatus)); 
     return 99; 
    } 
    cudaStatus = cudaFree(d_ops); 
    cudaStatus = cudaFree(d_best); 
    cudaStatus = cudaDeviceReset(); 
    cudaStatus = cudaGetLastError(); 
    getchar(); 
    return cudaStatus; 
} 

背景

尽管高往往频非活动线程的(因为q valeu是intial_q - threadIdx.x)它避免了数据传送从主机。这是我发现横跨替代集群分区的最佳方式。

规则

  • 所有元件必须娄于单个簇(又名硬聚类)
  • 所有簇必须至少有一种元素
  • 在向量中的元素的位置是固定

(4个分区,10个元素,群集bondaries是显示波纹管)

ALT轻拍1:1-1,2-2,3-3,4-10 (每个集群元素,除了最后一个塔具有元素{4,5,6,7,8,9和10}

ALT轻拍2:1-1,2-2,3-4,5-10 (与上述相同,但是第4簇具有元素{3和4}并且最后具有元素{5,6,7,8,9和10}

...

ALT轻拍X:1-1,2-2,3-9,10-10

ALT轻拍X + 1:1-1,2-3,4-4,5-10

alt pat x + 2:1-1,2-3,4-5,6-10

...

ALT轻拍Y:1-7,8-8,9-9,10-10

最后可能的分区具有第一集群中的元素的最大数量,从而任何其他簇具有单一元素

+2

你推出错误可能是一个内核超时。 (您没有“非常频繁的非活动线程”;您只启动1个线程。)如果您在Windows上,请使用谷歌“cuda wddm timeout”并按照说明进行操作。如果你在linux上,请阅读[this](http://nvidia.custhelp.com/app/answers/detail/a_id/3029/~/using-cuda-and-x)。也完全可能的是,如果你在错误检查方面做得更好(打印出错误字符串),它甚至可能会说“内核超时并被终止”。试试这个:'fprintf中(错误, “失败:%S”,cudaGetErrorString(cudaStatus));' –

+0

@RobertCrovella **你说得对TDR!它修复了它,因为错误来自无处(代码没有改变,只是另一台计算机),所以我疯了。 我使用的完整代码完整的错误字符串,但只给了我“未指定发射失败的” 关于“高常频不活动线程的”自循环“帽”取为laneID增幅较小,预计至少在同一个warp中的线程之间存在细微的差异,但它对于集群模式来说是固有的 感谢支持 –

回答

0

未指定的发射失败是由于内核超时。 这是由于长期的处理成本和TDR窗口选项作为活动。 将其设置为关闭固定它。