GPU 在 Julia 集合计算中没有带来性能提升

2024-01-21

我正在尝试比较 CPU 和 GPU 的性能。我有

  • CPU:Intel® Core™ i5 CPU M 480 @ 2.67GHz × 4
  • 显卡:NVidia GeForce GT 420M

我可以确认 GPU 已配置并且可以与 CUDA 一起正常工作。

我正在实现 Julia 集合计算。http://en.wikipedia.org/wiki/Julia_set http://en.wikipedia.org/wiki/Julia_set基本上对于每个像素,如果坐标在集合中,它将把它涂成红色 否则把它漆成白色。

虽然,我对 CPU 和 GPU 都得到了相同的答案,但并没有得到 性能改进,使用 GPU 会导致性能损失。

运行时间

  • CPU:0.052秒
  • GPU:0.784秒

我知道将数据从设备传输到主机可能需要一些时间。 但是,我如何知道使用 GPU 是否真的有益?

这是相关的GPU代码

    #include <stdio.h>
    #include <cuda.h>

    __device__ bool isJulia( float x, float y, float maxX_2, float maxY_2 )
    {
        float z_r = 0.8 * (float) (maxX_2 - x) / maxX_2;
        float z_i = 0.8 * (float) (maxY_2 - y) / maxY_2;

        float c_r = -0.8;
        float c_i = 0.156;
        for( int i=1 ; i<100 ; i++ )
        {
        float tmp_r = z_r*z_r - z_i*z_i + c_r;
        float tmp_i = 2*z_r*z_i + c_i;

        z_r = tmp_r;
        z_i = tmp_i;

        if( sqrt( z_r*z_r + z_i*z_i ) > 1000 )
            return false;
        }
        return true;
    }

    __global__ void kernel( unsigned char * im, int dimx, int dimy )
    {
        //int tid = blockIdx.y*gridDim.x + blockIdx.x;
        int tid = blockIdx.x*blockDim.x + threadIdx.x;
        tid *= 3;
        if( isJulia((float)blockIdx.x, (float)threadIdx.x, (float)dimx/2, (float)dimy/2)==true )
        {
        im[tid] = 255;
        im[tid+1] = 0;
        im[tid+2] = 0;
        }
        else
        {
        im[tid] = 255;
        im[tid+1] = 255;
        im[tid+2] = 255;
        }

    }

    int main()
    {
        int dimx=768, dimy=768;

        //on cpu
        unsigned char * im = (unsigned char*) malloc( 3*dimx*dimy );

        //on GPU
        unsigned char * im_dev;

        //allocate mem on GPU
        cudaMalloc( (void**)&im_dev, 3*dimx*dimy ); 

        //launch kernel. 
**for( int z=0 ; z<10000 ; z++ ) // loop for multiple times computation**
{
        kernel<<<dimx,dimy>>>(im_dev, dimx, dimy);
}

        cudaMemcpy( im, im_dev, 3*dimx*dimy, cudaMemcpyDeviceToHost );

        writePPMImage( im, dimx, dimy, 3, "out_gpu.ppm" ); //assume this writes a ppm file

        free( im );
        cudaFree( im_dev );
    }

这是CPU代码

    bool isJulia( float x, float y, float maxX_2, float maxY_2 )
    {
        float z_r = 0.8 * (float) (maxX_2 - x) / maxX_2;
        float z_i = 0.8 * (float) (maxY_2 - y) / maxY_2;

        float c_r = -0.8;
        float c_i = 0.156;
        for( int i=1 ; i<100 ; i++ )
        {
        float tmp_r = z_r*z_r - z_i*z_i + c_r;
        float tmp_i = 2*z_r*z_i + c_i;

        z_r = tmp_r;
        z_i = tmp_i;

        if( sqrt( z_r*z_r + z_i*z_i ) > 1000 )
            return false;
        }
        return true;
    }


    #include <stdlib.h>
    #include <stdio.h>

    int main(void)
    {
      const int dimx = 768, dimy = 768;
      int i, j;

      unsigned char * data = new unsigned char[dimx*dimy*3];

**for( int z=0 ; z<10000 ; z++ ) // loop for multiple times computation**
{
      for (j = 0; j < dimy; ++j)
      {
        for (i = 0; i < dimx; ++i)
        {
          if( isJulia(i,j,dimx/2,dimy/2) == true )
          {
          data[3*j*dimx + 3*i + 0] = (unsigned char)255;  /* red */
          data[3*j*dimx + 3*i + 1] = (unsigned char)0;  /* green */
          data[3*j*dimx + 3*i + 2] = (unsigned char)0;  /* blue */
          }
          else
          {
          data[3*j*dimx + 3*i + 0] = (unsigned char)255;  /* red */
          data[3*j*dimx + 3*i + 1] = (unsigned char)255;  /* green */
          data[3*j*dimx + 3*i + 2] = (unsigned char)255;  /* blue */
          }
        }
      }
}

      writePPMImage( data, dimx, dimy, 3, "out_cpu.ppm" ); //assume this writes a ppm file
      delete [] data


      return 0;
    }

此外,根据 @hyde 的建议,我循环了仅计算部分以生成 10,000 张图像。不过,我懒得写所有这些图像。我所做的只是计算。

这是运行时间

  • CPU:超过 10 分钟,代码仍在运行
  • GPU:1m 14.765s

转评论来回答:

为了得到相关的数字,需要计算不止一张图像,因此执行时间至少是几秒或几十秒。此外,在结果中包含文件保存时间会增加噪音并隐藏 CPU 与 GPU 的实际差异。

获得真实结果的另一种方法是选择一个 Julia 集,其中有很多属于该集的点,然后将迭代计数提高到需要很多秒才能计算一个图像。那么只有一种计算设置,因此这可能是 GPU/CUDA 最有利的场景。

要测量有多少开销,请将图像大小更改为 1x1 并将迭代限制设置为 1,然后计算至少需要几秒钟的足够图像。在这种情况下,GPU 可能会明显变慢。

要获得与您的用例最相关的计时,请选择您真正要使用的图像大小和迭代计数,然后测量图像计数,其中两个版本同样快。这将为您提供一个粗略的经验法则来决定何时使用哪个。

如果您只想获得一张图像,则获得实际结果的替代方法是:找到单个最坏情况图像的迭代限制,其中 CPU 和 GPU 的速度相同。如果多次或多次迭代是有利的,则选择 GPU,否则选择 CPU。

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

GPU 在 Julia 集合计算中没有带来性能提升 的相关文章

  • Cuda 6.5 找不到 - libGLU。 (在 ubuntu 14.04 64 位上)

    我已经在我的ubuntu上安装了cuda 6 5 我的显卡是 GTX titan 当我想要制作 cuda 样本之一时 模拟 粒子 我收到这条消息 gt gt gt WARNING libGLU so not found refer to C
  • TensorRT 多线程

    我正在尝试使用 python API 来使用 TensorRt 我试图在多个线程中使用它 其中 Cuda 上下文与所有线程一起使用 在单个线程中一切正常 我使用 docker 和 tensorrt 20 06 py3 图像 onnx 模型和
  • Tensorflow:docker 镜像和 -gpu 后缀

    在具有 GPU 支持的 Tensorflow 的 Docker 映像中 例如 tensorflow tensorflow 2 2 0 gpu 安装的python包是tensorflow gpu 如图所示pip freeze 安装任何依赖于的
  • cudaMemcpy() 与 cudaMemcpyFromSymbol()

    我试图找出原因cudaMemcpyFromSymbol 存在 似乎 symbol func 可以做的所有事情 nonSymbol cmd 也可以做 symbol func 似乎可以轻松移动数组或索引的一部分 但这也可以使用 nonSymbo
  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • GPU的编程语言有哪些

    我读过一篇文章 指出 GPU 是超级计算的未来 我想知道在GPU上编程使用什么编程语言 OpenCL 是开放式跨平台解决方案 可在 GPU 和 CPU 上运行 另一个是 NVIDIA 为其 GPU 构建的 CUDA HLSL Cg 等少数几
  • 内联 PTX 汇编代码强大吗?

    我看到一些代码示例 人们在 C 代码中使用内联 PTX 汇编代码 CUDA工具包中的文档提到PTX很强大 为什么会这样呢 如果我们在 C 代码中使用这样的代码 我们会得到什么好处 内联 PTX 使您可以访问未通过 CUDA 内在函数公开的指
  • 最小化 MC 模拟期间存储的 cuRAND 状态数量

    我目前正在 CUDA 中编写蒙特卡罗模拟 因此 我需要生成lots使用随机数cuRAND图书馆 每个线程处理一个巨大的元素floatarray 示例中省略 并在每次内核调用时生成 1 或 2 个随机数 通常的方法 参见下面的示例 似乎是为每
  • 通过 cuFFT 进行逆 FFT 缩放

    每当我使用 cuFFT 绘制程序获得的值并将结果与 Matlab 的结果进行比较时 我都会得到相同形状的图形 并且最大值和最小值位于相同的点 然而 cuFFT 得到的值比 Matlab 得到的值大得多 Matlab代码是 fs 1000 s
  • OpenCL 内核在 Nvidia GPU 上每个线程使用多少寄存器?

    我的第一个问题是如何获取 Nvidia GPU 上 OpenCL 内核代码的寄存器使用信息 因为 nvcc 编译器给出了相同的使用信息nvcc ptxas options vCUDA 内核代码的标志 我还从 AMD GPU for Open
  • CUDA 中指令重放的其他原因

    这是我从 nvprof CUDA 5 5 获得的输出 Invocations Metric Name Metric Description Min Max Avg Device Tesla K40c 0 Kernel MyKernel do
  • cuda 文件组织的有效方式:.cpp .h .cu .cuh .curnel 文件

    cuda最容易理解 最高效的代码组织是什么 经过一番调查后 我发现 cuda 函数声明应位于 cuh 文件中 实现位于 cu 文件中 内核函数实现位于 curnel 文件中 其他 C 内容通常在 cpp 和 h 文件中 最近我发布了一个问题
  • 在没有 SurfaceView 的 Android 上获取 GPU 信息

    在Android上 有没有一种方法可以在不创建SurfaceView的情况下获取GPU信息 我不想使用 OpenGL 绘制任何内容 但我只需要获取硬件信息 例如供应商 OpenGL ES 版本 可用扩展等 抱歉 我不知道如何在 Androi
  • 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 中
  • GPU上动态分配内存

    是否可以在内核内的 GPU 全局内存上动态分配内存 我不知道我的答案有多大 因此我需要一种方法为答案的每个部分分配内存 CUDA 4 0 允许我们使用 RAM 这是一个好主意还是会降低速度 可以在内核中使用 malloc 检查以下内容 摘自
  • 使用 cudamalloc()。为什么是双指针?

    我目前正在浏览有关的教程示例http code google com p stanford cs193g sp2010 http code google com p stanford cs193g sp2010 学习CUDA 演示的代码 g
  • 无法在 CUDA 中找到 1 到 100 数字的简单和?

    我正在研究使用 CUDA 的图像处理算法 在我的算法中 我想使用 CUDA 内核找到图像所有像素的总和 所以我在cuda中制作了内核方法 来测量16位灰度图像的所有像素的总和 但我得到了错误的答案 所以我在cuda中编写了一个简单的程序来查
  • 为什么 cudaGLSetGLDevice 失败,即使它是在 main 函数的第一行中调用的

    我想使用 OpenGL 和 CUDA 之间的互操作性 我知道 正如一些教程所说 第一步是选择设备 但是 当我在主函数的第一行中调用 cudaGLSetGLDevice 0 时 程序退出并显示信息 cudaSafeCall 运行时 API 错
  • 在 Cuda 中简单添加两个 int,结果始终相同

    我开始了学习Cuda的旅程 我正在玩一些 hello world 类型的 cuda 代码 但它不起作用 我不知道为什么 代码非常简单 取两个整数并将它们添加到 GPU 上并返回结果 但无论我将数字更改为什么 我都会得到相同的结果 如果数学那

随机推荐

  • 实现自重置 XMLHttpRequest 对象

    我正在尝试使用 XMLHttpResponse 对象实现彗星风格的长轮询连接 这个想法是保持与服务器的开放连接 该服务器在可用时发送数据 伪造推送 XHR 对象完成后 我需要生成一个新对象来等待任何新数据 下面是一段代码 概述了一个有效的解
  • 如何自动调整移动网站的图像大小?

    我尝试了谷歌搜索 但仍然无法弄清楚如何根据各种移动设备的宽度调整图像的大小 这是我的尝试 CSS img test width 100 height auto HTML
  • 确定两个未排序的数组是否相同?

    给定两个unsorted arrays A and B具有不同的元素 确定是否A and B可以重新排列 使它们相同 我的策略如下 首先 使用确定性选择算法O N 是时候找到Max of A and Max of B 如果他们没有相同的Ma
  • 读取由空格分隔的单词,并且字符串值在批处理脚本中也包含空格

    我需要从批处理脚本读取注册表的默认值 某些项目的名称包含一些空格 另外我想在批处理文件中执行 for 循环一次两次 rem echo OFF setlocal ENABLEEXTENSIONS set KEY NAME HKEY CURRE
  • 如何在 Play 之外使用 Anorm?

    在 Scala 之外如何使用 Anorm 在玩的 Anorm 文档中 它简单地使用了类似的内容 DB withConnection implicit c gt val result Boolean SQL Select 1 execute
  • clang-query:检查函数参数类型的模板参数名称

    我有一个大项目 以及大量以下形式的 C 类成员函数 Return CClass MemberFunction Arg1 arg1 std weak ptr
  • 应用程序崩溃但没有 TestFlight 崩溃报告

    我有一位用户 使用 iPhone 5 报告说 我的应用程序在屏幕变黑 启动画面为黑色 后大约 15 秒后崩溃 用户下载了 TestFlight 版本 其中我在应用程序委托中包含了检查点 但我没有得到这些检查点被交叉的证据 而且我从未收到崩溃
  • 我可以用C++中的成员变量地址获取对象的引用吗?

    如果我只有该对象的成员变量的地址 是否可以获得对该对象的引用 struct example int var int main example exampleObject int point exampleObject var can i g
  • 让查询与参数和“like”一起使用

    我见过很多关于在 Sql 查询和 like 中使用参数的问题 但我已经尝试了所有我见过的编码方法 但仍然无法让我的查询给出结果 如果我在查询本身中输入一个值 它就会正常运行 当我运行列出的第一个查询时 出现错误 必须声明标量变量 Searc
  • QML 可以看到我的 Q_GADGET 但看不到 Q_OBJECT

    为什么我的可以Q GADGET在 QML JS 中可以完美阅读 但不是我的Q OBJECT 在 Ubuntu 14 04 上运行 Qt 5 8 0 我正在尝试返回一个列表 QVariantMap 的对象到 QML 我现在保持简单 没有指针等
  • 如果 body 有此类,则将此内容放入 #mydiv,否则将其他内容放入 #mydiv

    JS初学者在这里 我需要一个脚本帮助 根据页面正文标记是否具有 home 类来将不同的内容放置在 div 中 我正在尝试使用 hasClass html 来实现此目的 看起来应该非常简单 但我无法弄清楚 缺乏正确的语法知识 声明不正确 我不
  • 给定一个私钥,是否可以推导出它的公钥?

    根据我通过阅读各种材料所了解的一点点 公钥 私钥对是非对称加密的基础 也是选择 2 个素数 大致是您的私钥 并将它们相乘 大致是您的公钥 的基础 在我看来 如果您知道私钥 就可以生成公钥 这是正确的还是我弄错了什么 让我更困惑的是 不可能将
  • 动态重新加载 Cython 模块

    我正在尝试自动更新我的 python 程序即时使用的 Cython so 模块 下载新模块后del module and import modulePython 似乎仍在导入旧版本 From 这个问题 https stackoverflow
  • 如何从进程ID获取主窗口句柄?

    如何获得main来自进程 ID 的窗口句柄 我想把这个窗口放在前面 它在 Process Explorer 中运行良好 我检查了 NET 如何确定主窗口 我的发现表明它也使用EnumWindows 此代码应该以类似于 NET 的方式执行此操
  • GraphicsMagick:toBuffer() 流产生空缓冲区

    我正在尝试将文件读入缓冲区 调整其大小 然后使用以下示例代码将其写入磁盘 function processImage data gm data test jpg resize 300x300 background white flatten
  • 如何将实体框架设置为使用可选外键进行级联删除?

    我正在尝试将实体框架设置为使用可选外键在删除时级联 我首先使用代码 我的模型如下所示 public class Node Key public int ID get set ForeignKey Parent public int Pare
  • 写入 Python 子进程的标准输入,而无需communicate()的阻塞行为

    如何使其成为非阻塞调用 osd cat仅接受输入作为PIPE哪个需要p communicate 调用使进程阻塞 还有其他方法可以设置吗stdin in Popen p subprocess Popen osd cat d format in
  • Kotlin 'when' 语句 vs Java 'switch'

    Kotlin 中的模式匹配非常好 并且在 90 的用例中它不会执行下一个模式匹配这一事实是好的 在 Android 中 当数据库更新时 如果我们不放置中断以使代码如下所示 我们将使用 Java switch 属性继续下一种情况 switch
  • 供应商/捆绑包和 ruby​​ 版本

    我想知道我对 rbenv 和捆绑器的使用是否错误 我在用着rbenv和 ruby 2 1 2 一样 rbenv versions system 2 1 2 set by home deploy cp repo ruby version I
  • GPU 在 Julia 集合计算中没有带来性能提升

    我正在尝试比较 CPU 和 GPU 的性能 我有 CPU Intel Core i5 CPU M 480 2 67GHz 4 显卡 NVidia GeForce GT 420M 我可以确认 GPU 已配置并且可以与 CUDA 一起正常工作