Brook+ Programming (4)
(接上篇)
由main函数开始,生成三个流接受输入矩阵(A和B)和输出矩阵(流一般用来表示矩阵)。然后三块内存缓冲区开辟出来(input_A,input_B和
input_C)接着streamRead()函数将数据从input_A复制到流A,input_B到流B。
simple_matmult( (float) Width, A, B, C) 这一行将Width、输入流A、B和输出流C等参数传递给kernel函数,同时也触发了kernel函数在流处理器上的执行。在简单的矩阵乘法操作中,kernel函数从一个矩阵读入一行向量,从另一个矩阵读入一列向量,将二者点乘写入结果。在上面的例子中,kernel函数遍历输出流的每个数据的位置。总结如下:
1.循环遍历矩阵A的行;
2.循环遍历矩阵B的列;
3.每次从每个矩阵取出一个值;
4.乘法运算得到结果
这里kernel利用了一个特性就是向量数据类型(float2和float4)。Brook+支持最多四个元素的数据类型。(注:即最多四个分量的向量)元素可以通过任何结合方式被访问。这也就是所谓的混合(swizzling)。
这里kernel的输入流和前面的sum kernel的流稍有不同。这里,流是用方括号的,表示输入流被当作内存数组并且可以直接对数据元素寻址。这就是所谓的“聚集流”。kernel代码和C代码之间的一个重要不同就是聚集流只能用向量类来寻址,而不是多个方括号(注:像数组那样)。
例如:A[x][y]是不允许的。
为了确定kernel该访问输出的哪一行/列,输出(注:指每次算得的输出矩阵中的一个值)的位置必须要确定。这是通过indexof()函数实现的,它返回一个整数表示输出域中的位置。
在while循环中,从矩阵A中的列和矩阵B中的值相乘(注:疑此处有误,AxB应该是A的行和B的列相乘),accumulator变量是乘积的结果。
和前面的sum例子一样,结果是不用方括号的。Brook+自动将结果写回正确的位置,也就是indexof()在输出流中的位置。
2.3.2Optimized Matrix Multiply Example
(注:更完善的矩阵乘法例子)
上面的kernel的一个缺点是:同样的数据在不同的地方被重用。例如:相邻的两个输出位置上,kernel使用了相同的行向量或是列向量。一般而言,从内存读取数据的开销大于从流处理器中读取。一个更完美的方法是在kernel中执行更多计算,这样读取操作就可以减少。下面是完善的矩阵乘法的代码:
kernel void
optimized_matmult(int loopVar0,
float4 A1[][], float4 A2[][], float4 A3[][], float4 A4[][],
float4 A5[][], float4 A6[][], float4 A7[][], float4 A8[][],
float4 B1[][], float4 B2[][], float4 B3[][], float4 B4[][],
out float4 C1<>, out float4 C2<>, out float4 C3<>, out float4 C4<>,
out float4 C5<>, out float4 C6<>, out float4 C7<>, out float4 C8<>)
{
// Setting zero
float4 zero = float4(0.0f, 0.0f, 0.0f, 0.0f);
// Declaring and initializing accumulators
float4 accumulator1 = zero;
float4 accumulator2 = zero;
float4 accumulator3 = zero;
float4 accumulator4 = zero;
float4 accumulator5 = zero;
float4 accumulator6 = zero;
float4 accumulator7 = zero;
float4 accumulator8 = zero;
// Row number of output position
int i = instance().y;
// Column number of output position
int j = instance().x;
int k = 0;
for(; k < loopVar0; ++k)
{
// Fetching values from A
float4 A11 = A1[i][k]; float4 A22 = A2[i][k];
float4 A33 = A3[i][k]; float4 A44 = A4[i][k];
float4 A55 = A5[i][k]; float4 A66 = A6[i][k];
float4 A77 = A7[i][k]; float4 A88 = A8[i][k];
// Fetching values from B
float4 B11 = B1[k][j]; float4 B22 = B2[k][j];
float4 B33 = B3[k][j]; float4 B44 = B4[k][j];
accumulator1 += A11.xxxx * B11.xyzw + A11.yyyy * B22.xyzw + A11.zzzz * B33.xyzw + A11.wwww * B44.xyzw;
accumulator2 += A22.xxxx * B11.xyzw + A22.yyyy * B22.xyzw + A22.zzzz * B33.xyzw + A22.wwww * B44.xyzw;
accumulator3 += A33.xxxx * B11.xyzw + A33.yyyy * B22.xyzw + A33.zzzz * B33.xyzw + A33.wwww * B44.xyzw;
accumulator4 += A44.xxxx * B11.xyzw + A44.yyyy * B22.xyzw + A44.zzzz * B33.xyzw + A44.wwww * B44.xyzw;
accumulator5 += A55.xxxx * B11.xyzw + A55.yyyy * B22.xyzw + A55.zzzz * B33.xyzw + A55.wwww * B44.xyzw;
accumulator6 += A66.xxxx * B11.xyzw + A66.yyyy * B22.xyzw + A66.zzzz * B33.xyzw + A66.wwww * B44.xyzw;
accumulator7 += A77.xxxx * B11.xyzw + A77.yyyy * B22.xyzw + A77.zzzz * B33.xyzw + A77.wwww * B44.xyzw;
accumulator8 += A88.xxxx * B11.xyzw + A88.yyyy * B22.xyzw + A88.zzzz * B33.xyzw + A88.wwww * B44.xyzw;
}
C1 = accumulator1;
C2 = accumulator2;
C3 = accumulator3;
C4 = accumulator4;
C5 = accumulator5;
C6 = accumulator6;
C7 = accumulator7;
C8 = accumulator8;
}
Brook+ Programming (4)相关推荐
- Brook+ Programming
翻译自AMD文档 2.1Runtime Options 在运行Brook+程序之前,需要注意一下环境变量: BRT_RUNTIME 这个环境变量允许你决定计算的后端是CPU(可以方便地调试)还是CAL ...
- Brook+ Programming (2)
(接上一篇) 2.2.2 Building 使用如下步骤生成: 第一步: 用brcc编译 编译器可以在<BROOKROOT>/sdk/bin/下找到 brcc [-hkrbfilxae ...
- Brook+ Programming (6)
2.6 The Brook+ Runtiem API 现在版本的Brook+的特性都是完全改写了runtime引擎后的.为了提高性能和稳定性,新的C++ API提供给开发者以便能在低层用更有弹性的方式 ...
- Brook+ Programming (1)
(接上一篇文章) Brook+的代码和C/C++的很像,但要注意以下几点: 第一,brcc像C编译器一样工作,也就是说编程要坚持标准C规范(例如:变量在代码段前声明). 对于更复杂的应用,要小心地区分 ...
- docker报错:driver failed programming external connectivity on endpoint, iptables:No chain by that name
docker 报错: Error response from daemon: Cannot restart container hello: driver failed programming ext ...
- Java OOP(Object Oriented Programming)个人理解及总结
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计) 其三大特征:封装,继承,多态: 封装:解决数据的安全问题. 继承:解决代码的重用问题. 多态:解决程序 ...
- Structured Streaming编程 Programming Guide
Structured Streaming编程 Programming Guide • Overview • Quick Example • Programming Model o Basic Conc ...
- 算法编程Algos Programming
算法编程Algos Programming 不同算法的集合,用于编程比赛,如ACM ICPC. 算法按主题划分.大多数算法都可以从文件中按原样运行.每种算法都有一个参考问题,并对其时间和空间复杂度作了 ...
- CSE 3100 Systems Programming
代做CSE 3100留学生作业.代写C/C++程序作业.代做Systems Programming作业.代写C/C++编程设计作业 CSE 3100 Systems Programming Homew ...
最新文章
- CQRS体系结构模式实践案例:Tiny Library:领域仓储与事件存储
- 搜索引擎Solr系列(二): Solr6.2.1 从MySql中导入数据
- Highly Available (Mirrored) Queues
- 个人信息安全影响评估指南_发布 | 网络安全标准实践指南—移动互联网应用程序(App)收集使用个人信息自评估指南...
- P1943-LocalMaxima_NOI导刊2009提高(1)【数论】
- Hibernate应用程序级可重复读取
- Linux:十条为系统管理员节省时间的命令
- python程序打包成安卓app教程_Python zipapp打包教程(超级详细)
- opencv视频播放
- 文件被后台程序占用无法删除_群晖NAS教程第十五节:查询群晖NAS硬盘空间占用情况,解决删除文件空间不增加问题...
- 再回首Java第二十二天
- 故障树最小割集程序化设计方案
- 工作效率低如何解决?
- Seaborn 绘图中设置字体及大小
- gloox1.0使用Emai格式的账号登录
- 弧度制和角度制的换算
- code review流程规范。
- 我在用的翻译软件 - 微软翻译+网易有道词典+谷歌翻译
- matlab-行相加、列相加
- 今天来聊一聊互联网35岁梗,这个行业真的不需要35岁以上从业人员?
热门文章
- 2021年黄岩中学高考成绩查询,2021台州中考分数线预测
- css marquee属性,css之marquee,让你的文字跳起来
- Big Endian 和 Little Endian 模式的区别
- win10系统提示 “你的账户已被停用,请向系统管理员咨询” 如何解决 ?
- Android安全输入设计与思考
- SQL Server 语句大全(3)-------常用函数
- 全景拍照返回键无保存
- Jetson Xavier、Jetson TX2、 1080(Ti)、2080显卡运行深度学习模型性能对比(英伟达开发平台VS常用显卡)
- Linux一句话精彩问答--2008/11/02更新--20071212pdf版本下载
- 前端裁切图片插件之cropper介绍