const char programSource[] =
"__kernel void vecAdd(__global int *a, __global int *b, __global int *c)"
"{"
" int gid = get_global_id(0);"
"for(int i=0; i<10; i++){"
" a[gid] = b[gid] + c[gid];}"
"}";
Run Code Online (Sandbox Code Playgroud)
上面的内核是每个循环执行十次的向量加法.我已经使用编程指南和堆栈溢出来弄清楚全局内存是如何工作的,但是如果我以一种好的方式访问全局内存,我仍然无法通过查看我的代码来弄清楚.我以连续的方式访问它,我正在以一种统一的方式猜测.该卡是否为阵列a,b和c加载128kb的全局内存块?然后是否为每个处理的32个gid索引加载一次128kb的每个数组块?(4*32 = 128)好像那时我没有浪费任何全局内存带宽吗?
顺便说一句,计算分析器显示gld和gst效率为1.00003,这看起来很奇怪,我认为如果所有的商店和负载都合并,那只会是1.0.它是如何高于1.0的?
来自Nvidia发行说明:
The nvcc compiler switch, --fmad (short name: -fmad), to control the contraction of
floating-point multiplies and add/subtracts into floating-point multiply-add
operations (FMAD, FFMA, or DFMA) has been added:
--fmad=true and --fmad=false enables and disables the contraction respectively.
This switch is supported only when the --gpu-architecture option is set with
compute_20, sm_20, or higher. For other architecture classes, the contraction is
always enabled.
The --use_fast_math option implies --fmad=true, and enables the contraction.
Run Code Online (Sandbox Code Playgroud)
我有两个内核 - 一个是纯粹的计算绑定,有很多乘法,而另一个是内存绑定.当我这样做时,我注意到我的计算密集型内核的性能持续改善(大约5%),-fmad=false并且当我为内存绑定内核关闭时,性能下降相同.所以,FMA对我的内存绑定内核工作得更好,但我的计算绑定内核可以通过关闭它来挤出一点性能.可能是什么原因?我的设备是M2090,我使用的是CUDA 4.2.
完整的编译选项:(
-arch,sm_20,-ftz=true,-prec-div=false,-prec-sqrt=false,-use_fast_math,-fmad=false …
我正在使用Windows 7 64位SP1上的CUDA Toolkit 4.0和Visual Studio 2010 Professional为GTX 580开发CUDA应用程序.我的程序比典型的CUDA程序更耗费内存,我试图为每个CUDA块分配尽可能多的共享内存.但是,每次尝试为每个块使用超过32K的共享内存时,程序都会崩溃.
通过阅读官方CUDA文档,我了解到CUDA设备上每个SM有48KB的片上存储器,其计算能力为2.0或更高,而片上存储器在L1缓存和共享存储器之间分配:
相同的片上存储器用于L1和共享存储器,并且可以为每个内核调用配置多少L1和共享存储器(第F.4.1节) http://developer.download.nvidia.com /compute/DevZone/docs/html/C/doc/Fermi_Tuning_Guide.pdf
这让我怀疑在我的程序运行时只有32KB的单内存被分配为共享内存.因此我的问题是:是否可以将所有48KB的片上内存用作共享内存?
我尝试了我能想到的一切.我为nvcc指定了选项--ptxas-options =" - v -dlcm = cg",我在程序中调用了cudaDeviceSetCacheConfig()和cudaFuncSetCacheConfig(),但没有一个解决了这个问题.我甚至确保没有寄存器溢出,并且我没有意外地使用本地内存:
1> 24 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
1> ptxas info : Used 63 registers, 40000+0 bytes smem, 52 bytes cmem[0], 2540 bytes cmem[2], 8 bytes cmem[14], 72 bytes cmem[16]
Run Code Online (Sandbox Code Playgroud)
虽然我可以使用32KB的共享内存,这已经给了我巨大的性能提升,但我宁愿充分利用所有快速的片上内存.任何帮助深表感谢.
更新:我在程序崩溃时启动了640个线程.512给了我比256更好的性能,所以我试图进一步增加线程数.
我对这个话题发表了各种各样的意见,所以这就是我决定在这里问的原因.我的问题是从CUDA支持的int64_t计算能力开始.我在Quadro770M上运行cuda 5,下面的代码没有问题,但我读到从计算能力1.3开始支持64位无符号.那么这个问题的真正答案是什么?
__device__ void printBinary(int64_t a) {
int bits[64];
int i;
for (i = 0; i < 64; i++) {
bits[63 - i] = (a >> i) & 1;
}
for (int i = 0; i < 64; ++i) {
cuPrintf("%d", bits[i]);
}
cuPrintf("\n");
cuPrintf("%016llX", a);
}
Run Code Online (Sandbox Code Playgroud) 如果我将一个字节从CUDA内核传输到PCI-E到主机(零拷贝存储器),那么与传输200兆字节的东西相比,它有多慢?
我想知道的是,因为我知道通过PCI-E传输CUDA内核的速度很慢,是:如果我只传输一个字节或大量数据,它会改变什么吗?或者也许由于内存传输是在"批量"中执行的,因此传输单个字节非常昂贵且无法传输200 MB?
我使用CUDA 6.5和4 x GPU开普勒.
我使用多线程,CUDA运行时API和从不同CPU线程访问CUDA上下文(通过使用OpenMP - 但它并不重要).
当我打电话cudaDeviceSynchronize();时,它会等待内核只在最新调用选择的当前CUDA上下文中完成cudaSetDevice(),还是在所有CUDA上下文中完成?
如果它将等待内核在所有CUDA上下文中完成,那么它将等待当前CPU线程中使用的所有CUDA上下文(例如CPU thread_0将等待GPU:0和1)或通常所有CUDA上下文(CPU) thread_0会等待GPU:0,1,2和3)?
以下代码:
// For using OpenMP requires to set:
// MSVS option: -Xcompiler "/openmp"
// GCC option: –Xcompiler –fopenmp
#include <omp.h>
int main() {
// execute two threads with different: omp_get_thread_num() = 0 and 1
#pragma omp parallel num_threads(2)
{
int omp_threadId = omp_get_thread_num();
// CPU thread 0
if(omp_threadId == 0) {
cudaSetDevice(0);
kernel_0<<<...>>>(...);
cudaSetDevice(1);
kernel_1<<<...>>>(...);
cudaDeviceSynchronize(); // …Run Code Online (Sandbox Code Playgroud) 为什么我应该使用CUDA驱动程序API,在哪些情况下我不能使用CUDA Runtime API(比Driver API更方便)?
我安装了tensorflow-gpu来在我的GPU上运行我的tensorflow代码.但我不能让它运行.它继续给出上述错误.以下是我的示例代码,后跟错误堆栈跟踪:
import tensorflow as tf
import numpy as np
def check(W,X):
return tf.matmul(W,X)
def main():
W = tf.Variable(tf.truncated_normal([2,3], stddev=0.01))
X = tf.placeholder(tf.float32, [3,2])
check_handle = check(W,X)
with tf.Session() as sess:
tf.initialize_all_variables().run()
num = sess.run(check_handle, feed_dict =
{X:np.reshape(np.arange(6), (3,2))})
print(num)
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
我的GPU是相当不错的GeForce GTX 1080 Ti,拥有11 GB的vram,并且没有其他任何重要的运行(只是chrome),你可以在nvidia-smi中看到:
Fri Aug 4 16:34:49 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 381.22 Driver Version: 381.22 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage …Run Code Online (Sandbox Code Playgroud) 我正在尝试开始使用一些OpenCL编码.
我已经在我的计算机上安装了NVidia CUDA OpenCL,并设法构建了一个简单的"Hello World!" 使用Visual Studio 2017的应用程序.
我还安装了英特尔OpenCL SDK(安装警告我,我需要更新我的OpenCL驱动程序,但英特尔更新管理器告诉我一切都是最新的,所以我不确定这是否是一个问题).
现在每当我在PC上查询OpenCL平台时,都是如此:
std::vector< cl::Platform > platformList;
cl::Platform::get(&platformList);
Run Code Online (Sandbox Code Playgroud)
我只回到我的nVidia openCL平台,我的GPU是唯一的设备.我的CPU没有得到任何回报.
有人可以帮忙吗?是否可以在同一个项目中执行CPU和GPU OpenCL计算(在不同的OpenCL上下文中?我将如何进行此操作?
我有一台配置了NVIDIA GeForce1080 GTX和CentOS 7作为操作系统的Intel Xeon机器。我已经安装了NVIDIA驱动程序410.93和cuda-toolkit 10.0。编译cuda-samples之后,我尝试运行./deviceQuery。但是这样扔
./deviceQuery Starting...
CUDA Device Query (Runtime API) version (CUDART static linking)
cudaGetDeviceCount returned 30
-> unknown error
Result = FAIL
Run Code Online (Sandbox Code Playgroud)
一些命令输出
lspci | grep VGA
01:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1080] (rev a1)
Run Code Online (Sandbox Code Playgroud)
英伟达
Wed Feb 13 16:08:07 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.93 Driver Version: 410.93 CUDA Version: 10.0 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util …Run Code Online (Sandbox Code Playgroud)