与 CUDA 占用计算器不同的实验结果

2024-06-21

我研究CUDA架构。

我在如下环境中编写了一些并行处理代码。

GPU:GTX580(CC为2.0)

每块线程:16x16 = 256

每线程寄存器:16

每块共享内存:48 字节

我通过编译选项知道寄存器的数量和共享内存的大小:--ptxas-options=-v 另外,网格大小为32x32 = 1024,并且没有额外的共享内存。

因此,我尝试使用 NVIDIA 的 CUDA_Occupancy_Calculator。 然后,它说,

3.) GPU 占用数据显示在此处和图表中: 每个多处理器的活动线程 1536 每个多处理器的活动扭曲 48 每个多处理器的活动线程块 6 每个多处理器占用率 100%

所以,我运行该应用程序。 但是,结果表明块大小比 16x16 快 8x8。

8x8表示块大小,网格大小为64x64。 16x16表示块大小,网格大小为32x32。 因此,线程总数是相同的。它没有改变。

我不知道为什么。请帮我。

以下代码是我的程序的一部分。

void LOAD_VERTEX(){
        MEM[0] = 60;    //y0 
        MEM[1] = 50;    //x0
        MEM[2] = 128;   //r0
        MEM[3] = 0;     //g0
        MEM[4] = 70;    //b0
        MEM[5] = 260;
        MEM[6] = 50;
        MEM[7] = 135;
        MEM[8] = 70;
        MEM[9] = 0;
        MEM[10] = 260;
        MEM[11] = 250;
        MEM[12] = 0;
        MEM[13] = 200;
        MEM[14] = 55;
        MEM[15] = 60;
        MEM[16] = 250;
        MEM[17] = 55;
        MEM[18] = 182;
        MEM[19] = 100;
        MEM[20] = 30;
        MEM[21] = 330;
        MEM[22] = 72;
        MEM[23] = 12;
        MEM[24] = 25;
        MEM[25] = 30;
        MEM[26] = 130;
        MEM[27] = 80;
        MEM[28] = 255;
        MEM[29] = 15;
        MEM[30] = 230; 
        MEM[31] = 330;
        MEM[32] = 56;   
        MEM[33] = 186;  
        MEM[34] = 201;
}

__global__ void PRINT_POLYGON( unsigned char *IMAGEin, int *MEMin, int dev_ID, int a, int b, int c)
{
        int i = blockIdx.x*TILE_WIDTH + threadIdx.x;
        int j = blockIdx.y*TILE_HEIGHT + threadIdx.y;

        float result_a, result_b;
        int temp[15];
        int k;

        for(k = 0; k < 5; k++){
                temp[k] = a*5+k;
                temp[k+5] = b*5+k;
                temp[k+10] = c*5+k;
        }

        int result_a_up = ((MEMin[temp[11]]-MEMin[temp[1]])*(i-MEMin[temp[0]]))-((MEMin[temp[10]]-MEMin[temp[0]])*(j-MEMin[temp[1]]));
        int result_a_down = ((MEMin[temp[11]]-MEMin[temp[1]])*(MEMin[temp[5]]-MEMin[temp[0]]))-((MEMin[temp[6]]-MEMin[temp[1]])*(MEMin[temp[10]]-MEMin[temp[0]]));

        int result_b_up = ((MEMin[temp[6]] -MEMin[temp[1]])*(MEMin[temp[0]]-i))-((MEMin[temp[5]] -MEMin[temp[0]])*(MEMin[temp[1]]-j));
        int result_b_down = ((MEMin[temp[11]]-MEMin[temp[1]])*(MEMin[temp[5]]-MEMin[temp[0]]))-((MEMin[temp[6]]-MEMin[temp[1]])*(MEMin[temp[10]]-MEMin[temp[0]]));

        result_a = float(result_a_up) / float(result_a_down);
        result_b = float(result_b_up) / float(result_b_down);

        int isIn = (0 <= result_a && result_a <=1) && ((0 <= result_b && result_b <= 1)) && ((0 <= (result_a+result_b) && (result_a+result_b) <= 1));

        IMAGEin[(i*HEIGHTs+j)*CHANNELS] += (int)(float(MEMin[temp[2]]) + (float(MEMin[temp[7]])-float(MEMin[temp[2]]))*result_a + (float(MEMin[temp[12]])-float(MEMin[temp[2]]))*result_b) * isIn;      //Red Channel
        IMAGEin[(i*HEIGHTs+j)*CHANNELS+1] += (int)(float(MEMin[temp[3]]) + (float(MEMin[temp[8]])-float(MEMin[temp[3]]))*result_a + (float(MEMin[temp[13]])-float(MEMin[temp[3]]))*result_b) * isIn;    //Green Channel
        IMAGEin[(i*HEIGHTs+j)*CHANNELS+2] += (int)(float(MEMin[temp[4]]) + (float(MEMin[temp[9]])-float(MEMin[temp[4]]))*result_a + (float(MEMin[temp[14]])-float(MEMin[temp[4]]))*result_b) * isIn;    //Blue Channel

}

//The information each device
struct DataStruct {
    int                 deviceID;
    unsigned char       IMAGE_SEG[WIDTH*HEIGHTs*CHANNELS];
};

void* routine( void *pvoidData ) {
        DataStruct  *data = (DataStruct*)pvoidData;
        unsigned char *dev_IMAGE;
        int *dev_MEM;
        unsigned char *IMAGE_SEG = data->IMAGE_SEG;

        HANDLE_ERROR(cudaSetDevice(data->deviceID));

        //initialize array
        memset(IMAGE_SEG, 0, WIDTH*HEIGHTs*CHANNELS);

        printf("Device %d Starting..\n", data->deviceID);

        //Evaluate Time
        cudaEvent_t start, stop;
        cudaEventCreate( &start );
        cudaEventCreate( &stop );

        HANDLE_ERROR( cudaMalloc( (void **)&dev_MEM, sizeof(int)*35) );                                //Creating int array each Block
        HANDLE_ERROR( cudaMalloc( (void **)&dev_IMAGE, sizeof(unsigned char)*WIDTH*HEIGHTs*CHANNELS) ); //output array

        cudaMemcpy(dev_MEM, MEM, sizeof(int)*256, cudaMemcpyHostToDevice);
        cudaMemset(dev_IMAGE, 0, sizeof(unsigned char)*WIDTH*HEIGHTs*CHANNELS);

        dim3    grid(WIDTH/TILE_WIDTH, HEIGHTs/TILE_HEIGHT);            //blocks in a grid
        dim3    block(TILE_WIDTH, TILE_HEIGHT);                         //threads in a block

        cudaEventRecord(start, 0);

        PRINT_POLYGON<<<grid,block>>>( dev_IMAGE, dev_MEM, data->deviceID, 0, 1, 2);                    //Start the Kernel
        PRINT_POLYGON<<<grid,block>>>( dev_IMAGE, dev_MEM, data->deviceID, 0, 2, 3);                    //Start the Kernel
        PRINT_POLYGON<<<grid,block>>>( dev_IMAGE, dev_MEM, data->deviceID, 0, 3, 4);                    //Start the Kernel
        PRINT_POLYGON<<<grid,block>>>( dev_IMAGE, dev_MEM, data->deviceID, 0, 4, 5);                    //Start the Kernel
        PRINT_POLYGON<<<grid,block>>>( dev_IMAGE, dev_MEM, data->deviceID, 3, 2, 4);                    //Start the Kernel
        PRINT_POLYGON<<<grid,block>>>( dev_IMAGE, dev_MEM, data->deviceID, 2, 6, 4);                    //Start the Kernel

        cudaEventRecord(stop, 0);
        cudaEventSynchronize(stop);

        HANDLE_ERROR( cudaMemcpy( IMAGE_SEG, dev_IMAGE, sizeof(unsigned char)*WIDTH*HEIGHTs*CHANNELS, cudaMemcpyDeviceToHost ) );
        HANDLE_ERROR( cudaFree( dev_MEM ) );
        HANDLE_ERROR( cudaFree( dev_IMAGE ) );

        cudaEventElapsedTime( &elapsed_time_ms[data->deviceID], start, stop );          //Calculate elapsed time
        cudaEventDestroy(start);
        cudaEventDestroy(stop);

        printf("Algorithm Elapsed Time : %f ms(Device %d)\n", elapsed_time_ms[data->deviceID], data->deviceID);
        printf("Device %d Complete!\n", data->deviceID);

        return 0;
}

int main( void )
{       
        int i;
        CUTThread thread[7];

        printf("Program Start.\n");                     
        LOAD_VERTEX();

        DataStruct data[DEVICENUM];                     //define device info

        for(i = 0; i < DEVICENUM; i++){
                data[i].deviceID = i;
                thread[i] = start_thread(routine, &(data[i]));
        }

        for(i = 0; i < DEVICENUM; i++){
                end_thread(thread[i]);
        }

        cudaFreeHost(MEM);

    return 0;
}

既然你复制过来了您来自 Nvidia 论坛的问题 https://devtalk.nvidia.com/default/topic/532759/i-39-ve-a-question-about-cuda-occuapncy-calculator-by-nvidia/,我复制一下我的答案 https://devtalk.nvidia.com/default/topic/532759/cuda-programming-and-performance/i-39-ve-a-question-about-cuda-occuapncy-calculator-by-nvidia/post/3750080/#3750080还有:

对于您的内核,您发现性能随占用率升高而降低,这很容易解释为缓存溢出导致更高的占用率。

本地数组temp[]完全占用时需要 1536×15×4=92160 字节的缓存,而 33% 占用时(对于较小的 8×8 块大小)每个 SM 仅需要 512×15×4=30720 字节。通过更大的 48kB 缓存/SM 设置,后者可以完全缓存,从而消除片外内存访问temp[]几乎完全如此,但即使在默认的 16kB 缓存/SM 设置中,缓存命中概率也会显着提高。

As the temp[]无论如何都不需要数组,最快的选择(无论占用哪种情况)都是完全消除它。如果您只插入一个,编译器可能已经能够实现这一点#pragma unroll在初始化循环之前。否则替换所有使用temp[]使用一些宏或内联函数,甚至只是将结果替换到代码中(在这种情况下,我什至会发现更具可读性)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与 CUDA 占用计算器不同的实验结果 的相关文章

  • 如何为 CUDA 内核选择网格和块尺寸?

    这是一个关于如何确定CUDA网格 块和线程大小的问题 这是对已发布问题的附加问题here https stackoverflow com a 5643838 1292251 通过此链接 talonmies 的答案包含一个代码片段 见下文 我
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 最小化 MC 模拟期间存储的 cuRAND 状态数量

    我目前正在 CUDA 中编写蒙特卡罗模拟 因此 我需要生成lots使用随机数cuRAND图书馆 每个线程处理一个巨大的元素floatarray 示例中省略 并在每次内核调用时生成 1 或 2 个随机数 通常的方法 参见下面的示例 似乎是为每
  • “gld/st_throughput”和“dram_read/write_throughput”指标之间有什么区别?

    在 CUDA 可视化分析器版本 5 中 我知道 gld st requested throughput 是应用程序请求的内存吞吐量 然而 当我试图找到硬件的实际吞吐量时 我很困惑 因为有两对似乎合格的指标 它们是 gld st throug
  • cuda-gdb 错误消息

    我尝试使用 cuda gdb 调试我的 CUDA 应用程序 但遇到了一些奇怪的错误 我设置了选项 g G O0构建我的应用程序 我可以在没有 cuda gdb 的情况下运行我的程序 但没有得到正确的结果 因此我决定使用 cuda gdb 但
  • CUDA:获取数组中的最大值及其索引

    我有几个块 每个块在整数数组的单独部分上执行 举个例子 块一从 array 0 到 array 9 块二从 array 10 到 array 20 我可以获得每个块的数组最大值的索引的最佳方法是什么 示例块一 a 0 到 a 10 具有以下
  • CUDA计算能力2.0。全局内存访问模式

    CUDA 计算能力 2 0 Fermi 全局内存访问通过 768 KB L2 缓存进行 看起来 开发人员不再关心全局内存库 但全局内存仍然非常慢 因此正确的访问模式很重要 现在的重点是尽可能多地使用 重用 L2 我的问题是 如何 我将感谢一
  • OpenCV 2.4.3rc 和 CUDA 4.2:“OpenCV 错误:没有 GPU 支持”

    我在这张专辑中上传了几张截图 https i stack imgur com TELST jpg https i stack imgur com TELST jpg 我正在尝试在 Visual Studio 2008 中的 OpenCV 中
  • NVCC 警告级别

    我希望 NVCC 将以下警告视为错误 warning calling a host function foo from a host device function bar NVCC 文档 NVIDIA CUDA 编译器驱动程序 NVCC
  • CUDA Thrust 库中counting_iterators 的用途和用法

    我很难理解counting iterator在 CUDA 的推力库中 它的目的是什么以及如何使用 它在其他编程语言 例如 C 中也可用吗 计数迭代器只是一个迭代器 它从每次迭代器递增时前进的序列中返回下一个值 最简单的例子是这样的 incl
  • 使用 GPU 进行 Matlab 卷积

    我用gpuArray尝试了matlab的卷积函数conv2 convn 例如 convn gpuArray rand 100 100 10 single gpuArray rand 5 single 并将其与 cpu 版本 convn ra
  • 使用 Cuda 并行读取多个文本文件

    我想使用 CUDA 在多个文件中并行搜索给定字符串 我计划使用 pfac 库来搜索给定的字符串 问题是如何并行访问多个文件 示例 我们有一个包含 1000 个文件的文件夹 需要搜索 这里的问题是我应该如何访问给定文件夹中的多个文件 应该动态
  • 如何安装libcusolver.so.11

    我正在尝试安装 Tensorflow 但它要求 libcusolver so 11 而我只有 libcusolver so 10 有人可以告诉我我做错了什么吗 这是我的 Ubuntu nvidia 和 CUDA 版本 uname a Lin
  • 一维纹理内存访问比一维全局内存访问更快吗?

    我正在测量标准纹理和 1Dtexture 内存访问之间的差异 为此 我创建了两个内核 global void texture1D float doarray int size int index calculate each thread
  • 如何从尖点库矩阵格式获取原始指针

    我需要从尖点库矩阵格式获取原始指针 例如 cusp coo matrix
  • 使用设备函数指针数组

    我需要以下设备版本 主机代码 double func double x double func1 double x return x 1 double func2 double x return x 2 double func3 doubl
  • 针对“CUDA 驱动程序版本不足以满足 CUDA 运行时版本”该怎么办?

    当我去 usr local cuda samples 1 Utilities deviceQuery并执行 moose pc09 usr local cuda samples 1 Utilities deviceQuery sudo mak
  • 我可以将 CUDA 与非 NVIDIA GPU 一起使用吗? [复制]

    这个问题在这里已经有答案了 我正在寻找一种在没有 NVIDIA GPU 的系统上运行 CUDA 程序的方法 我尝试安装 MCUDA 和 gpuOcelot 但安装似乎遇到一些问题 我已经浏览了中给出的答案如何使用软件实现在没有 GPU 的情
  • 嵌套循环中数组的二维累积和——CUDA实现?

    我一直在考虑如何使用归约在 CUDA 上执行此操作 但我对如何完成它有点不知所措 C 代码如下 要记住的重要部分 变量预先计算的值依赖于取决于both循环迭代器 另外 变量ngo并不是每个值都是唯一的m 例如m 0 1 2 可能有ngo 1
  • 如何在 Java 编程中使用 GPU

    我这些天都在使用 CUDAC 来访问 GPU 但现在我的导游要求我使用 Java 和 GPU 于是我在网上搜索发现Rootbeer是最好的选择 但我无法理解如何使用 Rootbeer 运行程序 可以有一个吗告诉我使用 Rootbeer 的步

随机推荐

  • vagrant box速度慢,如何改进?

    我们已经为我们的开发盒构建了一个 vagrant box 但我们面临着一些延迟问题 Issues Assetic 手表速度很慢 app dev php 中的整体应用程序访问速度很慢 在 vagrant box 的共享文件夹中使用 查找 命令
  • 在 Kotlin 中将数组转换为列表

    我尝试用 与java相同 来做到这一点 val disabledNos intArrayOf 1 2 3 4 var integers Arrays asList disabledNos 但这并没有给我一个清单 有任何想法吗 Kotlin
  • 用于在子字符串中用破折号替换空格的正则表达式。

    我一直在努力寻找一种方法 可以用字符串中的破折号替换空格 但只能替换字符串特定部分内的空格 Source ABC This is a sub string DEF 我对正则表达式的尝试 s g 如果我使用正则表达式来匹配空格并替换 我会得到
  • 是否可以在 php.ini 中指示 PHP 使用 postfix 配置?

    是否可以配置 PHP 使用 postfix 的配置集发送电子邮件 WordPress 通过 PHPMailer 依赖于 php ini 中的这些设置是否正确 SMTP localhost http php net smtp port smt
  • gcc:对 -static -shared -fPIE -fPIC -Wl,-pie 感到困惑

    我正在尝试构建 clang 所有库都静态链接 这样我就可以在具有古老 GCC 4 4 版本的 CentOS 6 上运行它 首先 我想添加选项 static通过打开 LLVM BUILD STATIC 就足够了 但到了链接阶段 就出错了 生成
  • onTouch 给出奇怪的触摸点 Android

    我正在做的事情非常简单 我以前做过 但现在它没有按我的预期运行 无论如何 让我简要解释一下我正在尝试做什么以及我得到了什么 设想 我有一个RelativeLayout其中一个ImageView已放置 现在我设置touchlistener像这
  • 应用程序 Angular2 外部的路由

    我在 Angular2 中有一个应用程序 我需要在应用程序外部导航 我有简单的看法 a target blank library url a 我想导航到library url 我有导航方法 goToPage url string What
  • ggplot2 可视化/显示中的地图错误?

    正如您在下面看到的 我使用 ggplots 制作的地图上存在一个奇怪的显示问题 任何投影似乎都会发生同样的问题 这是代码 仅包maps and ggplot2需要 mapWorld lt borders world colour gray5
  • 在查询中创建临时变量

    我希望能够在查询中创建一个临时变量 而不是存储过程或函数 它不需要声明和设置 这样我在调用它时就不需要传递查询参数 正在努力朝这个方向努力 Select field1 tempvariable 2 2 newlycreatedfield t
  • 覆盖 Vagrantfile 自定义 JSON 数据中的 Cookbook 属性

    如何在 Vagrant 文件中使用chef json 访问node override 例如 使用vagrant berkshelf 我正在尝试安装基于自定义 JSON 数据的特定 Maven 版本Vagrantfile chef json
  • 使用 Javascript / Jquery 的本地存储(不使用 HTML5)

    我想在 javascript 或 jquery 中复制本地存储概念 类似于 HTML5 但不幸的是我不知道如何开始 任何人都可以建议如何使用 javascript 或 jquery 实现本地存储 不使用 HTML5 这是一个有点愚蠢的差事
  • 引入 V8 后,Google Apps 脚本无法为其他用户完全执行

    我编写了一个脚本 得到了这里好心人的大力帮助 该脚本使用 Google Sheets 脚本复制 Google Drive 上的文件夹 和内容 它运行了很长一段时间 但后来我启用了 V8 引擎 现在已禁用 问题是 它仍然适用于我 也许还有其他
  • 根据R中的前一行和当前行按组计算

    我可以根据 R 中的前一行和当前行进行计算 对于此数据框 df A B 1 2 2 2 2 3 3 4 5 5 B2 A2 0 5 B1 我可以使用这段代码来计算这个函数 for i in 2 nrow df B i lt 1 2 B i
  • 协程和 Firebase:如何实现类似 Javascript 的 Promise.all()

    在 Javascript 中 您可以同时启动两个 或更多 异步任务 等待它们完成 然后执行某些操作 继续 const firstReturn secondReturn await Promise all firstPromise secon
  • 将数据从控制器传递到 symfony2 类型

    如果我在表单中显示 实体 类型的字段 并且我想根据从控制器传递的参数过滤此实体类型 我该怎么做 PlumeOptionsType php public function buildForm FormBuilder builder array
  • 错误:无法访问文件“$libdir/plpython2”:没有这样的文件或目录

    我正在运行 postgresql 9 4 PostgreSQL 9 4 4 on x86 64 unknown linux gnu compiled by gcc GCC 4 1 2 20070626 Red Hat 4 1 2 14 64
  • 从 ES6 箭头函数返回对象文字

    如果有人解释为什么在 UpdatedPosts 中我们应该返回一个对象 而在一个对象内我们应该再次返回它 我将不胜感激 为什么我们可以只做这种和平的代码 gt const UpdatedPosts posts map 数据 gt 数据 作者
  • 以最少插入次数将字符串转换为回文

    这是一个来自日常编码问题 https www dailycodingproblem com 给定一个字符串 找到可以通过插入来组成的回文数 单词中任何位置的字符数尽可能少 如果有 大于一个可以制作的最小长度的回文 返回 字典顺序最早的一个
  • 使用 jQuery 仅从字符串末尾修剪空格

    我知道 jQuery trim 函数 但我需要的是一种仅从字符串末尾修剪空格的方法 而不是开头 So str this is a string 会成为 str this is a string 有什么建议么 Thanks 您可以使用正则表达
  • 与 CUDA 占用计算器不同的实验结果

    我研究CUDA架构 我在如下环境中编写了一些并行处理代码 GPU GTX580 CC为2 0 每块线程 16x16 256 每线程寄存器 16 每块共享内存 48 字节 我通过编译选项知道寄存器的数量和共享内存的大小 ptxas optio