Parallel processing 如何与OpenMP并行?
我想并行化包含两个for循环的OpenMP光线跟踪算法 除了设置Parallel processing 如何与OpenMP并行?,parallel-processing,openmp,Parallel Processing,Openmp,我想并行化包含两个for循环的OpenMP光线跟踪算法 除了设置omp\u set\u num\u线程(omp\u get\u max\u threads())并将\pragma omp parallel for放在第一个for循环前面,我还能做什么 到目前为止,我已经实现了一个2.13倍快的算法 代码: start = omp_get_wtime(); #pragma omp parallel for for (int i = 0; i < (viewport.xvmax - view
omp\u set\u num\u线程(omp\u get\u max\u threads())
并将\pragma omp parallel for
放在第一个for循环前面,我还能做什么
到目前为止,我已经实现了一个2.13倍快的算法
代码:
start = omp_get_wtime();
#pragma omp parallel for
for (int i = 0; i < (viewport.xvmax - viewport.xvmin); i++)
{
for (int j = 0; j < (viewport.yvmax - viewport.yvmin); j++)
{
int intersection_object = -1; // none
int reflected_intersection_object = -1; // none
double current_lambda = 0x7fefffffffffffff; // maximum positive double
double current_reflected_lambda = 0x7fefffffffffffff; // maximum positive double
RAY ray, shadow_ray, reflected_ray;
PIXEL pixel;
SPHERE_INTERSECTION intersection, current_intersection, shadow_ray_intersection, reflected_ray_intersection, current_reflected_intersection;
double red, green, blue;
double theta, reflected_theta;
bool bShadow = false;
pixel.i = i;
pixel.j = j;
// 1. compute ray:
compute_ray(&ray, &view_point, &viewport, &pixel, &camera_frame, focal_distance);
// 2. check if ray hits an object:
for (int k = 0; k < NSPHERES; k++)
{
if (sphere_intersection(&ray, &sphere[k], &intersection))
{
// there is an intersection between ray and object
// 1. Izracunanaj normalu...
intersection_normal(&sphere[k], &intersection, &ray);
// 2. ako je lambda presjecista manji od trenutacnog:
if (intersection.lambda_in < current_lambda)
{
current_lambda = intersection.lambda_in;
intersection_object = k;
copy_intersection_struct(¤t_intersection, &intersection);
}
// izracunaj current lambda current_lambda =
// oznaci koji je trenutacni object : intersection_object =
// kopiraj strukturu presjeka : copy_intersection_struct();
}
}
// Compute the color of the pixel:
if (intersection_object > -1)
{
compute_shadow_ray(&shadow_ray, &intersection, &light);
theta = dotproduct(&(shadow_ray.direction), &(intersection.normal));
for (int l = 0; l<NSPHERES; l++)
{
if (l != intersection_object)
{
if (sphere_intersection(&shadow_ray, &sphere[l], &shadow_ray_intersection) && (theta>0.0))
bShadow = true;
}
}
if (bShadow)
{ // if in shadow, add only ambiental light to the surface color
red = shadow(sphere[intersection_object].ka_rgb[CRED], ambi_light_intensity);
green = shadow(sphere[intersection_object].ka_rgb[CGREEN], ambi_light_intensity);
blue = shadow(sphere[intersection_object].ka_rgb[CBLUE], ambi_light_intensity);
}
else
{
// the intersection is not in shadow:
red = blinnphong_shading(¤t_intersection, &light, &view_point,
sphere[intersection_object].kd_rgb[CRED], sphere[intersection_object].ks_rgb[CRED], sphere[intersection_object].ka_rgb[CRED], sphere[intersection_object].shininess,
light_intensity, ambi_light_intensity);
green = blinnphong_shading(¤t_intersection, &light, &view_point,
sphere[intersection_object].kd_rgb[CGREEN], sphere[intersection_object].ks_rgb[CGREEN], sphere[intersection_object].ka_rgb[CGREEN], sphere[intersection_object].shininess,
light_intensity, ambi_light_intensity);
blue = blinnphong_shading(¤t_intersection, &light, &view_point,
sphere[intersection_object].kd_rgb[CBLUE], sphere[intersection_object].ks_rgb[CBLUE], sphere[intersection_object].ka_rgb[CBLUE], sphere[intersection_object].shininess,
light_intensity, ambi_light_intensity);
}
tabelaPixlov[i][j].red = red;
tabelaPixlov[i][j].green = green;
tabelaPixlov[i][j].blue = blue;
glColor3f(tabelaPixlov[i][j].red, tabelaPixlov[i][j].green, tabelaPixlov[i][j].blue);
intersection_object = -1;
bShadow = false;
}
else
{
// draw the pixel with the background color
tabelaPixlov[i][j].red = 0;
tabelaPixlov[i][j].green = 0;
tabelaPixlov[i][j].blue = 0;
intersection_object = -1;
bShadow = false;
}
current_lambda = 0x7fefffffffffffff;
current_reflected_lambda = 0x7fefffffffffffff;
}
}
//glFlush();
stop = omp_get_wtime();
for (int i = 0; i < (viewport.xvmax - viewport.xvmin); i++)
{
for (int j = 0; j < (viewport.yvmax - viewport.yvmin); j++)
{
glColor3f(tabelaPixlov[i][j].red, tabelaPixlov[i][j].green, tabelaPixlov[i][j].blue);
glBegin(GL_POINTS);
glVertex2i(i, j);
glEnd();
}
}
printf("%f\n št niti:%d\n", stop - start, omp_get_max_threads());
glutSwapBuffers();
}
start=omp_get_wtime();
#pragma-omp并行
对于(int i=0;i<(viewport.xvmax-viewport.xvmin);i++)
{
对于(int j=0;j<(viewport.yvmax-viewport.yvmin);j++)
{
int intersection_object=-1;//无
int\u交叉点\u对象=-1;//无
双电流\u lambda=0x7fefffffffffffff;//最大正双
双电流\u反射\u lambda=0x7fefffffffffffffff;//最大正双
射线、阴影射线、反射射线;
像素;
球体相交、当前相交、阴影相交、反射相交、反射相交、当前相交;
重瓣的红色,绿色,蓝色;
双θ,反射θ;
bool-bShadow=false;
像素i=i;
像素j=j;
//1.计算光线:
计算光线(光线、视点、视口、像素、相机帧、焦距);
//2.检查光线是否击中对象:
for(int k=0;k-1)
{
计算阴影光线(阴影光线、交点和灯光);
θ=点积(&(阴影光线方向),&(交点法线));
对于(int l=0;l0.0))
b阴影=真;
}
}
如果(b阴影)
{//如果处于阴影中,则仅向曲面颜色添加环境光
红色=阴影(球体[相交对象].ka\u rgb[CRED],环境光强度);
绿色=阴影(球体[相交对象]、ka_rgb[绿色]、环境光强度);
蓝色=阴影(球体[相交对象].ka\u rgb[CBLUE],环境光强度);
}
其他的
{
//交叉点不在阴影中:
红色=blinnphong_明暗处理(¤t_交叉点,&light,&view_点),
球体[Crossion_object].kd_rgb[CRED],球体[Crossion_object].ks_rgb[CRED],球体[Crossion_object].ka_rgb[CRED],球体[Crossion_object].Shiness,
光照强度、环境光照强度);
绿色=blinnphong_明暗处理(&当前_交叉点,&灯光,&视点,
球体[相交对象].kd\U rgb[CGREEN],球体[相交对象].ks\U rgb[CGREEN],球体[相交对象].ka\U rgb[CGREEN],球体[相交对象],
光照强度、环境光照强度);
蓝色=blinnphong_明暗处理(¤t_交叉点,&light,&view_点,
球体[相交对象].kd\U rgb[CBLUE],球体[相交对象].ks\U rgb[CBLUE],球体[相交对象].ka\U rgb[CBLUE],球体[相交对象],
光照强度、环境光照强度);
}
tabelaPixlov[i][j].红色=红色;
tabelaPixlov[i][j].绿色=绿色;
tabelaPixlov[i][j].蓝色=蓝色;
glColor3f(tabelaPixlov[i][j]。红色,tabelaPixlov[i][j]。绿色,tabelaPixlov[i][j]。蓝色);
交叉点_对象=-1;
b阴影=假;
}
其他的
{
//用背景色绘制像素
tabelaPixlov[i][j].红色=0;
tabelaPixlov[i][j].绿色=0;
tabelaPixlov[i][j].蓝色=0;
交叉点_对象=-1;
b阴影=假;
}
当前λ=0x7fefffffffffffff;
电流λ=0x7FEFFFFFFFFFFFFFFF;
}
}
//glFlush();
stop=omp_get_wtime();
对于(int i=0;i<(viewport.xvmax-viewport.xvmin);i++)
{
对于(int j=0;j<(viewport.yvmax-viewport.yvmin);j++)
{
glColor3f(tabelaPixlov[i][j]。红色,tabelaPixlov[i][j]。绿色,tabelaPixlov[i][j]。蓝色);
glBegin(总分);
glVertex2i(i,j);
格伦德();
}
}
printf(“%f\nšt niti:%d\n”,停止-启动,omp_get_max_threads());
glutSwapBuffers();
}
对于光线跟踪,您应该使用计划(动态)
。除此之外,我建议将回路熔断
#pragma omp parallel for schedule(dynamic) {
for(int n=0; n<((viewport.xvmax - viewport.xvmin)*(viewport.yvmax - viewport.yvmin); n++) {
int i = n/(viewport.yvmax - viewport.yvmin);
int j = n%(viewport.yvmax - viewport.yvmin)
//...
}
#计划的pragma omp并行(动态){
对于(int n=0;nomp\u set\u num\u threads(omp\u get\u max\u threads())
完全无效。两个调用都在同一个OpenMP内部控制变量上运行。OpenMP自3.0版以来支持循环折叠。还应记住,对于内存限制算法,如果程序的数据不适合CPU缓存,矢量化多线程代码的性能可能比标量多线程代码差。@HristoIliev,是的,但MSVC不支持OpenMP 3.0,手工熔合循环也很简单。光线跟踪通常不受内存限制。但即使如此,它也不是tri