1

我正在尝试实现一个函数的两个版本,该函数将在浮点数组中找到最大元素。但是,我的并行函数似乎比串行代码运行得慢得多。

使用 4194304 (2048 * 2048) 浮点数组,我得到以下数字(以微秒为单位):

  • 序列号:9433

  • PPL 代码:24184(慢两倍以上

  • OpenMP 代码:862093(几乎慢了100

这是代码:

PPL:

float find_largest_element_in_matrix_PPL(float* m, size_t dims)
{
    float max_element;
    int row, col;
    concurrency::combinable<float> locals([] { return (float)INT_MIN; });
    concurrency::parallel_for(size_t(0), dims * dims, [&locals](int curr)
    {
        float &localMax = locals.local();
        localMax = max<float>(localMax, curr);
    });

    max_element = locals.combine([](float left, float right) { return max<float>(left, right); });
    return max_element;
}

开放式MP:

float find_largest_element_in_matrix_OMP(float* m, unsigned const int dims)
{
    float max_value = 0.0;
    int i, row, col, index;

    #pragma omp parallel for private(i) shared(max_value, index)
    for (i = 0; i < dims * dims; ++i)
    {
#pragma omp critical
        if (m[i] > max_value)
        {
            max_value = m[i];
            index = i;
        }
    }

    //row = index / dims;
    //col = index % dims;
    return max_value;
}

  1. 是什么让代码运行如此缓慢?我错过了什么吗?

  2. 你能帮我找出我做错了什么吗?

4

1 回答 1

1

因此,正如Baum mit Augen所注意到的,OpenMP 的问题在于我有一个临界区,并且代码实际上并没有并行运行,而是同步运行。删除关键部分就可以了。

至于 PPL,我发现它比 OpenMP 做了更多的准备工作(创建线程和东西),因此速度变慢了。


更新

因此,这是使用 OpenMP 查找最大元素的正确变体(仍然需要关键部分,但在if块内):

float find_largest_element_in_matrix_OMP(float* m, unsigned const int dims)
{
    float max_value = 0.0;
    int i, row, col, index;

    #pragma omp parallel for
    for (i = 0; i < dims * dims; ++i)
    {
        if (m[i] > max_value)
        {
            #pragma omp critical
            max_value = m[i];
        }
    }
    return max_value;
}

PS:未测试。

于 2015-12-19T18:45:13.440 回答