没有循环的函数是否可并行化?

时间:2018-11-27 17:58:53

标签: c openmp

考虑以下代码,即使没有循环,我们也可以认为它是并行的吗?

>>> print(json.dumps(c, default=dataclass_object_dump, indent=4))
{
    "mylist": [
        {
            "x": 0,
            "y": 0,
            "__dataclass__": "__main__.Point"
        },
        {
            "x": 10,
            "y": 4,
            "__dataclass__": "__main__.Point"
        }
    ],
    "__dataclass__": "__main__.C"
}
>>> json.loads(json.dumps(c, default=dataclass_object_dump), object_hook=dataclass_object_load)
C(mylist=[Point(x=0, y=0), Point(x=10, y=4)])
>>> json.loads(json.dumps(c, default=dataclass_object_dump), object_hook=dataclass_object_load) == c
True

1 个答案:

答案 0 :(得分:6)

直接回答:

是的,这里是您的代码部分

int a = 1;
a = 0;

并行运行P次,其中P是计算机上的内核数。

例如,在四核计算机上,以下代码(带有相关的导入内容),

int main(void) {
    #pragma omp parallel
    {
        printf("Thread number %d", omp_get_thread_num());
    }
    return 0;
}

将输出:

Thread number 0
Thread number 1
Thread number 2
Thread number 3

请注意,在并行运行时,无法保证输出的顺序,因此输出可能像这样:

Thread number 1
Thread number 2
Thread number 0
Thread number 3

此外,如果您想指定并行区域中使用的线程数,则可以写#pragma omp parallel代替#pragma omp parallel num_threads(4)


进一步的说明:

如果您仍然感到困惑,可能有助于更好地理解并行for循环与并行代码区域之间的区别。

#pragma omp parallel告诉编译器可以并行执行以下代码块。这样可以保证并行区域内的所有代码在继续执行后续代码之前都已完成执行。

在下面的(玩具)示例中,程序员可以保证在并行区域之后,该数组会将所有条目设置为零。

int *arr = malloc(sizeof(int) * 128); 
const int P = omp_get_max_threads();

#pragma omp parallel num_threads(P)
{
    int local_start = omp_get_thread_num();
    int local_end = local_start + (100 / P);
    for (int i = local_start; i < local_end; ++i) {
        arr[i] = 0;
    }

}
// any code from here onward is guaranteed that arr contains all zeros!

忽略调度上的差异,可以使用以下并行for循环等效地完成此任务:

int *arr = malloc(sizeof(int) * 128); 
const int P = omp_get_max_threads();

#pragma omp parallel num_threads(P) for
for (int i = 0; i < 128; ++i) {
    arr[i] = 0;
}
// any code from here onward is guaranteed that arr contains all zeros!

本质上,#pragma omp parallel使您能够描述可以并行执行的代码区域-与并行for循环相比,它可以更加灵活。相反,#pragma omp parallel for通常应用于通过独立迭代并行化循环。

如果您愿意,我可以进一步详细说明性能差异。