参考:http://blog.youkuaiyun.com/canhui_wang/article/details/52919318
loop unrolling 不同于内存优化(hardware accessing),这是一种指令级优化(software programming)。如果说编程上For循环是一种以计算性能的打折作为代价来实现编程的简单化的编程思路,那么Loop unrolling将是一种以编程复杂为代价来提升并行代码性能的高级的编程方式;更进一步地,For循环可以看成是loop unrolling零优化的状态;所以,计算性能loop unrolling严格优于或至少等于For语句——这是CPU,GPU的硬件的系统结构所致。
举例分析如下:
loop_unrolling.cpp
#include <iostream>
#include <windows.h>
#pragma comment(lib, "Winmm.lib") //timeGetTime()
using namespace std;
int main()
{
int N = 10000000;
DWORD start, end1,end2;
start = timeGetTime();
int *a = (int*)malloc(sizeof(int) * N);
//传统实现
for (int i = 0; i < N; i++) {
a[i] = i*2;
}
end1 = timeGetTime();
cout <<"传统实现时间:"<< (end1 - start) << " ms" << endl;
//指令并行化
for (int i = 0; i < N; i = i + 2) {
a[i] = i * 2;
a[i + 1] = (i + 1) * 2;
}
end2 = timeGetTime();
cout << "指令并行化实现时间:"<< (end2 - end1) << " ms" << endl;
return 0;
}
运行结果:
Unrolling Loop可以进一步抽象出“并行粒度”的概念,比如,例子一中一个线程处理一个指令(任务轻),例子二中一个线程处理两个指令(任务重);另一方面,就CUDA而言,例子一需要的blocks数目少,例子二需要的blocks数目多。因为总体的性能是由线程执行时间与blocks数目决定的(线程计算能力范围内任务轻重耗时相近,计算能力外任务重耗时大;并行blocks能力范围内(比如NVIDIA GTX780Ti一次可并行192blcoks)blcoks的数目多数目少二者耗时相近),能力范围外,blocks数多点调度数目多点,耗时长点————总而言之,这是一个tradeoff问题,我们做的就是寻找一种策略在blocks块数目与线程处理时间之间的处理平衡,达到性能最大优化。