2017-09-04 39 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窗口選項作爲活動。 將其設置爲關閉固定它。