Parallel processing 如何与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

我想并行化包含两个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 - 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(&current_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(&current_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(&current_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(&current_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;n
omp\u set\u num\u threads(omp\u get\u max\u threads())
完全无效。两个调用都在同一个OpenMP内部控制变量上运行。OpenMP自3.0版以来支持循环折叠。还应记住,对于内存限制算法,如果程序的数据不适合CPU缓存,矢量化多线程代码的性能可能比标量多线程代码差。@HristoIliev,是的,但MSVC不支持OpenMP 3.0,手工熔合循环也很简单。光线跟踪通常不受内存限制。但即使如此,它也不是tri