多线程
多线程的相关信息可根据我的另一个blog查看。
多线程处理提速方式
将像素width*height
分隔为多份,每一份交给一个线程处理。
分隔方式有:
- 网格分隔(代码中使用了这种分隔方式)
- 条形分隔(每一列 或 每一行 为一个线程,更利于编程)
线程代码
- 输入为线程需要操作的像素区间。
x∈[min_x,max_x],y∈[min_y,max_y]
。 - 对于网状分隔方式,m横线移动时,数值是连续的,故只需要在纵向移动时初始化m的值。
std::lock_guard<std::mutex> lock(mutex_ins);
为锁管理器
锁管理器:
多个线程访问外部同一个变量并对该变量进行修改时,可能会因为混乱的修改代码的先后顺序导致修改的变量不符合预期。这时候需要锁管理器,使得每一个线程中的修改代码执行完毕后再去执行其他线程的内容。
对于该线程框架:
framebuffer[m]
为每一个像素的值,而每一个线程有独立计算的像素,相互之间互不影响,故不需要考虑代码运行的先后顺序。process
为外部变量,是每一个线程都要修改的公共变量,因为其修改代码只有一句++process
(在汇编中只是一条指令,process++
也只是两条指令),因此不使用锁管理器可能也不会造成数据混乱。(建议使用锁管理器)UpdateProgress((float)process / scene.height / y_block);
为更新进程函数,因为进程信息的显示不能混乱,如果混乱就会…看下面的图。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25auto castRayMultiThread = [&](int min_x,int min_y,int max_x,int max_y) { for (uint32_t j = min_y; j < max_y; ++j) { int m = j *scene.width + min_x; for (uint32_t i = min_x; i < max_x; ++i) { // generate primary ray direction float x = (2 * (i + 0.5) / (float)scene.width - 1) * imageAspectRatio * scale; float y = (1 - 2 * (j + 0.5) / (float)scene.height) * scale; Vector3f dir = normalize(Vector3f(-x, y, 1)); for (int k = 0; k < spp; k++) { framebuffer[m] += scene.castRay(Ray(eye_pos, dir), 0) / spp; } m++; } { std::lock_guard<std::mutex> lock(mutex_ins); ++process; UpdateProgress((float)process / scene.height / y_block); } } };
分隔、启动线程
要确保分隔的线程中像素点不会有重叠,且不会遗漏像素点或越界。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//分块为5*5个处理单元 const int x_block = 5; const int y_block = 5; std::thread th[x_block * y_block]; //步距计算,步距多加1,保证无论像素有多少,所有像素都可被包含在块中 int strideX = scene.width / x_block + 1; int strideY = scene.height / y_block + 1; 线程lamada表达式 // 分块计算光线追踪 int id = 0; for (int i = 0; i < y_block; i++){//height for (int j = 0; j < x_block; j++){//width th[id] = std::thread(castRayMultiThread, j* strideX, i* strideY, std::min((j+1)* strideY, scene.width), std::min((i+1) * strideY, scene.height)); id++; } } for (int i = 0; i < x_block * y_block; i++) th[i].join(); UpdateProgress(1.f);
提速效果
spp16-----由先前的6分钟提速为30秒左右。
最后
以上就是自觉电灯胆最近收集整理的关于Games101,作业7(多线程提速)多线程多线程处理提速方式线程代码分隔、启动线程提速效果的全部内容,更多相关Games101内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复