CUDA By Example笔记--Julia集合的并行计算

news2024/11/20 22:42:10

目录

1--linux报错汇总

1-1 使用 nvcc 命令编译报错

1-2--使用 CMake 编译源码报错

2--源码解读


1--linux报错汇总

1-1 使用 nvcc 命令编译报错

        使用 nvcc ./julia_gpu.cu -lglut -lGLU -lGL 运行时,显示 cannot find -lglut 的错误,定位 "gl_helper.h" 时(即下图所示),无法找到 “glut.h”;

         解决方法:在 linux 下安装 glut 的开源版本,即 freeglut :

sudo apt-get install build-essential freeglut3 freeglut3-dev binutils-gold

        安装后,可以在路径 “/usr/include/GL” 找到头文件 glut.h;

        测试:重新编译 julia_gpu.cu 文件

nvcc ./julia_gpu.cu -lglut -lGLU -lGL

         运行可执行文件 a.out:

./a.out

1-2--使用 CMake 编译源码报错

        使用 CMake 编译提供的源码时,出现以下错误:

undefined reference to `glClearColor';

undefined reference to `glClear';

undefined reference to `glDrawPixels';

undefined reference to `glFlush';

        解决方法:在 CMakeLists.txt 中增加库的链接:

cmake_minimum_required(VERSION 3.14)

project(Test1 LANGUAGES CUDA) # 添加支持CUDA语言
add_executable(main julia_gpu.cu)
target_link_libraries(main -lglut -lGLU -lGL)

        测试:运行可执行文件 main:

2--源码解读

#include "./common/book.h"
#include "./common/cpu_bitmap.h"

#define DIM 1000

struct cuComplex {
    float   r;
    float   i;
    __device__ cuComplex( float a, float b ) : r(a), i(b) {}
    __device__ float magnitude2( void ) {
        return r * r + i * i;
    }
    __device__ cuComplex operator*(const cuComplex& a) {
        return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
    }
    __device__ cuComplex operator+(const cuComplex& a) {
        return cuComplex(r+a.r, i+a.i);
    }
};

// 判断点(x, y)是否属于 julia 集
__device__ int julia( int x, int y ) {
    const float scale = 1.5;
    float jx = scale * (float)(DIM/2 - x)/(DIM/2);
    float jy = scale * (float)(DIM/2 - y)/(DIM/2);

    cuComplex c(-0.8, 0.156);
    cuComplex a(jx, jy);

    int i = 0;
    for (i=0; i<200; i++) {
        a = a * a + c;
        if (a.magnitude2() > 1000)
            return 0;
    }

    return 1;
}

__global__ void kernel( unsigned char *ptr ) {
    
    // 在声明二维线程格时,线程格每一维的大小与图像每一维的大小相等
    // 则(0, 0)和(DIM-1, DIM-1)之间每个像素点(x, y)都能获得一个线程块
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y * gridDim.x; // 行索引 y 乘以线程块宽度 gridDim.x,再加上列索引 x,得到每一个(x, y)的指针索引

    int juliaValue = julia( x, y ); // 判断点(x, y)是否属于julia集
    ptr[offset*4 + 0] = 255 * juliaValue;
    ptr[offset*4 + 1] = 0;
    ptr[offset*4 + 2] = 0;
    ptr[offset*4 + 3] = 255;
}

int main( void ) {

    CPUBitmap bitmap(DIM, DIM); // 创建位图图像
    unsigned char    *dev_bitmap; // 创建指针,申请GPU内存
    HANDLE_ERROR( cudaMalloc( (void**)&dev_bitmap, bitmap.image_size() ) );

    dim3    grid(DIM,DIM); // 用于指定启动的线程块数量,这里用到的是二维线程格
    kernel<<<grid,1>>>( dev_bitmap ); // 执行定义的核函数,计算julia集

    HANDLE_ERROR( cudaMemcpy( bitmap.get_ptr(), dev_bitmap,
                              bitmap.image_size(),
                              cudaMemcpyDeviceToHost ) ); // 将计算结果从 device 传递到 host
                              
    HANDLE_ERROR( cudaFree( dev_bitmap ) ); // 释放在 GPU 申请的内存
                              
    bitmap.display_and_exit(); // 可视化位图
}

        核心代码分析:

dim3    grid(DIM,DIM); // 用于指定启动的线程块数量,这里用到的是二维线程格

        代码创建了一个二维线程格,其维度大小为 (DIM, DIM),即共有 DIM*DIM 个线程块,每一个线程块对应一个位图像素点(x, y),用于计算其是否属于 julia 集;

__global__ void kernel( unsigned char *ptr ) {
    
    // 在声明二维线程格时,线程格每一维的大小与图像每一维的大小相等
    // 则(0, 0)和(DIM-1, DIM-1)之间每个像素点(x, y)都能获得一个线程块
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y * gridDim.x; // 行索引 y 乘以线程块宽度 gridDim.x,再加上列索引 x,得到每一个(x, y)的指针索引

    int juliaValue = julia( x, y ); // 判断点(x, y)是否属于julia集
    ptr[offset*4 + 0] = 255 * juliaValue;
    ptr[offset*4 + 1] = 0;
    ptr[offset*4 + 2] = 0;
    ptr[offset*4 + 3] = 255;
}

         使用__global__声明核函数,gridDim 是一个常数用于保存线程格每一维的大小;由于每一个线程块对应一个像素点,则可以通过 x + y * gridDim.x 计算每一个像素点相应的偏移量;

        kernel 函数是这个例子并行计算的核心代码,通过为每一个像素点分配一个线程块,通过并行计算快速判断每一个像素点是否属于 julia 集,无需在CPU中通过循环每次只能判断一个像素点 (x, y);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/387922.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux配置核查MySQL 配置规范 (Linux)_S3A3G3

linux的配置核查问题&#xff1a; 解决&#xff1a; 1.检查是否禁止mysql对本地文件存取 方法一&#xff1a;在my.cnf的mysql字段下加local-infile0 方法二&#xff1a;启动mysql时加参数local-infile0 /etc/init.d/mysql start --local-infile0 假如需要获取本地文件&#xf…

【C语言——练习题】指针,你真的学会了吗?

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨一维数组练习题&#xff1a;字符数组练习题&#xff1a;字符指针练习题&#xff1a;二维数组练习题&am…

Numpy专栏目录(长期更新)

文章目录数组基础文件与字符串多项式分布Numpy绝对可以说是支撑Python地位的最重要的包了&#xff0c;几乎所有能叫出名的Python计算库&#xff0c;都不可避免地调用了Numpy&#xff0c;Numpy官网也列出了一些&#xff0c;大致如下图这样&#xff0c;堪称科学计算领域的瑞士军刀…

计算机网络的166个概念你知道几个 第四部分

HTML&#xff1a;HTML 称为超文本标记语言&#xff0c;是一种标识性的语言。它包括一系列标签&#xff0e;通过这些标签可以将网络上的文档格式统一&#xff0c;使分散的 Internet 资源连接为一个逻辑整体。HTML 文本是由 HTML 命令组成的描述性文本&#xff0c;HTML 命令可以说…

黑猫带你学eMMC协议第28篇:eMMC的开漏和推挽模式(push-pull open drain)

本文依据eMMC JEDEC5.1及个人工作经验整理而成,如有错误请留言。 文章为个人辛苦整理,付费内容,已加入原创侵权保护,禁止私自转载。 文章所在专栏:《黑猫带你学:eMMC协议详解》 1 什么是开漏和推挽 1.1 推挽电路是什么 关于推挽和开漏电路,更多介绍详见我的另一篇文章…

面试热点题:环形链表及环形链表寻找环入口结点问题

环形链表 问题&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接…

IP 地址的简介

IP 地址 Internet 依靠 TCP/IP 协议&#xff0c;在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的主机之间的互联。在 Internet 上&#xff0c;每一个节点都依靠唯一的 IP 地址相互区分和相互联系&#xff0c;IP 地址用于标识互联网中的每台主机的身份&#xff0c…

php宝塔搭建部署实战六零导航页LyLme_Spage源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套php开发的六零导航页LyLme_Spage源码。感兴趣的朋友可以自行下载学习。 技术架构 PHP7.0 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&#xff0c;宝塔添…

语法篇--汇编语言先导浅尝

一、相关概念 1.机器语言 机器语言&#xff08;Machine Language&#xff09;是一种计算机程序语言&#xff0c;由二进制代码&#xff08;0和1&#xff09;组成&#xff0c;可被计算机直接执行。机器语言是计算机硬件能够理解和执行的唯一语言。 机器语言通常由一系列的指令组…

湖州银行冲刺A股上市:计划募资约24亿元,资产质量水平较高

3月4日&#xff0c;湖州银行股份有限公司&#xff08;下称“湖州银行”&#xff09;递交招股书&#xff0c;准备在上海证券交易所主板上市。本次冲刺上市&#xff0c;湖州银行计划募资23.98亿元&#xff0c;将在扣除发行费用后全部用于补充该行资本金。 湖州银行在招股书中表示…

GO 语言基础语法一 (快速入门 Go 语言)

Go语言基础语法一. golang 标识符&#xff0c;关键字&#xff0c;命名规则二. golang 变量三. golang 常量四. golang 数据类型五. golang 布尔类型六. golang 数字类型七. golang 字符串1. go语言字符串字面量2. go语言字符串连接(1). 使用加号(2). 使用 fmt.Sprintf() 函数(3…

内容算法解读:提高内容摘要与原文的一致性(Faithfulness)

全文摘要&#xff1a;受益于预训练语言模型的发展&#xff0c;应用神经网络模型提取内容摘要的技术也获得了长足进步。但目前还存在一个未被很好解决的问题&#xff1a;神经网络模型提取的摘要不能如实反映原文档的中心思想&#xff0c;没有做到忠实&#xff08;not faithful&a…

simulink PID控制

系列文章目录 文章目录系列文章目录前言一、非线性系统线性化原理二、反馈控制开环控制反馈or闭环控制PID ControllerPID微调案例总结前言 将非线性系统近似线性化PIDblock与微调 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、非线性系统线性化 …

Day907.分区表 -MySQL实战

分区表 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于分区表的内容。 经常被问到这样一个问题&#xff1a; 分区表有什么问题&#xff0c;为什么公司规范不让使用分区表呢&#xff1f; 一、分区表是什么&#xff1f; 为了说明分区表的组织形式&#xff0c;先创建…

Python 数据库如何更新、删除、执行?这里实例告诉你

人生苦短 我用Python 这次继续给大家带来数据库的相关操作 Python 安装包其他数据:点击此处跳转文末名片获取 数据库更新操作 更新操作用于更新数据表的的数据&#xff0c; 以下实例将 EMPLOYEE 表中的 SEX 字段为 M的 AGE 字段递增 1&#xff1a; #!/usr/bin/python # -*- …

ubuntu-9-安装chrony时间同步

使用chrony搭建时间同步服务器 [Linux系列]Chrony时间同步服务器 配置chrony服务&#xff0c;实现服务器时间自动同步 linux上内网环境配置NTP时间同步详解 经验体会&#xff1a;解决Ubuntu 18.04Windows双系统时间不同步的问题 1 时间同步 我们知道一台电脑主机&#xff0c;…

将微信小程序页面转为图片

最近做项目遇到一个需求,那就是要将某个页面转为图片然后传给后端,我仔细找了一圈,发现官方那个Api也就是wx.canvasToTempFilePath生成的图片很有可能为空,太坑了,于是我放弃用它了,选择了用wxml2canvas。 安装wxml2canvas npm init npm install wxml2canvas --save --…

通用游戏地图解决方案设计解析

前言&#xff1a; 在软件开发过程中&#xff0c;我们都希望能设计出一个稳健的&#xff0c;可维护的系统&#xff0c;为了实现这个目的&#xff0c;人们总结出了很多相关的设计原则&#xff0c;比如SOLID原则&#xff0c; KISS原则等等。SOLID每个字母代表了一种设计原则&…

数据是如何在计算机中存储的

我们普通人对于数据存储的认识恐怕大多数都是从自己使用的电脑来的。现在几乎人手一台电脑,而我们的电脑存储着各种各样的文件,比如视频文件、音频文件和Word文档等。这些文件从计算机术语的角度都可以称为数据。 如图1-1所示是Windows 10 “我的电脑”的截图。通过该截图我…

202302读书笔记|《长安的荔枝》——只要肯努力,办法总比困难多

202302读书笔记|《长安的荔枝》——只要肯努力&#xff0c;办法总比困难多 《长安的荔枝》这本书真是酣畅淋漓啊&#xff0c;读起来一气呵成&#xff0c;以讲故事的口吻叙述&#xff0c;上林署九品小官员——李善德&#xff0c;兢兢业业工作多年&#xff0c;终于借贷买了房&…