Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory cudamemcpy错误:“;发射超时并被终止;_Memory_Timeout_Cuda - Fatal编程技术网

Memory cudamemcpy错误:“;发射超时并被终止;

Memory cudamemcpy错误:“;发射超时并被终止;,memory,timeout,cuda,Memory,Timeout,Cuda,我的代码是计算π的第n位的并行实现。当我完成内核并尝试将内存复制回主机时,会出现“启动超时并被终止”错误。 我使用这段代码对每个cudamaloc、cudamemcpy和内核启动进行错误检查 std::string error = cudaGetErrorString(cudaGetLastError()); printf("%s\n", error); 这些调用表示一切正常,直到从内核返回后的第一个cudamemcpy调用。错误发生在main中的行“cudaMemcpy(avhost,avd

我的代码是计算π的第n位的并行实现。当我完成内核并尝试将内存复制回主机时,会出现“启动超时并被终止”错误。 我使用这段代码对每个cudamaloc、cudamemcpy和内核启动进行错误检查

std::string error = cudaGetErrorString(cudaGetLastError());
printf("%s\n", error);
这些调用表示一切正常,直到从内核返回后的第一个cudamemcpy调用。错误发生在main中的行“cudaMemcpy(avhost,avdev,size,cudaMemcpyDeviceToHost);”中。感谢您的帮助

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define mul_mod(a,b,m) fmod( (double) a * (double) b, m)
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/* return the inverse of x mod y */
__device__ int inv_mod(int x,int y) {
  int q,u,v,a,c,t;

  u=x;
  v=y;
  c=1;
  a=0;
  do {
    q=v/u;

    t=c;
    c=a-q*c;
    a=t;

    t=u;
    u=v-q*u;
    v=t;
  } while (u!=0);
  a=a%y;
  if (a<0) a=y+a;
  return a;
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/* return the inverse of u mod v, if v is odd */
__device__ int inv_mod2(int u,int v) {
  int u1,u3,v1,v3,t1,t3;

  u1=1;
  u3=u;

  v1=v;
  v3=v;

  if ((u&1)!=0) {
    t1=0;
    t3=-v;
    goto Y4;
  } else {
    t1=1;
    t3=u;
  }

  do {

    do {
      if ((t1&1)==0) {
    t1=t1>>1;
    t3=t3>>1;
      } else {
    t1=(t1+v)>>1;
    t3=t3>>1;
      }
      Y4:;
    } while ((t3&1)==0);

    if (t3>=0) {
      u1=t1;
      u3=t3;
    } else {
      v1=v-t1;
      v3=-t3;
    }
    t1=u1-v1;
    t3=u3-v3;
    if (t1<0) {
      t1=t1+v;
    }
  } while (t3 != 0);
  return u1;
}


/* return (a^b) mod m */
__device__ int pow_mod(int a,int b,int m)
{
  int r,aa;

  r=1;
  aa=a;
  while (1) {
    if (b&1) r=mul_mod(r,aa,m);
    b=b>>1;
    if (b == 0) break;
    aa=mul_mod(aa,aa,m);
  }
  return r;
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/* return true if n is prime */
int is_prime(int n)
{
   int r,i;
   if ((n % 2) == 0) return 0;

   r=(int)(sqrtf(n));
   for(i=3;i<=r;i+=2) if ((n % i) == 0) return 0;
   return 1;
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/* return the prime number immediatly after n */
int next_prime(int n)
{
   do {
      n++;
   } while (!is_prime(n));
   return n;
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
#define DIVN(t,a,v,vinc,kq,kqinc)       \
{                       \
  kq+=kqinc;                    \
  if (kq >= a) {                \
    do { kq-=a; } while (kq>=a);        \
    if (kq == 0) {              \
      do {                  \
    t=t/a;                  \
    v+=vinc;                \
      } while ((t % a) == 0);           \
    }                       \
  }                     \
}

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

__global__ void digi_calc(int *s, int *av, int *primes, int N, int n, int nthreads){
    int a,vmax,num,den,k,kq1,kq2,kq3,kq4,t,v,i,t1, h;
    unsigned int tid = blockIdx.x*blockDim.x + threadIdx.x;
// GIANT LOOP
    for (h = 0; h<1; h++){
    if(tid > nthreads) continue;
    a = primes[tid];
    vmax=(int)(logf(3*N)/logf(a));
    if (a==2) {
      vmax=vmax+(N-n);
      if (vmax<=0) continue;
    }
    av[tid]=1;
    for(i=0;i<vmax;i++) av[tid]*= a;

    s[tid]=0;
    den=1;
    kq1=0;
    kq2=-1;
    kq3=-3;
    kq4=-2;
    if (a==2) {
      num=1;
      v=-n; 
    } else {
      num=pow_mod(2,n,av[tid]);
      v=0;
    }

    for(k=1;k<=N;k++) {

      t=2*k;
      DIVN(t,a,v,-1,kq1,2);
      num=mul_mod(num,t,av[tid]);

      t=2*k-1;
      DIVN(t,a,v,-1,kq2,2);
      num=mul_mod(num,t,av[tid]);

      t=3*(3*k-1);
      DIVN(t,a,v,1,kq3,9);
      den=mul_mod(den,t,av[tid]);

      t=(3*k-2);
      DIVN(t,a,v,1,kq4,3);
      if (a!=2) t=t*2; else v++;
      den=mul_mod(den,t,av[tid]);

      if (v > 0) {
    if (a!=2) t=inv_mod2(den,av[tid]);
    else t=inv_mod(den,av[tid]);
    t=mul_mod(t,num,av[tid]);
    for(i=v;i<vmax;i++) t=mul_mod(t,a,av[tid]);
    t1=(25*k-3);                                                                                                                                                                                                                                                                                                                                                                       
    t=mul_mod(t,t1,av[tid]);
    s[tid]+=t;
    if (s[tid]>=av[tid]) s-=av[tid];
      }
    }

    t=pow_mod(5,n-1,av[tid]);
    s[tid]=mul_mod(s[tid],t,av[tid]);
    }
    __syncthreads();
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
int main(int argc,char *argv[])
{
  int N,n,i,totalp, h;
  double sum;
  const char *error;
  int *sdev, *avdev, *shost, *avhost, *adev, *ahost;
    argc = 2;
    argv[1] = "2";
  if (argc<2 || (n=atoi(argv[1])) <= 0) {
    printf("This program computes the n'th decimal digit of pi\n"
       "usage: pi n , where n is the digit you want\n"
       );
    exit(1);
  }
    sum = 0;
    N=(int)((n+20)*logf(10)/logf(13.5));
    totalp=(N/logf(N))+10;
    ahost = (int *)calloc(totalp, sizeof(int));
    i = 0;
    ahost[0]=2;
    for(i=1; ahost[i-1]<=(3*N); ahost[i+1]=next_prime(ahost[i])){
        i++;
    }
    // allocate host memory
    size_t size = i*sizeof(int);
    shost = (int *)malloc(size);
    avhost = (int *)malloc(size);

  //allocate memory on device
    cudaMalloc((void **) &sdev, size);
    cudaMalloc((void **) &avdev, size);
    cudaMalloc((void **) &adev, size);
    cudaMemcpy(adev, ahost, size, cudaMemcpyHostToDevice);

    if (i >= 512){
        h = 512;
    }
    else h = i;
    dim3 dimGrid(((i+512)/512),1,1);                   
    dim3 dimBlock(h,1,1);

    // launch kernel
    digi_calc <<<dimGrid, dimBlock >>> (sdev, avdev, adev, N, n, i);

    //copy memory back to host
    cudaMemcpy(avhost, avdev, size, cudaMemcpyDeviceToHost);
    cudaMemcpy(shost, sdev, size, cudaMemcpyDeviceToHost);

  // end malloc's, memcpy's, kernel calls
    for(h = 0; h <=i; h++){
    sum=fmod(sum+(double) shost[h]/ (double) avhost[h],1.0);
    }
  printf("Decimal digits of pi at position %d: %09d\n",n,(int)(sum*1e9));
    //free memory
    cudaFree(sdev);
    cudaFree(avdev);
    cudaFree(adev);
    free(shost);
    free(avhost);
    free(ahost);
  return 0;
}
#包括
#包括
#包括
#定义多模式(a,b,m)fmod((双)a*(双)b,m)
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/*返回x mod y的倒数*/
__设备内部库存模块(内部x,内部y){
int q,u,v,a,c,t;
u=x;
v=y;
c=1;
a=0;
做{
q=v/u;
t=c;
c=a-q*c;
a=t;
t=u;
u=v-q*u;
v=t;
}而(u!=0);
a=a%y;
如果(a>1;
t3=t3>>1;
}否则{
t1=(t1+v)>>1;
t3=t3>>1;
}
Y4:;
}而((t3&1)==0);
如果(t3>=0){
u1=t1;
u3=t3;
}否则{
v1=v-t1;
v3=-t3;
}
t1=u1-v1;
t3=u3-v3;
如果(t1>1;
如果(b==0)中断;
aa=多模态(aa,aa,m);
}
返回r;
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/*如果n是素数,则返回true*/
int是素数(int n)
{
int r,i;
if((n%2)==0)返回0;
r=(int)(sqrtf(n));
对于(i=3;i=a){\
do{kq-=a;}while(kq>=a)\
如果(kq==0){\
做{\
t=t/a\
v+=vinc\
}而((t%a)==0)\
}                       \
}                     \
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
__全局无效数字计算(int*s,int*av,int*primes,int N,int N,int nthreads){
int a,vmax,num,den,k,kq1,kq2,kq3,kq4,t,v,i,t1,h;
unsigned int tid=blockIdx.x*blockDim.x+threadIdx.x;
//巨环
对于(h=0;h n)继续;
a=素数[tid];
vmax=(int)(logf(3*N)/logf(a));
如果(a==2){
vmax=vmax+(N-N);

如果(vmax,这与您在中询问的问题完全相同。内核被驱动程序提前终止,因为它花费的时间太长。如果您阅读这些运行时API函数的文档,您将看到以下注意事项:

注: 请注意,此函数还可能返回以前的错误代码, 异步启动

所发生的一切是,内核启动后的第一个API调用返回内核运行时发生的错误——在本例中是cudaMemcpy调用。您可以自己确认这一点的方法是在内核启动后直接执行类似操作:

// launch kernel
digi_calc <<<dimGrid, dimBlock >>> (sdev, avdev, adev, N, n, i);
std::string error = cudaGetErrorString(cudaPeekAtLastError());
printf("%s\n", error);
error = cudaGetErrorString(cudaThreadSynchronize());
printf("%s\n", error);
//启动内核
数字计算(sdev、avdev、adev、N、N、i);
std::string error=cudaGetErrorString(cudaPeekAtLastError());
printf(“%s\n”,错误);
错误=cudaGetErrorString(cudaThreadSynchronize());
printf(“%s\n”,错误);
cudaPeekAtLastError()
调用将显示内核启动中是否存在任何错误,而
cudaThreadSynchronize()
调用返回的错误代码将显示内核执行时是否生成了任何错误


解决方案完全如前一个问题所述:最简单的方法可能是重新设计代码,使其“可重入”因此,您可以将工作分为几个内核启动,每个内核启动都在显示驱动程序看门狗定时器限制下安全进行。

Cuda会以某种方式缓冲全局内存上的所有读/写操作。因此,您可以使用某个内核在某个循环中批处理操作,实际上不需要时间。然后,当您调用
memcpy
,所有缓冲操作都已完成,并且可能会超时。方法是在迭代之间调用
cudaThreadSynchronize
过程


所以请记住:如果内核运行只需要纳秒的计算时间-这并不意味着它是如此之快-一些对全局内存的写入,是在调用
memcpy
threadsynchronize
时完成的。

啊,我认为它至少有点不同,因为我在内核完成exe后立即执行了一个cudagetlasterrorcuting,它说没有错误。在另一个问题中,内核在被看门狗关闭之前实际运行了5秒钟,但这个内核在不到一秒钟内完成。我添加了您建议的代码,没有收到cudaPeekAtLastError的错误,但是CuDatThreadSynchronize超时,并且由于持续了5秒以上而终止econds。这是预期的。例如,如果使用无效的内核参数,cudaPeekAtLastError将返回一个错误。cudaThreadSynchronize将阻止主机,直到内核完成或终止,并给出在cudaPeekAtLastError调用和内核结束之间发生的任何错误。我意识到我读取这些错误的频率有多高从全局内存中读取变量,并决定只读取一次并使用局部变量来存储它要聪明得多。现在的问题是,将最终结果写回全局内存会导致与以前相同的错误。我尝试对两次全局写入进行注释,但完全没有错误。我发现很难相信2次写入全局内存每个线程写一次会消耗我的内核执行时间。这是编译器优化。如果你不写,编译器足够聪明,可以计算出产生写操作的所有代码都是冗余的,并将删除“死”代码。因此,你的内核