在数组 OpenMP 和 PPL 版本 运行 中查找最大元素比串行代码慢得多
Find max element in array OpenMP and PPL versions run much slower than serial code
我正在尝试实现一个函数的两个版本,它们会在浮点数数组中找到最大元素。但是,我的并行函数似乎 运行 比串行代码慢得多。
使用 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;
}
OpenMP:
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;
}
是什么让代码 运行 这么慢?我错过了什么吗?
你能帮我找出我做错了什么吗?
因此,正如 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: 未测试。
我正在尝试实现一个函数的两个版本,它们会在浮点数数组中找到最大元素。但是,我的并行函数似乎 运行 比串行代码慢得多。
使用 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;
}
OpenMP:
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;
}
是什么让代码 运行 这么慢?我错过了什么吗?
你能帮我找出我做错了什么吗?
因此,正如 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: 未测试。