您是如何测试你的性能?
你是如何复制您的数组? 复制整个数组往往比复制子数组要快很多.因为一个完整的数组可以在一个连续的block里复制,而子数组必须在很多小的chunks里被复制。考虑到数组移动耗费很多,我发现减少数据的复制次数比复制数据的大小要重要得多.对于子数组,最好在复制以前将数组集中在一个单一的块里. 你可以参考这篇文章.
Multi-GPU Programming Using CUDA Fortran, MPI, and GPUDirect
如果你使用数组语法(即Arr_host=Arr_device)来复制整个数组,要在你的host数组上增加"pinned"属性,这是必须的,但不能保证操作系统把数组放在非交换物理内存,即pinned,为了执行一个DMA传输(即将数据复制到GPU上),内存必须是被pinned.因此没有pinned属性,内存会首先从虚拟内存复制到物理内存,然后在传输到GPU上.Pinned属性可以避免这种额外的复制.使用pinned需要注意的是,这个数据是由CUDA设备驱动管理,因为,如果你破坏了你的CUDA context,那么内存也会被消毁.
如果这个办法不能对你有帮助,那你就卡住了.你只能找别的办法减少复制的次数,或者增加GPU的计算量.
另外一件事情,就是检查你的GPU是否按照预期执行.我见过例子就是GPU卡插错了PCI槽,只获得1/4内存性能.你可以运行"pgaccelinfo"来检查一下带宽测试,为了便于比较,我把我的C2070上输出的结果展示出来:
% pgaccelinfo
CUDA Driver Version: 4010
NVRM version: NVIDIA UNIX x86_64 Kernel Module 285.05.33 Thu Jan 19 14:07:02 PST 2012
Device Number: 0
Device Name: Tesla C2070
Device Revision Number: 2.0
Global Memory Size: 6441598976
Number of Multiprocessors: 14
Number of Cores: 448
Concurrent Copy and Execution: Yes
Total Constant Memory: 65536
Total Shared Memory per Block: 49152
Registers per Block: 32768
Warp Size: 32
Maximum Threads per Block: 1024
Maximum Block Dimensions: 1024, 1024, 64
Maximum Grid Dimensions: 65535 x 65535 x 65535
Maximum Memory Pitch: 2147483647B
Texture Alignment: 512B
Clock Rate: 1147 MHz
Execution Timeout: No
Integrated Device: No
Can Map Host Memory: Yes
Compute Mode: default
Concurrent Kernels: Yes
ECC Enabled: No
Memory Clock Rate: 1494 MHz
Memory Bus Width: 384 bits
L2 Cache Size: 786432 bytes
Max Threads Per SMP: 1536
Async Engines: 2
Unified Addressing: Yes
Initialization time: 31185 microseconds
Current free memory: 5934874624
Upload time (4MB): 958 microseconds ( 711 ms pinned)
Download time: 1040 microseconds ( 672 ms pinned)
Upload bandwidth: 4378 MB/sec (5899 MB/sec pinned)
Download bandwidth: 4032 MB/sec (6241 MB/sec pinned)
我有两个我问题:
1. 我如何运行accelinfo??我要在cmd里运行什么特别的命令吗?
2. 我怎么检查内存带宽的最佳值?我是新手.
我目前是用NVIDIA GeForce 460卡,没有Tesla卡.我希望我的卡能用.根据你的问题,复制需要化多少时间?我已经开发了下面的代码,请看一下,或许你比较容易看懂我要做什么,
我用一个函数(CALL DATE AND TIME) 去计算运行时间来看在GPU上花费多长时间运行乘法,结果是1微秒,同样的任务在CPU上是80微秒.对我来说是很大的性能提升,但是当我努力从GPU上复制到CPU上时,我就卡住了,花费了227微秒! 这是3倍于CPU做乘法.但我没有使用pinned属性,我接下来会改这个程序.
这是我的代码:
module variables
implicit none
integer :: N = 500
integer :: M = 400
integer :: L = 500
real :: sum = 0.0
end module variables
module mmul_mod
use cudafor
use variables
contains
attributes (global) subroutine mmul_kernel (A,B,C, N,M,L)
integer , value :: N,M,L
real :: A(N,M) , B(M,L) , C(N,L)
real :: sum
integer :: k
blkidx = blockidx%x
blkidy = blockidx%y
sum = 0.0
do k =1, M
sum = sum + (A(blkidx,k) * B(k,blkidy))
enddo
C(blkidx,blkidy) = sum
sum = 0.0
end subroutine mmul_kernel
end module mmul_mod
!=============================
program mat_mult
!=============================
use variables
use mmul_mod
implicit none
integer i,j,k
real, dimension (N,M) :: A
real, dimension (M,L) :: B
real, dimension (N,L) :: C
real, device, allocatable, dimension (:,:) :: Adev, Bdev, Cdev
integer :: start_time(8), end_time(8)
CHARACTER (LEN = 12) REAL_CLOCK (3)
type(dim3) :: blocks
allocate (Adev(N,M), Bdev(M,L), Cdev(N,L))
CALL DATE_AND_TIME (REAL_CLOCK (1), REAL_CLOCK (2), REAL_CLOCK (3), start_time)
Adev = A(1:N,1:M)
Bdev (:,:) = B(1:M,1:L)
blocks = dim3(N, L, 1)
call mmul_kernel <<
>> (Adev, Bdev, Cdev, N,M,L)
CALL DATE_AND_TIME (REAL_CLOCK (1), REAL_CLOCK (2),REAL_CLOCK (3), end_time)
C(1:N,1:L) = Cdev
deallocate (Adev, Bdev, Cdev)
end program mat_mult
对于你的第一个问题,你可以在command line shell里运行pgaccellinfo, 你用PVF吗?如果用的话,你可以在"Start"菜单里打开一个PGI DOS command shell
对于你的第二个问题,我不能确认,产品规格页面里虽然列出的显存带宽,但是是on-chip带宽,不是CPU到GPU,我怀疑这将取决于很多因素,除了卡本身。
针对你的代码,首先你的计时代码是不对的,主机代码异步启动内核.因此,在调用后,主机持续直到到达一个异步点,在这个项目里,就是C数组的数据传输,因此,在这里,你计算的是数据传输到GPU的时间加上调用内核花费的一点开销.要解决,你要么在内核调用后增加一个调用"cudaThreadSynchronize",或更好,使用CUDA events去计算代码时间.
Tuning a Monte Carlo Algorithm on GPUs
, 在这里有一个如何使用CUDA Events的实例.
你的意思,只使用一个块?这会给你非常差的性能。所以我怀疑,这里的问题不是数据的复制,而是你如何安排你的内核。
改造成kernel时,参数很多,怎么办?
作者
master
(
CUDA
)
Re: cuda-gdb 显示的错误信息
作者
屠戮人神
(
CUDA
)
Re: cuda-gdb 显示的错误信息
作者
屠戮人神
(
CUDA
)
Re: 多个线程进行判断修改同一个全局内存遇到的问题
作者
屠戮人神
(
CUDA
)
Re: 多个线程进行判断修改同一个全局内存遇到的问题
作者
屠戮人神
(
CUDA
)
《如何用NVIDIA Nsight调试GPU程序》在线培训
53324 views 25 replies
运行我的程序时,英伟达板卡Jetson TX2比Jetson Tx1速度更慢可能是什么原因??求解答
52621 views 4 replies
float类型数据计算问题
39238 views 11 replies
怎么让线程互斥修改常量存储的值
36922 views 6 replies
【转载】我在深度学习上用GPU的经验
35021 views 3 replies
NVIDIA TensorRT推理服务器支持深度学习推理
34754 views 2 replies