CUDA(19)之PTX优化原理

article/2025/9/13 11:46:42

摘要

本文主要讲述CUDA中的PTX的原理实现和分析。

 

1. 不作优化的代码实现

Nvidia GTX 1050, CUDA 8.0测试代码如下:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"#include <stdio.h>__global__ void gpu(int *d_ptr, int length) {int elemID = blockIdx.x * blockDim.x + threadIdx.x;for (int innerloops = 0; innerloops < 100000; innerloops++) {if (elemID < length) {//unsigned int laneid;d_ptr[elemID] = elemID % 32;}}
}void valid(int *h_ptr, int length) {for (int elemID = 0; elemID<length; elemID++) {h_ptr[elemID] = elemID % 32;}
}int main(int argc, char **argv) {const int N = 1000;int *d_ptr;cudaMalloc(&d_ptr, N * sizeof(int));int *h_ptr;cudaMallocHost(&h_ptr, N * sizeof(int));//start timingfloat time_elapsed = 0;cudaEvent_t start, stop;cudaEventCreate(&start);cudaEventCreate(&stop);cudaEventRecord(start, 0);// GPU kernel without PTXdim3 cudaBlockSize(256, 1, 1);dim3 cudaGridSize((N + cudaBlockSize.x - 1) / cudaBlockSize.x, 1, 1);gpu << <cudaGridSize, cudaBlockSize >> >(d_ptr, N);cudaGetLastError();cudaDeviceSynchronize();// Finish timingcudaEventRecord(stop, 0);cudaEventSynchronize(start);cudaEventSynchronize(stop);cudaEventElapsedTime(&time_elapsed, start, stop);// Printprintf("Time Used on GPU:%f(ms)\n", time_elapsed);// CPU (results for validate)valid(h_ptr, N);int *h_d_ptr;cudaMallocHost(&h_d_ptr, N * sizeof(int));cudaMemcpy(h_d_ptr, d_ptr, N * sizeof(int), cudaMemcpyDeviceToHost);bool bValid = true;for (int i = 0; i<N && bValid; i++) {if (h_ptr[i] != h_d_ptr[i]) {bValid = false;}}printf("Test %s.\n", bValid ? "Successful" : "Failed");cudaFree(d_ptr);cudaFreeHost(h_ptr);cudaFreeHost(h_d_ptr);return bValid ? EXIT_SUCCESS : EXIT_FAILURE;
}

Nvidia GTX 1050, CUDA 8.0测试结果如下:

Nvidia 780Ti, CUDA 7.5测试代码如下: 

#include <stdio.h>
#include <assert.h>
#include <cuda_runtime.h>
#include <helper_functions.h>
#include <helper_cuda.h>__global__ void gpu(int *d_ptr, int length){int elemID = blockIdx.x * blockDim.x + threadIdx.x;for(int innerloops = 0; innerloops < 100000; innerloops++){if (elemID < length){//unsigned int laneid;d_ptr[elemID] = elemID % 32;}}
}void valid(int *h_ptr, int length){for (int elemID=0; elemID<length; elemID++){h_ptr[elemID] = elemID % 32;}
}int main(int argc, char **argv){const int N = 1000;int *d_ptr;checkCudaErrors(cudaMalloc(&d_ptr, N * sizeof(int)));int *h_ptr;checkCudaErrors(cudaMallocHost(&h_ptr, N * sizeof(int)));//start timingfloat time_elapsed=0;cudaEvent_t start,stop;cudaEventCreate(&start);    cudaEventCreate(&stop);cudaEventRecord( start,0);// GPU kernel without PTXdim3 cudaBlockSize(256,1,1);dim3 cudaGridSize((N + cudaBlockSize.x - 1) / cudaBlockSize.x, 1, 1);gpu<<<cudaGridSize, cudaBlockSize>>>(d_ptr, N);checkCudaErrors(cudaGetLastError());checkCudaErrors(cudaDeviceSynchronize());// Finish timingcudaEventRecord(stop,0);    cudaEventSynchronize(start);    cudaEventSynchronize(stop);   cudaEventElapsedTime(&time_elapsed,start,stop);// Printprintf("Time Used on GPU:%f(ms)\n",time_elapsed);// CPU (results for validate)valid(h_ptr, N);int *h_d_ptr;checkCudaErrors(cudaMallocHost(&h_d_ptr, N *sizeof(int)));checkCudaErrors(cudaMemcpy(h_d_ptr, d_ptr, N *sizeof(int), cudaMemcpyDeviceToHost));bool bValid = true;for (int i=0; i<N && bValid; i++){if (h_ptr[i] != h_d_ptr[i]){bValid = false;}}printf("Test %s.\n", bValid ? "Successful" : "Failed");checkCudaErrors(cudaFree(d_ptr));checkCudaErrors(cudaFreeHost(h_ptr));checkCudaErrors(cudaFreeHost(h_d_ptr));return bValid ? EXIT_SUCCESS: EXIT_FAILURE;
}

Nvidia 780Ti, CUDA 7.5测试结果如下:

2.  PTX

PTX主要特点是预计算的索引值放到L1缓存,实现内存操作的预取优化,达到本案例中性能的大幅提升。

Nvidia 780Ti, CUDA 7.5测试代码如下:

#include <stdio.h>
#include <assert.h>
#include <cuda_runtime.h>
#include <helper_functions.h>
#include <helper_cuda.h>__global__ void gpu_ptx(int *d_ptr, int length){int elemID = blockIdx.x * blockDim.x + threadIdx.x;for(int innerloops = 0; innerloops < 100000; innerloops++){if (elemID < length){unsigned int laneid;asm("mov.u32 %0, %%laneid;" : "=r"(laneid)); // 索引缓存d_ptr[elemID] = laneid;}}
}void valid(int *h_ptr, int length){for (int elemID=0; elemID<length; elemID++){h_ptr[elemID] = elemID % 32;}
}int main(int argc, char **argv){const int N = 1000;int *d_ptr;checkCudaErrors(cudaMalloc(&d_ptr, N * sizeof(int)));int *h_ptr;checkCudaErrors(cudaMallocHost(&h_ptr, N * sizeof(int)));//start timingfloat time_elapsed=0;cudaEvent_t start,stop;cudaEventCreate(&start);    cudaEventCreate(&stop);cudaEventRecord( start,0);// GPU kernel using PTXdim3 cudaBlockSize(256,1,1);dim3 cudaGridSize((N + cudaBlockSize.x - 1) / cudaBlockSize.x, 1, 1);gpu_ptx<<<cudaGridSize, cudaBlockSize>>>(d_ptr, N);checkCudaErrors(cudaGetLastError());checkCudaErrors(cudaDeviceSynchronize());// Finish timingcudaEventRecord(stop,0);    cudaEventSynchronize(start);    cudaEventSynchronize(stop);   cudaEventElapsedTime(&time_elapsed,start,stop);// Printprintf("Time Used on GPU:%f(ms)\n",time_elapsed);// CPU (results for validate)valid(h_ptr, N);int *h_d_ptr;checkCudaErrors(cudaMallocHost(&h_d_ptr, N *sizeof(int)));checkCudaErrors(cudaMemcpy(h_d_ptr, d_ptr, N *sizeof(int), cudaMemcpyDeviceToHost));bool bValid = true;for (int i=0; i<N && bValid; i++){if (h_ptr[i] != h_d_ptr[i]){bValid = false;}}printf("Test %s.\n", bValid ? "Successful" : "Failed");checkCudaErrors(cudaFree(d_ptr));checkCudaErrors(cudaFreeHost(h_ptr));checkCudaErrors(cudaFreeHost(h_d_ptr));return bValid ? EXIT_SUCCESS: EXIT_FAILURE;
}

Nvidia 780Ti, CUDA 7.5测试结果如下:

Nvidia GTX 1050, CUDA 8.0测试代码如下:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"#include <stdio.h>__global__ void gpu_ptx(int *d_ptr, int length) {int elemID = blockIdx.x * blockDim.x + threadIdx.x;for (int innerloops = 0; innerloops < 100000; innerloops++) {if (elemID < length) {unsigned int laneid;asm("mov.u32 %0, %%laneid;" : "=r"(laneid)); // 索引缓存d_ptr[elemID] = laneid;}}
}void valid(int *h_ptr, int length) {for (int elemID = 0; elemID<length; elemID++) {h_ptr[elemID] = elemID % 32;}
}int main(int argc, char **argv) {const int N = 1000;int *d_ptr;cudaMalloc(&d_ptr, N * sizeof(int));int *h_ptr;cudaMallocHost(&h_ptr, N * sizeof(int));//start timingfloat time_elapsed = 0;cudaEvent_t start, stop;cudaEventCreate(&start);cudaEventCreate(&stop);cudaEventRecord(start, 0);// GPU kernel using PTXdim3 cudaBlockSize(256, 1, 1);dim3 cudaGridSize((N + cudaBlockSize.x - 1) / cudaBlockSize.x, 1, 1);gpu_ptx << <cudaGridSize, cudaBlockSize >> >(d_ptr, N);cudaGetLastError();cudaDeviceSynchronize();// Finish timingcudaEventRecord(stop, 0);cudaEventSynchronize(start);cudaEventSynchronize(stop);cudaEventElapsedTime(&time_elapsed, start, stop);// Printprintf("Time Used on GPU:%f(ms)\n", time_elapsed);// CPU (results for validate)valid(h_ptr, N);int *h_d_ptr;cudaMallocHost(&h_d_ptr, N * sizeof(int));cudaMemcpy(h_d_ptr, d_ptr, N * sizeof(int), cudaMemcpyDeviceToHost);bool bValid = true;for (int i = 0; i<N && bValid; i++) {if (h_ptr[i] != h_d_ptr[i]) {bValid = false;}}printf("Test %s.\n", bValid ? "Successful" : "Failed");cudaFree(d_ptr);cudaFreeHost(h_ptr);cudaFreeHost(h_d_ptr);return bValid ? EXIT_SUCCESS : EXIT_FAILURE;
}

Nvidia GTX 1050, CUDA 8.0测试结果如下:


http://chatgpt.dhexx.cn/article/GHXduQGZ.shtml

相关文章

Cy5/FITC/CY3/CY7-Nab-PTX ,荧光标记白蛋白结合型紫杉醇

Cy5 (Cyanine 5) 是一种发远红(far-red)荧光的花青素荧光染料&#xff0c;分为普通Cy5和磺化Cy5(Sulfo-Cy5)。它的消光系数很高&#xff0c;荧光很亮&#xff0c;并且对pH不敏感&#xff0c;一般可以用633 nm或647 nm的激光束激发然后用 Cy5或APC滤片观察&#xff0c;所以在绝大…

vs进行cuda编程失败,报错“the provided PTX was compiled with an unsupported toolchain.”

这表明提供的PTX是使用不受支持的工具链编译的。最常见的原因是PTX是由比CUDA驱动程序和PTX JIT编译器支持的编译器更新的编译器生成的。 解决&#xff1a;更新显卡驱动。 更新方法&#xff1a; 1.进入英伟达官网页面&#xff0c;网址https://www.nvidia.cn/Download/index.asp…

arduino笔记33:nRF24l01模块使用 FSK 波特率 通信方式 PTX PRX

最近再arduino中文社区看到了一篇介绍nrf24l01基本原理的帖子&#xff0c;内容感觉蛮不错的&#xff0c;学习一下&#xff0c;记录一下学习笔记。 大部分内容都是Arduino中文社区的帖子&#xff0c;附上自己的一点点体会。 目录 一、数据传输 FSK&#xff08;Frequency Shi…

Internal: Invoking ptxas not supported on WindowsRelying on driver to perform ptx compilation.

原环境&#xff1a;Windows 10, gpu 3090, TF 1.15&#xff0c;cuda_10.0.130_411.31_win10&#xff0c;cuDNN 7.6.5.32 mask-rcnn框架&#xff0c;运行train.py报错信息如下&#xff1a; image_id 333 image_id 32 image_id 58 2022-01-01 19:03:07.415032: I tensorflow/str…

Matlab里.cu函数转ptx文件常见错误

错误类型&#xff1a; nvcc fatal : Cannot find compiler ‘cl.exe’ in PATHwarning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 &#xff1b;fatal error C1083: 无法打开包括文件: “mat.h”: No such file or di…

vs cuda c/c++ 生成ptx配置

在编译cu文件生成ptx文件 一&#xff1a;生成依赖项目 二&#xff1a;配置.cu属性&#xff0c;项目类型改为CUDA C/C 三&#xff1a;配置CUDA C/C属性 compiler output&#xff1a;输出的文件名&#xff1b; additional include directories: 包含库&#xff1b; nvcc compi…

the provided ptx was compiled with an unsupported toolchain

本人遇到这个问题的原因是&#xff0c;一个动态库在一个cuda驱动比较新的服务器上编译的&#xff0c;然后使用这个动态库&#xff0c;在cuda较老的驱动上运行 编译机器cuda版本信息 运行机器cuda版本信息

VS查看PTX代码

首先&#xff0c;声明本人用的是Windows 7操作系统&#xff0c;使用Windows 8操作系统的小伙伴们会启动不了Nsight monitor&#xff0c;原因在于Windows 8操作系统的Framework版本过新&#xff0c;解决办法可以是&#xff1a;安装一个版本旧一点的Matlab&#xff0c;安装起初会…

Nvidia Tensor Core-MMA PTX编程入门

目录 1 PTX (Parallel Thread Execution) 2 MMA (Matrix Multiply Accumulate) PTX 3 LDMATRIX PTX 4 示例 5 底层代码 6 其他 6.1 HGEMM优化 1 PTX (Parallel Thread Execution) PTX是什么&#xff0c;Nvidia官方描述为a low-level parallel thread execution virtual…

PTX ISA 7.4 参考手册翻译

文章目录 PTX Parallel Thread Execution ISA 7.4SynataxSource FormatCommentsStatementsinstruction identifiersInteger ConstantFloat-Point ConstantConstant expression整型常量表达式求值 State Spaces, Types, and Variables状态空间Kernel Function ParametersKernel …

CUDA PTX ISA阅读笔记(一)

不知道这是个啥的看这里&#xff1a;Parallel Thread Execution ISA Version 5.0. 简要来说&#xff0c;PTX就是.cu代码编译出来的一种东西&#xff0c;然后再由PTX编译生成执行代码。如果不想看网页版&#xff0c;cuda的安装目录下的doc文件夹里有pdf版本&#xff0c;看起来也…

CUDA进阶第二篇:巧用PTX

写在前面 并行线程执行&#xff08;Parallel Thread eXecution&#xff0c;PTX&#xff09;代码是编译后的GPU代码的一种中间形式&#xff0c;它可以再次编译为原生的GPU微码。CUDA 手册传送门&#xff1a;Parallel Thread Execution ISA Version 4.3 利用PTX来进行试验&…

一文了解GPU并行计算CUDA

了解GPU并行计算CUDA 一、CUDA和GPU简介二、GPU工作原理与结构2.1、基础GPU架构2.2、GPU编程模型2.3、软件和硬件的对应关系 三、GPU应用领域四、GPUCPU异构计算五、MPI与CUDA的区别 一、CUDA和GPU简介 CUDA&#xff08;Compute Unified Device Architecture&#xff09;&…

MPI 并行

MPI from b站视频 超算小白-灵犀学院 click &#xff08;一&#xff09;基本框架 头文件 mpi.h #include "mpi.h"初始化函数&#xff1a;MPI_Init( ) MPI_Init(int *argc, char ***argv)完成MPI程序初始化工作&#xff0c;通过获取main函数的参数&#xff0c;让…

C# 并行编程

一 并行任务库TPL 1 并行任务库&#xff08;TPL&#xff0c;Task Parallel Library&#xff09; 2 最重要的是Task类&#xff0c;还有Parallel类 3 Task类&#xff0c;是利用线程池来进行任务的执行 比如直接用ThreadPool更优化&#xff0c;而且编程更方便 4 Paallel类&…

并行处理及分布式系统

并行处理及分布式系统 1 为什么要并行计算 1.1 为什么需要不断提升性能 随着计算能力的增加&#xff0c;我们所面临的计算问题和需求也在增加随着技术的进步&#xff0c;我们从未想过的技术得到了解决&#xff0c;比如&#xff1a;人类基因解码、更准确的医疗成像、更快速准…

并行计算之MPI(一)

MPI学习 1. 了解并行计算 为什么要采用并行计算&#xff1f; &#xff08;1&#xff09;这是因为它可以加快速度即在更短的时间内解决相同的问题或在相同的时间内解决更多更复杂的问题特别是对一些新出现的巨大挑战问题&#xff1b; &#xff08;2&#xff09;节省投入并行计…

并行网关

1、并行网关 假设现在我们想在旁边放一份沙拉。无论如何&#xff0c;如果你想要沙拉&#xff0c;你可以像我们在图1.1中所做的那样建模。 图1.1:准备沙拉和主菜。 在这里&#xff0c;我们介绍了另一个符号&#xff1a;(文本)注释&#xff1b;这是一个您可以与任何流对象(在本…

并行计算:循环程序并行化的一般方法

一、数据划分和处理器指派 1. 带状划分方法 又叫做行列划分&#xff0c;就是将矩阵的整行或整列分成若干组&#xff0c;各组指派给一个处理器。 例如&#xff1a;设矩阵A由n行和m列&#xff0c;对其串行处理的程序段如下&#xff1a; for i1 to n dofor j1 to m doProcess(a[…

并行计算之MPI(三)

了解MPI 什么是MPI &#xff08;1&#xff09;MPI是一个库而不是一门语言&#xff0c;许多人认为MPI就是一种并行语言&#xff0c;这是不准确的。但是按照并行语言的分类可以把FORTRANMPI或CMPI。看作是一种在原来串行语言基础之上扩展后得到的并行语言&#xff0c;MPI库可以被…