Intel OpenCL 之 Pipeline(二)For循环的执行机制
嵌套for循环的pipeline机制
看下面的例子:
#define k_size 20
#define size 4
kernel void accum_swg (global int* a
,global int* c)
{
int sum[1024];
loop1: for (int k = 0; k < k_size; ++k) {
loop1_1: for (int i = 0; i < size; ++i) {
int j = k * size + i;
sum[k] += a[j];
}
}
loop2: for (int k = 0; k < k_size; ++k) {
c[k] = sum[k];
}
}
这个例子中,loop1
、loop1_1
、loop2
都能很好的pipeline。
内层循环
蓝色框表示内层循环体loop1_1
;L表示Latency
;一个粉色块表示一次迭代;这里启动了四次迭代(size=4)。
可以看到,第0次迭代已经要输出结果了,而第3次迭代则刚刚启动,第2和第1次迭代处于中间态。如果size大于4,那么,到下一个cycle时,1将输出,4将进入,而3和2将变成中间态。
pipeline-21
嵌套循环
把loop1
和loop1_1
一起考虑,执行过程如下图所示:
pipeline-32
可以看到,内层循环pipeline中间没有任何气泡,外层循环其实是在可以做插入的地方做内插,只要内层循环II为1且没有气泡,外层循环即使II值不恒为1,也能保证稳定态时每个时钟周期输出一个结果。
但当 Trip_count_inner_loop * II_inner_loop < II_outer_loop
时,就不能不考虑外层循环的II
了。
现在,我们来算一下执行loop1
和loop1_1
的总时钟周期数:
k_size * (size * II_inner_loop)+Latency_inner_loop + Latency_outer_loop
要注意的是,嵌套循环中内层循环是critical loop
,我们要首先保证的就是内层循环的性能,但当遇到下面这种情况时,哪个才是critical loop
呢?
for(unsigned i=0; i<N; i++){
for(unsigned j=0; j<M; j++){
...
}
for(unsigned j=0; j<P; j++){
...
}
}
这时候要比较M和P的大小,大的为 critical loop,而另一个loop的II值可以适当放宽要求(在 P * II_inner_loop_P < M
条件下)。
并列for循环的执行机制
如下图所示,并列的两个for循环如例子中的loop1, loop1_1
和loop2
,只能串行执行,等一个结束后下一个才开始。
pipeline-33
如果一个for循环内部嵌套着两个并列的for循环:
kernel void test(){
while(i<N){
...
for(j=0; j<M; j++){
...
}
for(j=0; j<P; j++){
...
}
}
}
首先要根据N
和P
的大小来确定哪个是critical loop
,内层两个循环串行执行,外层循环在可以做内插的地方做内插。
pipeline-34
参考
Intel FPGA SDK for OpenCL Best Practices Guide
- PHP数据结构(十) ——有向无环图与拓扑算法
- PHP数据结构(十一) ——图的连通性问题与最小生成树算法(1)
- 优化 MySQL: 3 个简单的小调整
- PHP数据结构(十一) ——图的连通性问题与最小生成树算法(2)
- 进程间通信的历史与未来
- PHP数据结构(十二) ——静态查找表
- 小程序中滚动条的使用,wx.pageScrollTo和<scroll-view>的对比
- 小程序中tabBar的使用
- ubuntu配置虚拟内存
- PHP数据结构(十三) ——动态查找表(二叉排序树)
- Ubuntu下配置JavaWeb开发环境
- 小程序中picker的使用|日期、时间、省市区联动都可以用它实现
- swiper组件添加左右箭头
- php日常使用总结
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python爬虫以及后端开发--实用加密模板整理
- APP脱壳方法三
- Flink Checkpoint 原理流程以及常见失败原因分析
- Docker原理之 - OverlayFS设计与实现
- 有赞零售跨平台打印库方案
- [Go] Golang练习项目-GO语言实现快速排序-第一个数作为基准更容易理解
- 有赞移动基础设施建设的实践和思考
- 大数据理论篇HDFS的基石——Google File System
- 6. 二十不惑,ObjectMapper使用也不再迷惑
- 接口自动化对比工具实践
- 什么?Java9这些史诗级更新你都不知道?Java9特性一文打尽!
- 利用 Arthas 精准定位 Java 应用 CPU 负载过高问题
- 你想了解的JDK 10版本更新都在这里
- Linux Page Cache调优在 Kafka 中的应用
- 声明式 UIKit 在有赞美业的实践