我是靠谱客的博主 自觉电灯胆,最近开发中收集的这篇文章主要介绍Games101,作业7(多线程提速)多线程多线程处理提速方式线程代码分隔、启动线程提速效果,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
多线程
多线程的相关信息可根据我的另一个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);
为更新进程函数,因为进程信息的显示不能混乱,如果混乱就会…看下面的图。
auto 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);
}
}
};
分隔、启动线程
要确保分隔的线程中像素点不会有重叠,且不会遗漏像素点或越界。
//分块为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,作业7(多线程提速)多线程多线程处理提速方式线程代码分隔、启动线程提速效果所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复