《cuda c编程权威指南》03 - cuda小功能汇总

这篇具有很好参考价值的文章主要介绍了《cuda c编程权威指南》03 - cuda小功能汇总。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 计时

1.1 linux

1.2 window下

2. nvprof实用工具

3. 设备管理cudaDeviceProp

4. 选择最佳gpu

5. 使用nvidia-smi查询GPU信息

5.1 nvidia-smi

5.2 nvidia-smi  -L

5.3 nvidia-smi -q -i 0

5.4 nvidia-smi -q -i 0 -d MEMORY

5.5 nvidia-smi -q -i 0 -d UTILIZATION

5.6 其他-d命令


1. 计时

1.1 linux

#include <sys/time.h>

double cpuSecond() {
	struct timeval tp;
	gettimeofday(&tp, NULL);
	return ((double)tp.tv_sec + (double)tp.tv_usec*1e-6);
}

// 调用
double start = cpuSecond();
kernel_name << <grid, block >> > (argument list);
cudaDeviceSynchronize();  // 显示的使其同步。
double cost = cpuSecond() - start;

1.2 window下

#include <time.h>


// 1 调用 clock_t
time_t begin = clock();
kernel_name << <grid, block >> > (argument list);
printf("\ngpu: %f s\n", (double)(clock() - begin) / CLOCKS_PER_SEC);


// 2 调用 time_t
time_t begin, end;
time(&begin);
kernel_name << <grid, block >> > (argument list);
time(&end);
time_t elapsed = end - begin;
printf("Time measured: %ld seconds.\n", elapsed);

2. nvprof实用工具

nvprof是命令行分析工具,功能很多,可以帮助从应用程序的CPU和GPU活动情况中获取时间线信息,其包括内核执行、内存传输以及CUDA API的调用。具体可通过以下命令查看。

nvprof --help

 (1)上面命令如果报错:由于找不到cupti64_2022.2.1.dll,无法继续执行代码。。。

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

原因:nvprof工具属于插件,其dll在目录: 

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\extras\CUPTI\lib64

 系统环境没有该目录,所以索引不到dll库。

解决办法:由于C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin在系统环境中,可以将cupti64_2022.2.1.dll拷贝到bin目录中.

(2)问题二,如果运行编译文件报错:Cannot find compiler ‘cl.exe‘ in PATH

nvcc kernel.cu -o kernel  // 编译

 则将C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin 加到系统路径中。

使用办法示例:

nvprof ./kernel

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

(1)可以看到哪些操作,被操作了多少次,平均、最大、最小用时是多少,用时占比是多少;

(2)cudaMalloc用时最多,被运行了3次,最小用时2us,最大用时259ms,平均用时86ms;

3. 设备管理cudaDeviceProp

CUDA Runtime API :: CUDA Toolkit Documentation

CUDA——通过cudaDeviceProp结构体查看GPU设备信息_Irving.Gao的博客-CSDN博客

struct cudaDeviceProp {
    char name[256]; // 识别设备的ASCII字符串(比如,"GeForce GTX 940M")
    size_t totalGlobalMem; // 全局内存大小(字节) byte/1024 -> kb/1024 -> m/1024 ->g
    size_t sharedMemPerBlock; // 每个block内共享内存的大小
    int regsPerBlock; // 每个block 32位寄存器的个数
    int warpSize; // warp大小
    size_t memPitch; // 内存中允许的最大间距字节数
    int maxThreadsPerBlock; // 每个Block中最大的线程数是多少
    int maxThreadsDim[3]; // 一个块中每个维度的最大线程数
    int maxGridSize[3]; // 一个网格的每个维度的块数量
    size_t totalConstMem; // 可用恒定内存量
    int major; // 该设备计算能力的主要修订版号
    int minor; // 设备计算能力的小修订版本号
    int clockRate; // 时钟速率
    size_t textureAlignment; // 该设备对纹理对齐的要求
    int deviceOverlap; // 一个布尔值,表示该装置是否能够同时进行cudamemcpy()和内核执行
    int multiProcessorCount; // 设备上的处理器的数量
    int kernelExecTimeoutEnabled; // 一个布尔值,该值表示在该设备上执行的内核是否有运行时的限制
    int integrated; // 返回一个布尔值,表示设备是否是一个集成的GPU(即部分的芯片组、没有独立显卡等)
    int canMapHostMemory; // 表示设备是否可以映射到CUDA设备主机内存地址空间的布尔值
    int computeMode; // 一个值,该值表示该设备的计算模式:默认值,专有的,或禁止的
    int maxTexture1D; // 一维纹理内存最大值
    int maxTexture2D[2]; // 二维纹理内存最大值
    int maxTexture3D[3]; // 三维纹理内存最大值
    int maxTexture2DArray[3]; // 二维纹理阵列支持的最大尺寸
    int concurrentKernels; // 一个布尔值,该值表示该设备是否支持在同一上下文中同时执行多个内核
}

常用功能示例:

#include <cuda_runtime.h>
#include <stdio.h>
#include <iostream>
#include "device_launch_parameters.h"  


#define CHECK(call)                                   \
{                                                     \
    const cudaError_t error_code = call;              \
    if (error_code != cudaSuccess)                    \
    {                                                 \
        printf("CUDA Error:\n");                      \
        printf("    File:       %s\n", __FILE__);     \
        printf("    Line:       %d\n", __LINE__);     \
        printf("    Error code: %d\n", error_code);   \
        printf("    Error text: %s\n",                \
            cudaGetErrorString(error_code));          \
        exit(1);                                      \
    }                                                 \
}


int main(int argc, char** argv)
{
    int dev = 0;
    cudaDeviceProp devProp;
    CHECK(cudaGetDeviceProperties(&devProp, dev));
    std::cout << "使用GPU device " << dev << ": " << devProp.name << std::endl;
    // 流式多处理器:一个sm可以处理多个block,一个block只能被一个sm处理,且sm处理的基本单元是线程束warps.
    std::cout << "SM的数量:" << devProp.multiProcessorCount << std::endl;  
    std::cout << "每个线程块的共享内存大小:" << devProp.sharedMemPerBlock / 1024.0 << " KB" << std::endl;
    std::cout << "每个线程块的最大线程数:" << devProp.maxThreadsPerBlock << std::endl;
    std::cout << "每个SM的最大线程数:" << devProp.maxThreadsPerMultiProcessor << std::endl;
    std::cout << "每个SM的最大线程束数:" << devProp.maxThreadsPerMultiProcessor / 32 << std::endl;

    return EXIT_SUCCESS;
}

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

每个SM的最大线程束数是32,而一个线程束是32个线程,则每个SM最大有32x32=1024个线程也就是maxThreadsPerMultiProcessor,有14个SM,所以最大处理32x32x14=14336个线程。

 

更多功能示例: 

#include "cuda_runtime.h"
#include "device_launch_parameters.h"  // threadIdx

#include <stdio.h>    // io
#include <time.h>     // time_t clock_t
#include <stdlib.h>  // rand
#include <memory.h>  //memset
#include <math.h>

#define CHECK(call)                                   \
{                                                     \
    const cudaError_t error_code = call;              \
    if (error_code != cudaSuccess)                    \
    {                                                 \
        printf("CUDA Error:\n");                      \
        printf("    File:       %s\n", __FILE__);     \
        printf("    Line:       %d\n", __LINE__);     \
        printf("    Error code: %d\n", error_code);   \
        printf("    Error text: %s\n",                \
            cudaGetErrorString(error_code));          \
        exit(1);                                      \
    }                                                 \
}

int main(void)
{
    // 1 检查有多少个gpu
    int deviceCount = 0;
    cudaGetDeviceCount(&deviceCount);
    if (deviceCount == 0)
    {
        printf("There are no available device(s) that support CUDA\n");
    }
    else
    {
        printf("Detected %d CUDA Capable device(s)\n", deviceCount);
    }

    // 2 设置使用哪个显卡,卡号0的显卡名称。
    int dev = 0;
    CHECK(cudaSetDevice(dev));  // 设置使用哪个显卡
    cudaDeviceProp deviceProp;
    CHECK(cudaGetDeviceProperties(&deviceProp, dev));
    printf("Device %d: \"%s\"\n", dev, deviceProp.name);  // 卡号0的显卡名称。

    // 3 驱动等版本, 显卡驱动最高支持的cuda版本和当前运行的cuda版本。
    int driverVersion = 0, runtimeVersion = 0;
    cudaDriverGetVersion(&driverVersion);
    cudaRuntimeGetVersion(&runtimeVersion);
    printf("  CUDA Driver Version / Runtime Version          %d.%d / %d.%d\n",
        driverVersion / 1000, (driverVersion % 100) / 10,    // 显卡驱动最高支持的cuda版本
        runtimeVersion / 1000, (runtimeVersion % 100) / 10);  // 当前运行的cuda版本

    // 4 cuda计算能力. 7.5. 8.5之类的
    printf("  CUDA Capability Major/Minor version number:    %d.%d\n",
        deviceProp.major, deviceProp.minor);


    // 5 GPU Clock rate:   1575 MHz (1.58 GHz)
    printf("  GPU Clock rate:                                %.0f MHz (%0.2f "
        "GHz)\n", deviceProp.clockRate * 1e-3f,
        deviceProp.clockRate * 1e-6f);

    // 6 Max Texture Dimension Size (x,y,z)  1D=(131072), 2D=(131072,65536), 3D=(16384,16384,16384)
    printf("  Max Texture Dimension Size (x,y,z)             1D=(%d), "
        "2D=(%d,%d), 3D=(%d,%d,%d)\n", deviceProp.maxTexture1D,
        deviceProp.maxTexture2D[0], deviceProp.maxTexture2D[1],
        deviceProp.maxTexture3D[0], deviceProp.maxTexture3D[1],
        deviceProp.maxTexture3D[2]);

    // 7 Max Layered Texture Size (dim) x layers 1D=(32768) x 2048, 2D=(32768,32768) x 2048
    printf("  Max Layered Texture Size (dim) x layers        1D=(%d) x %d, "
        "2D=(%d,%d) x %d\n", deviceProp.maxTexture1DLayered[0],
        deviceProp.maxTexture1DLayered[1], deviceProp.maxTexture2DLayered[0],
        deviceProp.maxTexture2DLayered[1],
        deviceProp.maxTexture2DLayered[2]);

    /*
      Total amount of constant memory:               65536 bytes
      Total amount of shared memory per block:       49152 bytes
      Total number of registers available per block: 65536
      Warp size:                                     32
      Maximum number of threads per multiprocessor:  1024
      Maximum number of threads per block:           1024
      Maximum sizes of each dimension of a block:    1024 x 1024 x 64
      Maximum sizes of each dimension of a grid:     2147483647 x 65535 x 65535
      Maximum memory pitch:                          2147483647 bytes
    */
    printf("  Total amount of constant memory:               %lu bytes\n",
        deviceProp.totalConstMem);
    printf("  Total amount of shared memory per block:       %lu bytes\n",
        deviceProp.sharedMemPerBlock);
    printf("  Total number of registers available per block: %d\n",
        deviceProp.regsPerBlock);
    printf("  Warp size:                                     %d\n",
        deviceProp.warpSize);
    printf("  Maximum number of threads per multiprocessor:  %d\n",
        deviceProp.maxThreadsPerMultiProcessor);
    printf("  Maximum number of threads per block:           %d\n",
        deviceProp.maxThreadsPerBlock);
    printf("  Maximum sizes of each dimension of a block:    %d x %d x %d\n",
        deviceProp.maxThreadsDim[0],
        deviceProp.maxThreadsDim[1],
        deviceProp.maxThreadsDim[2]);
    printf("  Maximum sizes of each dimension of a grid:     %d x %d x %d\n",
        deviceProp.maxGridSize[0],
        deviceProp.maxGridSize[1],
        deviceProp.maxGridSize[2]);
    printf("  Maximum memory pitch:                          %lu bytes\n",
        deviceProp.memPitch);

}

4. 选择最佳gpu

#include "cuda_runtime.h"
#include "device_launch_parameters.h"  // threadIdx


int main(void)
{
    // 计算有多少个gpu
    int numDevices = 0;
    cudaGetDeviceCount(&numDevices);

    // 选择最佳gpu: 比较GPU包含的多处理器的数量选出计算能力最佳的GPU
    if (numDevices > 1)
    {
        int maxMultiprocessors = 0, maxDevice = 0;  // 多处理器的数量
        for (int device = 0; device < numDevices; device++)
        {
            cudaDeviceProp props;
            cudaGetDeviceProperties(&props, device);
            if (props.multiProcessorCount > maxMultiprocessors)
            {
                maxMultiprocessors = props.multiProcessorCount;
                maxDevice = device;
            }
        }
        cudaSetDevice(maxDevice);  // 将使用的gpu设置成处理器最多的那个gpu
    }
}

5. 使用nvidia-smi查询GPU信息

5.1 nvidia-smi

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

5.2 nvidia-smi  -L

GPU以及每个GPU的设备ID

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

5.3 nvidia-smi -q -i 0

0号gpu详细信息,非常信息,这里只是截图部分。

 《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

5.4 nvidia-smi -q -i 0 -d MEMORY

只是显示内存信息

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

5.5 nvidia-smi -q -i 0 -d UTILIZATION

设备使用情况

《cuda c编程权威指南》03 - cuda小功能汇总,cuda,c语言,linux,开发语言

5.6 其他-d命令

nvidia-smi -q -i 0 -d 再加上后面这些字符串,即可获取相应的信息。

·MEMORY
·UTILIZATION
·ECC

·TEMPERATURE
·POWER
·CLOCK
·COMPUTE
·PIDS
·PERFORMANCE
·SUPPORTED_CLOCKS
·PAGE_RETIREMENT
·ACCOUNTING

待续。。。文章来源地址https://www.toymoban.com/news/detail-620942.html

到了这里,关于《cuda c编程权威指南》03 - cuda小功能汇总的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Azure OpenAI 官方指南03|DALL-E 的图像生成功能与安全过滤机制

    2021年1月,OpenAI 推出 DALL-E。这是 GPT 模型在图像生成方面的人工智能应用。其名称来源于著名画家、艺术家萨尔瓦多 • 达利(Dalí)和机器人总动员(Wall-E)。DALL-E 图像生成器,能够直接 根据 文本描述 生成多种艺术风格的高质量图像 ,让机器也能拥有顶级画家、设计师的

    2024年02月02日
    浏览(44)
  • 配置VScode开发环境-CUDA编程

    如果觉得本篇文章对您的学习起到帮助作用,请 点赞 + 关注 + 评论 ,留下您的足迹💪💪💪 本文主要介绍VScode下的CUDA编程配置,因此记录以备日后查看,同时,如果能够帮助到更多人,也不胜荣幸。 compile_commands.json 文件能够有效提高一些工具(比如vscode)的代码跳转、补全

    2024年02月05日
    浏览(51)
  • Elasticsearch权威指南

    作者:禅与计算机程序设计艺术 Elasticsearch是一个基于Lucene构建的开源搜索引擎,它提供了一个分布式、高扩展性、可靠、快速、精准的全文检索解决方案。它的主要特点包括: 分布式架构:集群中每一个节点都存储数据并且可以同时被索引和搜索; RESTful API:Elasticsearch通过

    2024年02月07日
    浏览(49)
  • Elasticsearch 权威指南

    作者:禅与计算机程序设计艺术 Elasticsearch是一个开源分布式搜索引擎,它的目的是提供一个搜索引擎系统,能够实时地、高效地存储、搜索、分析海量数据。相对于传统数据库搜索引擎来说,Elasticsearch具有以下几个主要优点: 分布式特性:Elasticsearch可以横向扩展,支持P

    2024年02月11日
    浏览(46)
  • kafka权威指南(阅读摘录)

    零复制 Kafka 使用零复制技术向客户端发送消息——也就是说,Kafka 直接把消息从文件(或者更确切地说是 Linux 文件系统缓存)里发送到网络通道,而不需要经过任何中间缓冲区。这是 Kafka 与其他大部分数据库系统不一样的地方,其他数据库在将数据发送给客户端之前会先把

    2024年02月14日
    浏览(40)
  • Zookeeper 权威指南

    作者:禅与计算机程序设计艺术 1997年,Apache发布了ZooKeeper项目,基于Google的Chubby论文,解决分布式协调服务问题。ZooKeeper是一种开源的分布式协调服务,它是一个高效且可靠的分布式数据管理框架。其目标就是构建一个简单而健壮的分布式数据管理系统。 ZooKeeper通过一组简

    2024年02月09日
    浏览(38)
  • 《Kafka权威指南》读书笔记

    《Kafka权威指南》第一、三、四、六章,是重点。可以多看看。 kafka是一个发布与订阅消息系统 消息:kafka的数据单元称为\\\"消息\\\"。可以把消息看成是数据库中的一个\\\"数据行\\\"。 消息的key:为key生成一个一致性散列值(HashCode),然后使用散列值对主题分区数进行取模,为消息选

    2024年02月04日
    浏览(39)
  • Docker 与 Kubernetes 权威指南

    作者:禅与计算机程序设计艺术 作为Docker火爆发展的一年里,Kubernetes带来了容器编排的革命性变化。Kubernetes整合了云原生计算的理念和开源社区的力量,真正成为企业级容器集群管理的事实标准。本书从Docker与Kubernetes的基础知识、安装部署配置三个方面全面剖析Docker及其周

    2024年02月05日
    浏览(53)
  • hadoop权威指南第四版

    1.1 面临的问题 存储越来越大,读写跟不上。 并行读多个磁盘。 问题1 磁盘损坏 – 备份数据HDFS 问题2 读取多个磁盘用于分析,数据容易出错 --MR 编程模型 1.2 衍生品 1 在线访问的组件是hbase 。一种使用hdfs底层存储的模型。支持单行的读写,对数据块读写也是不错的。 2 yar

    2024年02月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包