首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用OpenMP并行化?

如何使用OpenMP并行化?
EN

Stack Overflow用户
提问于 2014-01-19 17:08:39
回答 1查看 854关注 0票数 1

我想并行一个OpenMP射线跟踪算法,其中包含两个for循环。

除了设置omp_set_num_threads(omp_get_max_threads())和将#pragma omp parallel for放在第一个for循环前面之外,还有什么可以做的吗?

到目前为止,我已经达到了2.13倍的速度算法。

代码:

代码语言:javascript
运行
复制
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();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-20 08:28:03

对于射线跟踪,您应该使用schedule(dynamic)。此外,我建议把这个回路融合起来

代码语言:javascript
运行
复制
#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)
    //...
}

另外,为什么要设置线程数?只需使用默认值,它应该设置为逻辑核的数量。如果您有超线程,射线跟踪是将受益于超线程的算法之一,所以您不希望将线程数设置为物理内核的数目。

除了在OpenMP中使用MIMD之外,我还建议考虑使用SIMD进行射线跟踪。有关如何执行此PhD的示例,请参阅Ingo的http://www.sci.utah.edu/~wald/PhD/论文。基本上,你在一个SSE (AVX)寄存器中拍摄四(8)条射线,然后并行地沿着射线树对每条射线进行拍摄。但是,如果有一条射线完成了,那么您可以保持它,直到所有四条射线都完成为止(这类似于GPU所做的事情)。从那以后,就有很多论文都有了基于这个观点的更先进的技巧。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21219861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档