AMD OpenCL 大学教程(2): OpenCL概述

1、OpenCL架构 OpenCL可以实现混合设备的并行计算,这些设备包括CPU,GPU,以及其它处理器,比如Cell处理器,DSP等。使用OpenCL编程,可以实现可移植的并行加速代码。[ 但由于各个OpenCL device不同的硬件性能,可能对于程序的优化还要考虑具体的硬件特性 ]

1、opencl架构

OpenCL可以实现混合设备的并行计算,这些设备包括CPU,GPU,以及其它处理器,比如Cell处理器,DSP等。使用OpenCL编程,可以实现可移植的并行加速代码。[但由于各个OpenCL device不同的硬件性能,可能对于程序的优化还要考虑具体的硬件特性]。

通常OpenCL架构包括四个部分:

平台模型(Platform Model) 执行模型(Execution Model) 内存模型(Memory Model) 编程模型(Programming Model)

2、OpenCL平台模型

不同厂商的OpenCL实施定义了不同的OpenCL平台,通过OpenCL平台,主机能够和OpenCL设备之间进行交互操作。现在主要的OpenCL平台有AMD、Nvida,Intel等。OpenCL使用了一种Installable Client Driver模型,这样不同厂商的平台就能够在系统中共存。在我的计算机上就安装有AMD和Intel两个OpenCL Platform[现在的OpenCL driver模型不允许不同厂商的GPU同时运行]。

AMD OpenCL 大学教程(2): OpenCL概述

OpenCL平台通常包括一个主机(Host)和多个OpenCL设备(device),每个OpenCL设备包括一个或多个CU(compute units),每个CU包括又一个或多个PE(process element)。 每个PE都有自己的程序计数器(PC)。主机就是OpenCL运行库宿主设备,在AMD和Nvida的OpenCL平台中,主机一般都指x86 CPU。

对AMD平台来说,所有的CPU是一个设备,CPU的每一个core就是一个CU,而每个GPU都是独立的设备。

AMD OpenCL 大学教程(2): OpenCL概述

3、OpenCL编程的一般步骤

下面我们通过一个实例来了解OpenCL编程的步骤,假设我们用的是AMD OpenCL平台(因为本人的GPU是HD5730),安装了AMD Stream SDK 2.6,并在VS2008中设置好了include,lib目录等。

首先我们建立一个控制台程序,最初的代码如下:

 1: #include "stdafx.h"
 2: #include 
 3: #include 
 4: #include 
 5: 
 6: #pragma comment (lib,"OpenCL.lib")
 7: 
 8: int main(int argc, char* argv[])
 9: {
 10: return 0;
 11: }

第一步,我们要选择一个OpenCL平台,所用的函数就是

AMD OpenCL 大学教程(2): OpenCL概述

通常,这个函数要调用2次,第一次得到系统中可使用的平台数目,然后为(Platform)平台对象分配空间,第二次调用就是查询所有的平台,选择自己需要的OpenCL平台。代码比较长,具体可以看下AMD Stream SDK 2.6中的TemplateC例子,里面描述如何构建一个robust的最小OpenCL程序。为了简化代码,使程序看起来不那么繁琐,我直接调用该函数,选取系统中的第一个OpenCL平台,我的系统中安装AMD和Intel两家的平台,第一个平台是AMD的。另外,我也没有增加错误检测之类的代码,但是增加了一个status的变量,通常如果函数执行正确,返回的值是0。

 1: #include "stdafx.h"
 2: #include 
 3: #include 
 4: #include 
 5: 
 6: #pragma comment (lib,"OpenCL.lib")
 7: 
 8: int main(int argc, char* argv[])
 9: {
 10: cl_uint status;
 11: cl_platform_id platform;
 12: 
 13: status = clGetPlatformIDs( 1, &platform, NULL );
 14: 
 15: return 0;
 16: }

第二步是得到OpenCL设备,

AMD OpenCL 大学教程(2): OpenCL概述

这个函数通常也是调用2次,第一次查询设备数量,第二次检索得到我们想要的设备。为了简化代码,我们直接指定GPU设备。

 1: #include "stdafx.h"
 2: #include 
 3: #include 
 4: #include 
 5: 
 6: #pragma comment (lib,"OpenCL.lib")
 7: 
 8: int main(int argc, char* argv[])
 9: {
 10: cl_uint status;
 11: cl_platform_id platform;
 12: 
 13: status = clGetPlatformIDs( 1, &platform, NULL );
 14: 
 15: cl_device_id device;
 16: 
 17: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,
 18: 1,
 19: &device,
 20: NULL);
 21: 
 22: return 0;
 23: }

下面我们来看下OpenCL中Context的概念:

通常,Context是指管理OpenCL对象和资源的上下文环境。为了管理OpenCL程序,下面的一些对象都要和Context关联起来:

Noiz Agent Noiz Agent

AI声音创作Agent平台

Noiz Agent 323 查看详情 Noiz Agent

—设备(Devices):执行Kernel程序对象。

—程序对象(Program objects): kernel程序源代码

—Kernels:运行在OpenCL设备上的函数。

—内存对象(Memory objects): device处理的数据对象。

—命令队列(Command queues): 设备之间的交互机制。

注意:创建一个Context的时候,我们必须把一个或多个设备和它关联起来。对于其它的OpenCL资源,它们创建时候,也要和Context关联起来,一般创建这些资源的OpenCL函数的输入参数中,都会有context。

AMD OpenCL 大学教程(2): OpenCL概述

AMD OpenCL 大学教程(2): OpenCL概述

这个函数中指定了和context关联的一个或多个设备对象,properties参数指定了使用的平台,如果为NULL,厂商选择的缺省值被使用,这个函数也提供了一个回调机制给用户提供错误报告。

现在的代码如下:

 1: #include "stdafx.h"
 2: #include 
 3: #include 
 4: #include 
 5: 
 6: #pragma comment (lib,"OpenCL.lib")
 7: 
 8: int main(int argc, char* argv[])
 9: {
 10: cl_uint status;
 11: cl_platform_id platform;
 12: 
 13: status = clGetPlatformIDs( 1, &platform, NULL );
 14: 
 15: cl_device_id device;
 16: 
 17: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,
 18: 1,
 19: &device,
 20: NULL);
 21: cl_context context = clCreateContext( NULL,
 22: 1,
 23: &device,
 24:                
 25: 
 26: return 0;
 27: }

接下来,我们要看下命令队列。在OpenCL中,命令队列就是主机的请求,在设备上执行的一种机制。

在Kernel执行前,我们一般要进行一些内存拷贝的工作,比如把主机内存中的数据传输到设备内存中。

另外要注意的几点就是:对于不同的设备,它们都有自己的独立的命令队列;命令队列中的命令(kernel函数)可能是同步的,也可能是异步的,它们的执行顺序可以是有序的,也可以是乱序的。

AMD OpenCL 大学教程(2): OpenCL概述

命令队列在device和context之间建立了一个连接。

命令队列properties指定以下内容:

是否乱序执行(在AMD GPU中,好像现在还不支持乱序执行) 是否启动profiling。Profiling通过事件机制来得到kernel执行时间等有用的信息,但它本身也会有一些开销。

如下图所示,命令队列把设备和context联系起来,尽管它们之间不是物理连接。AMD OpenCL 大学教程(2): OpenCL概述

添加命令队列后的代码如下:

 1: #include "stdafx.h"
 2: #include 
 3: #include 
 4: #include 
 5: 
 6: #pragma comment (lib,"OpenCL.lib")
 7: 
 8: int main(int argc, char* argv[])
 9: {
 10: cl_uint status;
 11: cl_platform_id platform;
 12: 
 13: status = clGetPlatformIDs( 1, &platform, NULL );
 14: 
 15: cl_device_id device;
 16: 
 17: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,
 18: 1,
 19: &device,
 20: NULL);
 21: cl_context context = clCreateContext( NULL,
 22: 1,
 23: &device,
 24: NULL, NULL, NULL);
 25: 
 26: cl_command_queue queue = clCreateCommandQueue( context,
 27: device,
 28: CL_QUEUE_PROFILING_ENABLE, NULL );
 29: 
 30: return 0;
 31: }

 原文作者:迈克老狼

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/895357.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
《鸣潮》莫特斐出装与队伍搭配方案推荐
上一篇 2025年11月28日 17:29:58
《爱普生Epson M188D驱动》安装步骤及适用系统介绍
下一篇 2025年11月28日 17:30:09

相关推荐

  • Go语言:检查预编译库的构建版本与平台信息

    本文详细介绍了如何利用go语言内置的`go tool pack`工具,从预编译的go静态库(`.a`文件)中提取其构建信息,包括go编译器版本、操作系统和cpu架构。当`go build`因库版本不匹配而失败时,此方法能帮助开发者准确诊断问题,确保构建环境与库的兼容性。 在Go语言的开发实践中,我们…

    2026年5月10日
    000
  • Go 版本升级后依赖编译错误解决方案

    本文旨在解决 Go 语言版本升级(如从 1.1.1 到 1.1.2)后,由于依赖包编译缓存导致的项目编译错误。我们将深入探讨错误原因,并提供包括 `go clean -i` 和 `go install -a` 在内的有效清理和重建策略,确保您的 Go 项目在升级后能顺利编译运行。同时,文章也将强调 …

    2026年5月10日
    000
  • Golang gRPC消息压缩与传输优化

    启用Gzip压缩、配置Keepalive长连接、采用流式传输可显著提升gRPC性能。在Go中通过grpc.RPCCompressor注册Gzip,客户端使用grpc.UseCompressor启用压缩;结合grpc.WithKeepaliveParams保持连接活跃,避免频繁重连;对大数据使用流式R…

    2026年5月10日
    000
  • C++怎么用Bazel构建大型项目_C++可复现、可扩展的构建系统Google Bazel入门

    答案:Bazel通过声明式BUILD文件实现C++项目的高效构建,1. 使用Bazelisk安装并初始化项目创建WORKSPACE文件 2. 编写cc_binary规则构建主程序 3. 用cc_library拆分模块并通过deps依赖实现复用 4. 配置远程缓存、沙箱和工具链提升性能与可复现性。 构…

    2026年5月10日
    000
  • c++怎么用Valgrind工具检测内存泄漏_c++ Valgrind内存泄漏检测方法

    使用Valgrind检测C++内存泄漏需编译时加-g生成调试信息,运行valgrind –leak-check=full ./program,查看输出中definitely lost确认泄漏位置并修复。 Valgrind 是 Linux 下非常强大的内存调试工具,能有效检测 C++ 程序…

    2026年5月10日
    000
  • Go语言中实现操作系统特定逻辑的最佳实践

    go语言通过文件命名约定(pkgname_osname.go)提供了一种优雅的机制,用于在编译时根据目标操作系统选择性地包含代码。这使得开发者能够在单个项目树中编写平台特定的功能,如处理系统启动项,有效避免了传统条件编译的复杂性,确保了代码的整洁与高效。 在开发跨平台应用程序时,我们经常会遇到需要与…

    2026年5月10日
    000
  • 解决 Ubuntu 中 Go 无法正常工作的问题

    本文旨在帮助开发者解决在 Ubuntu 系统中配置 Go 环境时遇到的常见问题,特别是当出现 “GOPATH set to GOROOT has no effect” 或 “cannot find package” 等错误时。通过分析错误原因,并提供详…

    2026年5月10日
    100
  • 关于CSS3中选择符的实例详解

    英文原文: www.456bereastreet.com/archive/200601/css_3_selectors_explained/中文翻译: www.dudo.org/article.asp?id=197注:本文写于2006年1月,当时IE7、IE8和Firefox3还未发行,文中所有说的…

    用户投稿 2026年5月10日
    100
  • CSS动画教程:手把手教你实现脉冲特效

    CSS动画教程:手把手教你实现脉冲特效,需要具体代码示例 引言:CSS动画是网页设计中常用的一种效果,它可以为网页增添活力和视觉吸引力。本篇文章将带您深入了解如何利用CSS实现脉冲特效,并提供具体的代码示例教您一步步完成。 一、了解脉冲特效脉冲特效是一种循环变化的动画效果,通常用在按钮、图标或其他元…

    2025年12月24日
    100
  • CSS动画教程:手把手教你实现流水流光特效

    CSS动画教程:手把手教你实现流水流光特效,需要具体代码示例 前言:CSS动画是网页设计中常用的技术,它使得网页更生动有趣,吸引用户的注意力。在这篇教程中,我们将会学习如何使用CSS实现一个流水流光的特效,并提供具体的代码示例。让我们开始吧! 第一步:HTML结构首先,我们需要创建一个基本的HTML…

    2025年12月24日
    000
  • word-wrap怎么自动换行?css强行自动换行教程

    本篇文章给大家带来的内容是关于word-wrap怎么自动换行?css强行自动换行教程,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 word-wrap介绍 word-wrap是设置对象内文字遇到对象顶边时是否采取换行排版布局。 1、语法 立即学习“前端免费学习笔记(深入)”; wo…

    2025年12月24日
    000
  • 用CSS实现网站变黑白色

    这篇文章主要介绍了关于用css实现网站变黑白色,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 以下为全站CSS代码.  html { filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1); } 使用方法:这段…

    用户投稿 2025年12月24日
    000
  • 详解css加载会造成阻塞吗_CSS教程_CSS_网页制作

    详解css加载会造成阻塞吗_CSS教程_CSS_网页制作详解css加载会造成阻塞吗_CSS教程_CSS_网页制作详解css加载会造成阻塞吗_CSS教程_CSS_网页制作详解css加载会造成阻塞吗_CSS教程_CSS_网页制作

    这次给大家带来详解css加载会造成阻塞吗,css加载造成阻塞的注意事项有哪些,下面就是实战案例,一起来看一下。 终于考试完了,今天突然想起来前阵子找实习的时候,今日头条面试官问我,js执行会阻塞DOM树的解析和渲染,那么css加载会阻塞DOM树的解析和渲染吗?所以,接下来我就来对css加载对DOM树…

    2025年12月24日 用户投稿
    100
  • 阐述什么是CSS3?

    网页制作Webjx文章简介:CSS3不是新事物,更不是只是围绕border-radius属性实现的圆角。它正耐心的坐在那里,已经准备好了首次登场,呷着咖啡,等着浏览器来铺上红地毯。            CSS3不是新事物,更不是只是围绕border-radius属性实现              …

    用户投稿 2025年12月23日
    100
  • CSS教程(三)伪类——动态链接

    伪类可以看做是一种特殊的类选择符,是能被支持css的浏览器自动所识别的特殊选择符。它的最大的用处就是可以对链接在不同状态下定义不同的样式效果。 1.  语法 伪类的语法是在原有的语法里加上一个伪类(pseudo-class):selector:pseudo-class {property: valu…

    2025年12月23日
    000
  • CSS教程(四)如何在网页中插入CSS

    前两章我们了解了css的语法,但要想在浏览器中显示出效果,就要让浏览器识别并调用。当浏览器读取样式表时,要依照文本格式来读,这里介绍四种在页面中插入样式表的方法:链入外部样式表、内部样式表、导入外表样式表和内嵌样式。   链入外部样式表 链入外部样式表是把样式表保存为一个样式表文件,然后在页面中?l…

    2025年12月23日
    200
  • CSS教程(五)如何使用DW4创建CSS

    1. css styles面板 通过前面几章的学习,相信大家对css有了一定的了解,这一章我们来讲解如何利用dreamweaver4来创建css。首先运行dreamweaver4,启动后,选择菜单下的windows->css styles(或按shitf+f11),系统弹出css styles…

    2025年12月23日
    000
  • CSS教程(六) DW4中CSS属性详解

    在dreamweaver4的css样式里包含了w3c规范定义的所有css1的属性,dreamweaver4把这些属性分为type(类型)、background(背景)、block(块)、box(盒子)、border(边框)、 list(列表)、positioning(定位)、extensions(扩…

    2025年12月23日
    000
  • CSS教程(七) 滤镜

    css提供了一些内置的多媒体滤镜特效,使用这种技术可以把可视化的滤镜和转换效果添加到一个标准的html元素上,例如图片、文本容器、以及其他一些对象。dreamweaver4提供了16种滤镜可供选择,如下图: 下面,我们就来看看在dreamweaver4里如何方便的使用这些css滤镜。 建立一个自定义…

    2025年12月23日
    000
  • CSS教程(八) 简单介绍CSS结合JS的运用

    八、 简单介绍css结合js的运用(针对事件动作) 利用css配合javascript的可以做很多更酷的动态页面效果,在本教程的最后给大家简单介绍一下css配合js的应用。首先,我们要搞清楚事件和动作的概念。在客户端脚本中,javascript 通过对事件进行响应来获得与用户的交互。例如,当用户单击…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信