Intel说larrabee要以软件平台的形式发布了,至于实体…等吧。
Nvidia和ATI又可以小爽一段了。
话说现在竞争白热,局势却相对明朗了:Nvidia狂推自己的CUDA,AMD和IBM等一干人紧紧抱着Opencl,Intel自己没搞出来东西,又不甘落后,就自己再搞一套软件平台来搅浑水,Microsoft肯定是不屑跟他们这些人玩了,肯定要抱着自己的DX Compute闷头折腾了。
我们这些下游就得屁颠跟着他们晕了。
新闻Link
Intel说larrabee要以软件平台的形式发布了,至于实体…等吧。
Nvidia和ATI又可以小爽一段了。
话说现在竞争白热,局势却相对明朗了:Nvidia狂推自己的CUDA,AMD和IBM等一干人紧紧抱着Opencl,Intel自己没搞出来东西,又不甘落后,就自己再搞一套软件平台来搅浑水,Microsoft肯定是不屑跟他们这些人玩了,肯定要抱着自己的DX Compute闷头折腾了。
我们这些下游就得屁颠跟着他们晕了。
新闻Link
图像分割的定义是将整幅图像区域分割成各自互不交叉的小区域。图像分割的算法有很多,教科书上讲到一些经典的分割算法,包括阈值法、区域生长法、分裂与合并算法、边界跟踪与连接算法、分水岭算法,这些算法适合提取出灰度比较一致的各个区域;此外还有纹理分割算法,严格说来,与其称之为纹理分割还不如称之为纹理检测与分类,通过提取纹理特征,如:Laws特征、梯度共生矩阵特征、分形特征,得到每一个点或小邻域的特征向量,然后利用特征向量将每个点分到不同的纹理类中去。
有些扯远了,还是回到三维图像分割上来,由于三维图像的数据量是巨大的,暂不考虑复杂的纹理特征,我们仅仅希望有在GPU上实现一种并行的快速算法,能够自动标记出三维数据中所有灰度比较一致的各个连通区域。我们先看看教科书上的方法,阈值法不能提取多个灰度不一致的区域,区域生长不容易做到每个区域种子点自动选取,分裂与合并的逻辑稍显复杂且分割的区域边缘会出现锯齿,边界跟踪与连接在三维上根本没办法实现,分水岭又是串行递归的-_-!!!
假设已经是有了一幅二值图,我们就可以用连通区标记的算法,为二值图中的每一个小的区域标上不同的标号,这就是常用的二值图CCL(Connected Component Labeling)算法,可以扫描填充法、FloodFill等方式来具体实现这个算法。算法的原理是,判断当前点的邻域内有没有和当前点取值相同的点,如果有,就把他们标记为相同的标号。利用这个思想,如果在判断的时候,不是判断当前点的邻域内有没有和当前点取值相同的点,而是判断当前点的邻域内有没有和当前点取值相近的点——有点类似于梯度区域生长算法,就可以设计出适用于灰度图像的灰度连通区标记算法灰度图CCL算法,如果对每一个点进行如上判断,就可以预先生成一幅具有二值图,且对每个点的判断不依赖于其它点判断的结果,可以做到完全并行。这一段代码很简单,假设体数据已经做了去噪处理,然后用For循环遍历每一个点就能搞定(对于Cuda实现,就是把最里层的内容写到kernel里面),贴代码:
阅读这个条目剩下部分 »
AMD和Sisoft联合在Sisoft的Sandra 2010里面添加了opencl benchmark。支持的硬件有:
大致是对带宽的测试和计算性能的测试,结果:
GPU结果
CPU结果
比较诡异的是,amd的显卡是5870 ,NVidia的显卡竟然选用的是9500,这个…有点太…
Memory分类和访问(Memory Layout and Access)
opencl将存储模型分为三种:Private Memory,Local Memory,Constant Memory和Global Memory。其中Private Memory只可以被work-item使用,也就是单个work-item私有的;Local Memory可以被同一个work-group内的work-item所使用;Global Memory可以被所有的work-item访问和修改;而Constant Memory是Global Memory的一种,区别在于它是不能被更改的。示意图如下[1]:
大致了解了opencl中存储类型后,就会发现opencl的memory model和cuda的极为类似,ok,这里就简单的列出opencl中集中memory类型在Nvidia的GPU、AMD的GPU和CPU中实际对应的数据类型:
| Opencl | Nvidia CUDA | ATI GPU | AMD CPU |
|---|---|---|---|
| Global Memory | Global Memory | global buffer (g[] in CAL/IL) | 系统内存(RAM) |
| Local Memory | Shared Memory | Local Data Share | CPU L1缓存 |
| Private Memory | Register | scratch memory (x[] in CAL/IL) | 系统内存RAM |
update@2009.11.30
Opencl中还有一种存储类型:Image,也就是cuda中的纹理内存,包含2D和3D image。与CUDA中纹理一样提供不同的插值(采样)方式,同时也提供一定cache(硬件支持的),个人感觉,这是一个GPU的遗留产物,在CPU和DSP等的Opencl实现极有可能不提供对其的支持。所以要注意在使用时,最好先查询一下是否支持。
如何使用(How to use these memory)
to be continued…
坑,又少了一个。原文
update:好像是说停止了相关sdk的开发,转向了opencl,这点和前几天从amd那边得到的消息一致。
1. 下载 CUDA 文件
从 Nvidia CUDA 官方网站( http://www.nvidia.com/object/cuda_home.html )的下载页面可以找到适用于 ubuntu 9.04 的 CUDA 文件,包括:
* NVIDIA Driver 190.18 Beta for Linux (Ubuntu 9.04) with CUDA Support
* CUDA Toolkit 2.3 for Linux (Ubuntu 9.04)
* CUDA SDK 2.3 code samples for Linux (Ubuntu 9.04) 阅读这个条目剩下部分 »
我们已经写好的Kernel函数一般保存在一个字符串内,例如在第二节中的kernel:输入两个一维数组,用另外一个一维数组输出两个一维数组求和的结果,如下:
char* chKernelSource = "__kernel sum (__global const float* a, __global const float* b, __global float* answer) { int xid = get_global_id(0); answer[xid] = a[xid] + b[xid]; }";
如概述中所言,下面我们一步一步来写Host代码Main函数部分;
阅读这个条目剩下部分 »
1、计算设备(Compute Device). 是指系统中支持OpenCL的各类处理器,可以是CPU, GPU,甚至是DSP。一个系统中可以有多个Device连接到主机(Host)上。另外,每个device中会包含多个计算单元(Compute Unit),例如多核的CPU或者GPU中的多处理器(Multi-Processor). 而每个计算单元中还可以包含多个处理单位(PE, Processing Element). CPU中每个计算单元只含有一个PE, 而GPU中则含有多个。我们可以通过clGetDeviceIDs()这个函数来检查系统中是否有支持OpenCL的设备,并且配合clGetDeviceInfo()函数来了解该设备中如设备类型、计算单元个数等信息。
2、执行(Execution)
最终在Device上执行的代码成为内核(Kernel),这类代码是C语言的扩展,像下面这样子:
__kernel sum(__global const float* a, __global const float* b, __global float* answer) { int xid = get_global_id(0); answer[xid] = a[xid] + b[xid]; }
除了DirectX SDK里提供的几个写好函数外,最近一直再找Direct Compute的C++代码实现,这意味着随心所欲写自己的算法了。网上资源不多,搜到一个,分享一下:
The CUDA Toolkit 3.0 Beta is now available to GPU Computing registered
developers