Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/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
Pascal CUDA8 1080Ti统一内存的速度_Cuda_Openacc - Fatal编程技术网

Pascal CUDA8 1080Ti统一内存的速度

Pascal CUDA8 1080Ti统一内存的速度,cuda,openacc,Cuda,Openacc,多亏了昨天的答案,我想我现在已经使用Pascal 1080Ti对统一内存进行了正确的基本测试。它分配一个50GB的一维数组并将其相加。如果我理解正确,它应该是内存限制的,因为这个测试非常简单(添加整数)。但是,它需要24秒,相当于大约2GB/s。当我运行CUDA8带宽测试时,我看到更高的速率:11.7GB/s固定和8.5GB/s可分页 有没有办法让测试运行速度超过24秒 以下是完整的测试代码: $ cat firstAcc.c #include <stdio.h> #includ

多亏了昨天的答案,我想我现在已经使用Pascal 1080Ti对统一内存进行了正确的基本测试。它分配一个50GB的一维数组并将其相加。如果我理解正确,它应该是内存限制的,因为这个测试非常简单(添加整数)。但是,它需要24秒,相当于大约2GB/s。当我运行CUDA8带宽测试时,我看到更高的速率:11.7GB/s固定和8.5GB/s可分页

有没有办法让测试运行速度超过24秒

以下是完整的测试代码:

$ cat firstAcc.c 

#include <stdio.h>
#include <openacc.h>
#include <stdlib.h>
#include <time.h>

#define GB 50

static double wallclock()
{
  double ans = 0;
  struct timespec tp;
  if (0==clock_gettime(CLOCK_REALTIME, &tp))
      ans = (double) tp.tv_sec + 1e-9 * (double) tp.tv_nsec;
  return ans;
}

int main()
{
  int *a;

  size_t n = (size_t)GB*1024*1024*1024/sizeof(int);
  size_t s = n * sizeof(int);
  printf("n = %lu, GB = %.3f\n", n, (double)s/(1024*1024*1024));
  a = (int *)malloc(s);
  if (!a) { printf("Failed to malloc.\n"); return 1; }

  setbuf(stdout, NULL);
  double t0 = wallclock();
  printf("Initializing ... ");
  for (long i = 0; i < n; ++i) {
    a[i] = i%7-3;
  }
  double t1 = wallclock();
  printf("done in %f (single CPU thread)\n", t1-t0);
  t0=t1;

  int sum=0.0;
  #pragma acc parallel loop reduction (+:sum)
  for (long i = 0; i < n; ++i) {
    sum+=a[i];
  }
  t1 = wallclock();
  printf("Sum is %d and it took %f\n", sum, t1-t0);
  free(a);
  return 0;
}
然后我运行了两次:

$ ./a.out
n = 13421772800, GB = 50.000
Initializing ... done in 36.082607 (single CPU thread)
Sum is -5 and it took 23.902612
$ ./a.out
n = 13421772800, GB = 50.000
Initializing ... done in 36.001578 (single CPU thread)
Sum is -5 and it took 24.180615
结果(-5)是正确的,因为我是这样设置数据的。这些数字是由7个整数组成的重复序列-3:+3,当求和时,除结尾处的2的余数(-3-2=-5)外,其余的都会被抵消

pageable的带宽测试(CUDA 8个样本/1_实用程序)结果为:

$ ./bandwidthTest --memory=pageable
[CUDA Bandwidth Test] - Starting...
Running on...

 Device 0: GeForce GTX 1080 Ti
 Quick Mode

 Host to Device Bandwidth, 1 Device(s)
 PAGEABLE Memory Transfers
   Transfer Size (Bytes)        Bandwidth(MB/s)
   33554432                     8576.7

 Device to Host Bandwidth, 1 Device(s)
 PAGEABLE Memory Transfers
   Transfer Size (Bytes)        Bandwidth(MB/s)
   33554432                     11474.3

 Device to Device Bandwidth, 1 Device(s)
 PAGEABLE Memory Transfers
   Transfer Size (Bytes)        Bandwidth(MB/s)
   33554432                     345412.1

Result = PASS

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
我看到那张纸条了。但是我应该用什么来代替呢?这些测量值似乎在正确的范围内吗

有没有什么方法可以让测试运行在6秒(50GB/8.5GB/s)而不是25秒的时间内

使用--mode=shmoo的结果实际上显示pageable达到了更高的速率:11GB/s

$ ./bandwidthTest --memory=pageable --mode=shmoo
[CUDA Bandwidth Test] - Starting...
Running on...

 Device 0: GeForce GTX 1080 Ti
 Shmoo Mode

.................................................................................
 Host to Device Bandwidth, 1 Device(s)
 PAGEABLE Memory Transfers
   Transfer Size (Bytes)        Bandwidth(MB/s)
   1024                         160.3
   2048                         302.1
   3072                         439.2
   4096                         538.4
   5120                         604.6
   6144                         765.3
   7168                         875.0
   8192                         979.2
   9216                         1187.3
   10240                        1270.6
   11264                        1335.0
   12288                        1449.3
   13312                        1579.6
   14336                        1622.2
   15360                        1836.0
   16384                        1995.0
   17408                        2133.0
   18432                        2189.8
   19456                        2289.2
   20480                        2369.7
   22528                        2525.8
   24576                        2625.8
   26624                        2766.0
   28672                        2614.4
   30720                        2895.8
   32768                        3050.5
   34816                        3151.1
   36864                        3263.8
   38912                        3339.2
   40960                        3395.6
   43008                        3488.4
   45056                        3557.0
   47104                        3642.1
   49152                        3658.5
   51200                        3736.9
   61440                        4040.4
   71680                        4076.9
   81920                        4310.3
   92160                        4522.6
   102400                       4668.5
   204800                       5461.5
   307200                       5820.7
   409600                       6003.3
   512000                       6153.8
   614400                       6232.5
   716800                       6285.9
   819200                       6368.9
   921600                       6409.3
   1024000                      6442.5
   1126400                      6572.3
   2174976                      8239.3
   3223552                      9041.6
   4272128                      9524.2
   5320704                      9824.5
   6369280                      10065.2
   7417856                      10221.2
   8466432                      10355.7
   9515008                      10452.8
   10563584                     10553.9
   11612160                     10613.1
   12660736                     10680.3
   13709312                     10728.1
   14757888                     10763.8
   15806464                     10804.4
   16855040                     10838.1
   18952192                     10820.9
   21049344                     10949.4
   23146496                     10990.7
   25243648                     11021.6
   27340800                     11028.8
   29437952                     11083.2
   31535104                     11098.9
   33632256                     10993.3
   37826560                     10616.5
   42020864                     10375.5
   46215168                     10186.1
   50409472                     10085.4
   54603776                     10013.9
   58798080                     10004.8
   62992384                     9998.6
   67186688                     10006.4
提前谢谢

$ pgcc -V
pgcc 17.4-0 64-bit target on x86-64 Linux -tp haswell 
PGI Compilers and Tools
Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.

$ cat /usr/local/cuda-8.0/version.txt 
CUDA Version 8.0.61

在2013年11月的这篇博文中:NVIDIA写道

重要的一点是,一个经过仔细调整的CUDA程序,它使用流和cudaMemcpyAsync有效地将执行与数据传输重叠可能比只使用统一内存的CUDA程序性能更好。这是可以理解的:CUDA运行时从来没有程序员那么多关于何时何地需要数据的信息!CUDA程序员仍然可以访问显式设备内存分配和异步内存拷贝,以优化数据管理和CPU-GPU并发性。统一内存首先是一个生产力特性,它为并行计算提供了一个更平滑的入口,而不会剥夺CUDA为高级用户提供的任何特性

2014年3月:

CUDA 6引入了统一内存,大大简化了GPU计算的内存管理。现在,在将代码移植到GPU时,您可以专注于编写并行内核,内存管理成为一种优化。

现在,在CUDA8中,对统一内存机制进行了一些改进。他们特别说:

重要的一点是,CUDA程序员仍然拥有在必要时显式优化数据管理和CPU-GPU并发性所需的工具:CUDA 8引入了有用的API,用于向运行时提供内存使用提示(cudaMemAdvise())和显式预取(cudameprefetchasync())。这些工具允许使用与显式内存复制和固定API相同的功能,而无需恢复到显式GPU内存分配的限制

因此,似乎可以使用
cudaMemAdvise()
/
cudaMemPrefetch()
加快示例的速度。然而,即使这样,显式内存管理仍可能具有性能优势

由OP添加:

通过数据局部性提高性能 通过在CPU和GPU之间按需迁移数据,统一内存可以提供GPU上本地数据的性能,同时提供全局共享数据的易用性。CUDA驱动程序和运行时掩盖了此功能的复杂性,确保应用程序代码更易于编写。迁移的重点是实现每个处理器的全带宽;750 GB/s的HBM2内存带宽对于提高GP100 GPU的计算吞吐量至关重要。使用GP100上的页面错误,即使对于具有稀疏数据访问的程序,也可以确保局部性,其中CPU或GPU访问的页面无法提前知道,并且CPU和GPU同时访问相同阵列分配的部分

Pascal还改进了对统一内存的支持,这得益于更大的虚拟地址空间和新的页面迁移引擎,实现了更高的性能、GPU内存的超额订阅、和系统范围的原子内存操作


页面错误处理过程显然比数据的纯拷贝更复杂。因此,当您通过页面错误将数据驱动到GPU时,它无法在性能方面与数据的纯拷贝竞争

页面错误本质上是GPU要处理的另一种延迟。GPU是一个延迟隐藏机器,但它需要程序员给它隐藏延迟的机会。这可以粗略地描述为公开足够多的并行工作

表面上看,您似乎已经暴露了大量并行工作(数据集中约有12B个元素)。但是检索到的每个字节或元素的工作强度非常小,因此GPU在这里隐藏与页面错误相关的延迟的机会仍然有限。换句话说,GPU具有基于该GPU上可运行的最大线程数(上限:2048*#的SMs)和每个线程中公开的工作执行延迟隐藏的瞬时能力。不幸的是,在您的示例中,每个线程中公开的工作可能非常小——基本上是一次添加

帮助隐藏GPU延迟的方法之一是增加每个线程的工作,有多种技术可以做到这一点。一个好的起点是选择一个计算复杂度高的算法(如果可能的话)。矩阵乘法是每个数据元素计算复杂度高的经典例子

在这种情况下,一些建议是认识到您正在尝试做的事情是非常有序的,因此从编程的角度来看,通过将工作分解为多个部分并自己管理数据传输,并不难管理。这将允许您实现数据传输操作链路的全部带宽,实现大约
$ pgcc -V
pgcc 17.4-0 64-bit target on x86-64 Linux -tp haswell 
PGI Compilers and Tools
Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.

$ cat /usr/local/cuda-8.0/version.txt 
CUDA Version 8.0.61