我已经编写了一个CUDA代码来解决NP完全问题,但是性能并不像我想象的那样好
我知道一些使用共享内存、纹理、zerocopy的优化技术
CUDA程序员应该了解哪些最重要的优化技术?您应该阅读NVIDIA的CUDA编程最佳实践指南:
这有多个不同的性能提示和相关的优先级。以下是一些最重要的提示:
使用设备的有效带宽来计算内核的性能上限
尽可能减少主机和设备之间的内存传输—即使这意味着在设备上进行效率不高的计算
合并所有内存访问
更喜欢共享内存访问而不是全局内存访问
避免在单个扭曲内执行代码分支,因
在CUDA中是否可以创建最大数量的流
澄清一下,我指的是CUDA流,即允许您执行内核和内存操作的流。我在任何文档中都没有看到限制,但这并不意味着所有流都将同时执行,因为这是一个硬硬件限制(多处理器、寄存器等)。根据NVIDIA的介绍,最大值为16个流(在费米上)。
澄清一下,我已经成功创建了超过16个流,但我认为硬件只能支持16个并发内核,因此多余的内核在并发性方面是浪费的
开普勒可能不同。您可以创建的流的数量没有实际限制(至少1000个)。但是,可以有效使用的流的数量是有限制的,以实现并发性
不幸的是,基于费米(fermi)的GPU会将任何内核定时跟踪为并行Nsight序列化,即使它们是不同流中的并发内核
有人能建议如何使用计时器手动显示不同流中内核的并发性吗
干杯
Ed使用Nsight评测当前确实禁用了并发内核,因此要获得准确的计时,您需要使用事件来跟踪计时
您可以按预期使用事件,也可以使用cudaStreamWaitEvent()使流等待另一个流中的事件。有关更多信息,请参阅第4.5.2.5节。评测现在不再禁用并发内核执行。
标签: Cuda
resourcesassertioncuda-context
让我们想象一下这种情况,我有很多初始化的资源,例如:流、主机和设备内存结束事件,其中一部分在一个GPU的上下文中初始化,其余的属于另一个GPU上下文
有没有办法检查给定的资源(事件、流或内存)是否属于特定的GPU上下文
在某些情况下,在命令内存拷贝或内核执行之前,有必要断言这些东西,然后获取cudaErrorInvalidArgument 我真的不知道CUDA API本身有这样的选项。它只是一个低级的命令集,你可以发布到你的GPU
我要做的是将CUDAAPI函数封装到一个好的类中,该类将跟踪初始
标签: Cuda
memory-optimization
我用cuda编写了一个应用程序,它在每个块中使用1kb的共享内存。
由于每个SM中只有16kb的共享内存,所以总体上只能容纳16个块(我理解正确吗?),虽然一次只能调度8个,但现在如果某个块忙于内存操作,那么其他块将在gpu上调度,但是所有共享内存都被其他16个已经在那里调度的块使用,因此cuda不会在同一个sm上调度更多的块,除非之前分配的块完全完成?或者,它会将某些块的共享内存移动到全局内存,并在那里分配其他块(在这种情况下,我们应该担心全局内存访问延迟吗?它不是这样工作的。计划在任何给定时
标签: Cuda
sizeunits-of-measurement
谁能告诉我NVIDIA cuda的注册单位是什么?当我每个块有8192个寄存器时,这意味着是字节还是位?每个寄存器都是32位寄存器,即每个寄存器有4个字节。这在较新的计算能力中仍然有效吗?@AnixPasBesoin Yes。
我做了一些测试带宽的内核,它们没有做任何有用的计算。一个最小的例子是
__global__ void testKernel(float* a)
{
unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
float x;
x = a[i];
}
当我编译时,我得到(毫不奇怪)
警告:已设置变量“x”,但从未使用过
内核运行速度与空内核一样快:
__global__ void donothing()
{
}
这表明
请帮助我为什么下面不工作。在我的comp中,当我试图打印var的值时,它只打印0
#include<stdio.h>
__constant__ float pivot;
__global__ void kernel(float *set){
*set = pivot;
}
void main(){
float c[] = {1,3,4};
cudaError_t err = cudaMemcpyToSymbol(pivot,&c[2],
标签: Cuda
texturestexture-packing
我在设备全局内存中有一个可以访问的大字符数组
通过螺纹以结合的方式。我在某个地方读到过可以加快速度的文章
通过在每个线程的一个内存事务中读取4或16个字符来访问内存。
我相信我必须使用纹理和char4或int4结构。然而,
我找不到这方面的任何文档或示例。这里有人吗
提供一个简单的例子或指针,我可以在哪里了解更多有关这方面的信息
在我的代码中,我将char数组定义为
char *database = NULL;
cudaMalloc( (void**) &database, SIZE *
我正在使用动态语言(Clojure)使用JCuda以交互开发方式创建CUDA上下文。我通常会调用包含对jcuda.driver.JCudaDriver/cuInit的调用的初始值设定项。多次给cuInit打电话安全吗?此外,是否有类似于cuInit的销毁方法?我这样问是因为可能会返回错误代码CUDA\u error\u DEINITIALIZED。要回答这个问题,可以多次调用cuInit。我没有注意到这样做的任何副作用
但是,请注意,cuInit仅在API内部触发一次性初始化过程。它对设备或上下
我的问题和题目一样。实际上,我正在寻找一种异步释放设备内存的方法
谢谢 cudaFree()不是异步的。从主机调用cudaFree()时,将在内部调用同步调用
我不明白异步释放内存的实际需要。cudaFree()是同步的。如果您真的希望它是异步的,您可以创建自己的CPU线程,给它一个工作队列,并注册来自主线程的cudaFree请求
也就是说,异步释放似乎是一个奇怪的请求。也许您可以解释为什么希望它是异步的。您想在CUDA事件触发后立即释放吗?想象一系列相关内核启动,其中一些需要临时分配。如果主机
我正在分析一个内核,它在GTX480中每个线程使用25个寄存器,每个块使用3568字节的共享内存。内核配置为启动16x16个线程,线程缓存首选项设置为共享
根据GTX480的规范,该设备每个SM有32768个寄存器,因此可能会有25个regs x 256个线程/块x 6个块/SM块同时运行
但是,Compute Visual Profiler和Cuda占用率计算器报告,每个SM只有4个区块处于活动状态。我想知道为什么只有4个街区是活动的,而不是像我预期的5个街区
我发现的原因是CUDA将使用的寄
我正在通过C代码在CUDA(费米GPU)中进行数据预取。Cuda参考手册讨论的是ptx级代码而不是C级代码的预取
有人可以通过cuda代码(cu文件)向我提供一些关于预取的文档或信息吗。任何帮助都将不胜感激。以下是PTX中预取的工作原理:
您可以将PTX指令嵌入CUDA内核。以下是一个小样本:
您可以通过C中的以下预取功能得出结论:
__device__ void prefetch_l1 (unsigned int addr)
{
asm(" prefetch.global.L1 [ %
我需要大量的常量数据,超过6-8KB,最多16KB。同时,我不使用共享内存。现在我想把这些常量数据存储在共享内存中。这是个好主意吗?有性能近似值吗?广播对共享内存和恒定内存都有效吗
性能对于应用程序至关重要。我想,我的特斯拉C2075(CUDA 2.0)上只有8KB的恒定内存缓存。在compute capability 2.0中,同样的内存用于L1和共享内存。L1和共享内存之间的分区可以通过调用cudaFuncSetCacheConfig()来控制。我建议将L1设置为最大可能值(48K)
然后,
电话:
cudaExtent extent = make_cudaExtent( 1920 * sizeof(float), 1080, 10);
chanDesc = cudaCreateChannelDesc ( 32, 0, 0, 0, cudaChannelFormatKindFloat);
err = cudaMalloc3DArray ( &(devYAll[0]), &chanDesc, extent, 0);
使用err=cudaErrorInvalidVa
我试图在_全局_函数中使用数学函数(pow),但出现以下错误:
calling a __host__ function("std::pow<float, double> ") from a __global__ function is not allowed
不允许从全局函数调用主机函数(“std::pow”)
我试着选中项目属性->构建->设置->工具设置->优化和无运气下的“利用快速数学库”复选框
我检查了pow函数中的类型,这两种类型都是float,我还包括了以下头文件:
有什么方法可以让我知道免费/活动短信的数量吗?或者至少读取每个SM的电压/功率或温度值,通过这些值我可以知道其是否工作?(在gpu设备上执行某些作业时实时执行)
%smid帮助我了解每个SM的Id。类似的东西会有帮助
感谢和问候,
RakeshCUDA评测工具接口()包含一个事件API,该API支持GPU PM计数器的运行时采样。CUPTI SDK作为CUDA工具包的一部分提供。有关采样的文档可在CUPTI事件API\一节中找到
以下一个或多个计数器将为您提供有关SM活动的详细信息:
活动\u
是否可以访问GigaThread全局调度程序的代码
我的目的是了解调度器在给定时刻使用了多少条SMs(假设GigaThread global scheduler是负责决定特定应用程序需要使用多少条SMs和哪些SMs的调度器)。那么,有没有什么方法可以让调度器维护一个日志,并在每次为应用程序使用一组新的SMs时更新它,其中包含SMs的数量或SMs的ID
这将帮助我查看日志文件,以便在需要信息时检查计划程序最近使用了多少条SMs。目前没有公开的方法来跟踪计算工作分发服务器
可以使用%smid和%cl
我想从主机设置一个指向符号地址的符号指针。比如:
__device__ float * symbolPtr; // address of symbol[3]
__device__ float symbol[5];
cudaGetSymbolAddress( &symbolPtr, symbol[3] );
我只是用它来获取主机的设备地址。但是没有提到它不能设置符号变量
以下是另一种方法:
cudaMemcpytoSymbol(&symbolPtr, &symbol
我试图编译一个基本的CUDA矩阵乘法程序,但遇到了以下错误:
nvcc -I. -I/usr/local/cuda/include -c matrixMult1.cu -o matrixMult1.o
make: nvcc: Command not found
make: *** [matrixMult1.o] Error 127
nvcc: Command not found
我最初遇到了另一个错误,建议我使用nvcc,唯一的问题是我对nvcc一无所知。有人有主意吗?提前谢谢
生成文
我想在CUDA代码中指定我是使用CUDA生成规则版本4.2还是CUDA生成规则版本5进行编译
是否有用于此目的的宏
注意:我知道有一个选项可以指定当前的编译过程是否支持特定的体系结构,例如\uuuuuu CUDA\u ARCH\uuuu
我正在为CUDA构建规则版本寻找类似的宏。用于确定CUDA工具包版本的宏是CUDART\u版本
您可以根据CUDA Toolkit版本对代码进行条件编译,如下所示:
#if CUDART_VERSION == 5000
//Compilation is bei
标签: Cuda
atomicgpu-atomicsptxas
我想在CUDA中实现这个原子函数:
__device__ float lowest; // global var
__device__ int lowIdx; // global var
float realNum; // thread reg var
int index; // thread reg var
if(realNum < lowest) {
lowest= realNum; // the new lowest
lowIdx= index;
我有一段串行代码,它是这样做的
if( ! variable )
{
do some initialization here
variable = true;
}
我知道这在序列中工作得很好,只会执行一次。在CUDA中,什么原子操作才是正确的操作?在我看来,您想要的是代码中的“关键部分”。临界段允许一个线程执行一系列指令,同时阻止任何其他线程或线程块执行这些指令
例如,可以使用临界段来控制对内存区域的访问,以便允许单个线程对该区域进行无冲突的访问
原子本身只能用于一个非常有限的、基本
我是cuda的新手。我正在用cuda编写图像处理代码。
我的c和cuda代码如下,我试图转换成cuda,但效果不好
我的C代码:
void imageProcess_usingPoints(int point, unsigned short *img)
{
// doing image process here using point variable value.
}
int main(int argc, char **argv)
{
/* here i define and in
我正在尝试解决CUDA运行时错误。cuda gdb报告的调试信息(cuda memcheck打开时):
我已经检查了块、网格尺寸和正在使用的动态共享内存的大小,它们远远低于限制。请告诉我(0xb)错误类型代表什么,我在cuda文档中没有找到它。另外,请告诉我如何解决这个问题的建议?
设备:开普勒K20(CC=3.5)和CUDA 5.5
代码太大,无法粘贴到此处。如果您在代码中执行此操作,您可以检索从cudaGetLastError调用报告的0xb错误,并将其传递给解码器(cudagetrorst
如果我使用此代码,那么它将在设备0或1上执行吗
cudaSetDevice(0); // switch to device 0
cudaStream_t stream1;
cudaStreamCreate(&stream1); // created on device 0
cudaSetDevice(1); // switch to device 1
kernel_function<<<10, 1024, 0, stream1>>&g
我在程序中使用共享内存,问题是当我更改线程和块的数量时,结果也在更改。我可能会对某些配置使用正确的结果,但对另一个配置使用错误的结果
我正在尝试处理一个80x64=5120图像。这就是为什么我要创建:
const int NUM_THREADS = 16;
dim3 dimGrid( ColsNum / NUM_THREADS , RowsNum / NUM_THREADS );
dim3 dimBlock( NUM_THREADS ,NUM_THREADS );
因此,取4x5=20个块
我在一本书中读到,在波前或扭曲中,所有线程共享一个公共程序计数器。那么它的后果是什么呢?这有什么关系 这意味着所有线程同时运行相同的命令。这对于确保所有线程在处理当前行时都已完成前一行非常重要。例如,如果需要将数据从一个线程传递到另一个线程,则需要确保数据已经由第一个线程写入。因为程序计数器是共享的,所以您知道,一旦写入数据行完成,数据就存在于所有线程中。NVIDIA GPU一次执行32个线程(扭曲),AMD GPU一次执行64个线程(波前)。控制逻辑、提取和数据路径的共享减少了面积,提高了性能
我只是在学习CUDA/OpenCL,但我有一个概念上的问题。假设我正在编码一个算法,对一个图进行广度优先搜索。假设我的目标设备是一个GPU,只有2个工作组,2个处理单元(即4个核)。直观地说,我猜搜索可以通过保留一个“要访问的节点”数组并行完成。对于每个过程,并行访问每个节点,并将其添加到下一个“要访问的节点”数组中。例如,可以生成以下搜索:
start: must visit A
parallel pass 1: must visit B, C, D
parallel pass 2: must
我们一直在努力使以下代码正常工作
__global__ void kernel(){
if (threadIdx.x == 1){
while(var == 0){
}
}
if (threadIdx.x == 0){
var = 1;
}
}
其中var是一个全局设备变量。我只是简单的启动
使用kernel()在同一块中的两个线程
如果我切换ifs的顺序,代码将终止。然而,
如果我不切换i
我在《大规模并行处理器编程》(第二版)中读到
在CUDA 3.0及更高版本中,每个线程块最多可以有1024个线程。一些早期的CUDA版本在一个块中最多只允许512个线程
我最近下载了CUDA 7.0工具包,想知道上述信息是否与nowday版本相关
问题似乎也有过时的信息(该书在2012年出版时已经过时)CUDA 7仅支持计算能力为2.0及更高版本的CUDA设备。所有此类设备每个块最多可支持1024个线程
512数字属于计算能力为1.x的设备,CUDA 7不再支持此类设备
请注意,计算能力和CUD
我试图了解GPU的基本架构。我看过很多资料,包括这个。但我仍然感到困惑,无法很好地了解它
我的理解:
GPU包含两个或多个流式多处理器(SM),具体取决于计算能力值
每个SM都由流处理器(SP)组成,SP实际上负责指令的执行
SP以翘曲(32条螺纹)的形式处理每个块
每个块都可以访问共享内存。其他块无法访问其他块的共享内存的数据
混乱:
在下图中,我无法理解哪个是流式多处理器(SM),哪个是SP。我认为多处理器-1代表单个SM,处理器-1(高达M)代表单个SP。但我不确定这一点,因为我可以看
标签: Cuda
dynamic-memory-allocation
如果从CUDA 4.2中的\uuuuu设备\uuuuuuuu或\uuuuuu全局\uuuuuuuu代码调用,是否有人能清楚地解释new和delete关键字的行为
如果内存在设备上是本地的还是全局的,那么在哪里分配内存
就问题的背景而言,我试图在GPU上创建神经网络,我想要一个链接表示(就像一个链接列表,但每个神经元都存储一个包含权重的连接链接列表,以及指向其他神经元的指针),我知道我可以在内核启动之前使用cudamaloc进行分配,但我希望内核能够控制创建网络的方式和时间
谢谢 C++new和d
我的cuda程序在VisualStudio2013上运行得很好,但每次我尝试时,它都无法生成时间线对话,我至少等待了35分钟?
尽管我能够根据需要在其他cuda项目中获得结果 我调用的内核中没有结束循环。这个问题怎么了?为什么每个人都在贬低它?我已经添加了cudaDeviceReset!!根据你提供的信息,你认为其他人会如何回答这个问题?
我编写了以下代码以了解如何为1D数组使用纹理内存。但是tex1D函数没有从数组中获取对应线程id的值。请更正此代码,并告诉我如何高效地为1D数组使用纹理内存
__global__ void sum(float *b,cudaTextureObject_t texObj)
{
b[threadIdx.x]=tex1D<float>(texObj,threadIdx.x);
//printf("\n%f\n",tex1Dfetch<float>(te
CUDA允许使用cuMemcpy异步函数和流重叠计算和数据传输。但NPP(性能原件)是否可行
有点背景。我试图利用GPU使用NPP图像大小调整功能(在我们的例子中是nppiResize_8u_C3R)。我正在使用固定内存,并使用cuMemcpy2DAsync_v2和每线程流成功地将数据传输到GPU。问题是nppiResize_8u_C3R和所有其他计算函数不接受流
当我运行Nvidia Visual Profiler时,我会看到下一个:
固定内存使我能够更快地传输数据—约6.524 GB/s
m
我在使用CUDA 5的Linux上使用计算能力为35的特斯拉k20。通过一个简单的子内核调用,它会给出一个编译错误:未解析的外部函数cudaLaunchDevice
我的命令行如下所示:
nvcc --compile -G -O0 -g -gencode arch=compute_35 , code=sm_35 -x cu -o fill.cu fill.o
我在lib64中看到了cudadevrt.a。。我们是否需要添加它,或者可以做些什么来解决它?没有子内核调用,一切正常。您必须在启用可重
标签: Cuda
nvidiagpgputhrustreduction
我正在寻找一种快速的方法来减少多个相同长度的块
它们被排列成一个大的向量。
我有N个子数组(连续元素),它们排列在一个大数组中。每个子数组都有一个固定的大小:k。
所以整个数组的大小是:N*K
我要做的是调用内核N次。在每一次中,它计算子阵列的缩减,如下所示:
我将迭代大向量中包含的所有子数组:
for(i=0;i<N;i++){
thrust::device_vector< float > Vec(subarray, subarray+k);
我是OpenACC的新手。我非常喜欢它,因为我熟悉OpenMP
我有2个1080Ti卡,每个卡有9GB,我有128GB的RAM。我正在尝试一个非常基本的测试来分配一个数组,初始化它,然后并行求和。这适用于8GB,但当我增加到10GB时,会出现内存不足错误。我的理解是,有了Pascal(这些卡就是)和CUDA8的统一内存,我可以分配一个比GPU内存大的阵列,硬件将根据需要进行分页
下面是我的完整C代码测试:
$ cat firstAcc.c
#include <stdio.h>
#
我的问题是关于如何使用FunctionCudaEventReleasedTime来测量多流应用程序中的执行时间。
根据CUDA文件
如果其中一个事件最后记录在非空流中,产生的时间可能大于预期时间(即使两者使用相同的流句柄)操作是异步进行的,无法保证测量的延迟实际上正好在两个事件之间。在两个测量的事件之间可以执行ny个其他不同的流操作,从而显著改变时间。
我真的很难理解上面粗体的句子。看起来,使用默认流来测量时间更准确。但我想知道为什么?如果我想测量流中的执行时间,我发现通过该流而不是默认流附加启
我复制了nvGRAPH提供的来计算SSSP,并修改了代码,以便使用COO(而不是CSC)作为输入图形格式
在调用nvgraphSetGraphStructure的行中,我得到一个错误8,这是一个错误。错误描述进一步指出,这通常是由于向函数传递无效的图形描述符引起的。然而,我认为这里的情况并非如此
代码示例:
#include <stdio.h>
#include <cuda_runtime.h>
#include <nvgraph.h>
#in
我正在尝试安装TensorFlow gpu,所以我需要CUDA toolkit 9.2。
不幸的是,我安装了CUDA 10,然后意识到了这一点
如何在不接触驱动程序的情况下轻松删除CUDA 10.0并安装CUDA 9.2(既然我有Ubuntu 18,我想维护最新的视频驱动程序)
它说,我已经尝试从.deb(网络)文件简单安装CUDA9.2
dpkg:处理存档cuda-repo-ubuntu1710_9.2.148-1_amd64.deb时出错(--安装):
正在尝试覆盖“/etc/apt/s
当我注意到纹理引用被弃用时,我正在使用纹理引用,我尝试更新我的测试函数以使用tex1Dfetch的“新”无绑定纹理对象,但无法产生相同的结果
我目前正在探索使用纹理内存来加速我的aho corasick实现;我能够让tex1D处理纹理引用,但是,我注意到它们已被弃用,并决定使用纹理对象
当我试图以任何方式使用结果时,我得到了一些非常奇怪的内核行为;我可以做结果[tidx]=tidx;没有任何问题,但结果[tidx]=temp+1;仅返回temp not temp*3的值或任何其他涉及temp的数
我想根据模板向量有条件地从向量复制数据,模板向量比模板向量短N倍。模具中的每个元素将负责数据向量中的N个元素。
假设向量如下所示(N=3)
我希望得到的结果是:
result = {1,2,3,7,8,9}
有没有办法使用推力库中的函数来实现这一点
我知道,有:
thrust::copy_if (InputIterator1 first, InputIterator1 last, InputIterator2 stencil, OutputIterator result, Predicate
我尝试使用GPU对数组求和,代码如下:
__global__ void sum_array(int* a, uint n) {
uint idx = threadIdx.x + blockIdx.x * blockDim.x;
for (int s = 1; s < n; s *= 2) {
uint i1 = s * 2 * idx;
uint i2 = s * (2 * idx + 1);
if (i2 < n)
在windows下运行nvprof--metrics命令时出现错误:
==6580== NVPROF is profiling process 6580, command: Project1.exe
==6580== Error: Internal profiling error 4292:1.
======== Error: CUDA profiling error.
如果我只使用nvprof命令,则不会报告任何错误:
F:\vstest\Project1\x64\Release>n
我了解CUDA中如何安排翘曲和块,但不了解这两种安排是如何结合在一起的。我知道,一旦SM中有足够的执行资源来支持一个新块,就会执行一个新块,并且我知道每个时钟周期(如果备用执行资源允许)都会选择合适的扭曲来执行。然而,究竟是什么让扭曲“合格”?如果有足够的执行资源来支持一个新的扭曲,而不是一个新的块呢?块调度是否包括扭曲调度?非常感谢您的帮助,谢谢
块调度是否包括扭曲调度
块调度器和扭曲调度器应视为两个独立的实体。事实上,我将块调度器视为设备范围的实体,而warp调度器是每SM实体
您可以想象,
我正试图通过使用VS2010的并行Nsight 2.1版来优化我的CUDA程序
我的程序在带有GTX 480板的Windows 7(32位)计算机上运行。我已经安装了CUDA 4.1 32位工具包和301.32驱动程序
程序中的一个周期包括将主机数据复制到设备、执行内核以及将结果从设备复制到主机
正如您在下面的分析器结果图中所看到的,内核在四个不同的流中运行。每个流中的内核依赖于“流2”中复制到设备的数据。这就是asyncMemcpy在不同流中启动内核之前与CPU同步的原因
图中让我恼火的是第
例如,我如何使用两个设备来提高性能
以下代码的性能(向量之和)?
是否可以“同时”使用更多设备?
如果是,如何管理不同设备的全局内存上向量的分配
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <cuda.h>
#define NB 32
#define NT 500
#define N NB*NT
__globa
标签: Cuda
gpunvidianvccdarknet
我想在我的电脑上用GPU支持编译机器学习的Darknet框架。但是,我调用make时,会出现分段错误:
nvcc -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52] -Iinclude/ -Isrc/ -DOP
1 2 3 4 5 6 ...
下一页 最后一页 共 73 页