gpt4 book ai didi

带有 OpenMP 的 C++ 尽量避免紧密循环数组的错误共享

转载 作者:行者123 更新时间:2023-12-04 18:58:45 25 4
gpt4 key购买 nike

我尝试将 OpenMP 引入我的 c++ 代码,以使用如下所示的简单案例来提高性能:

#include <omp.h>
#include <chrono>
#include <iostream>
#include <cmath>

using std::cout;
using std::endl;

#define NUM 100000

int main()
{
double data[NUM] __attribute__ ((aligned (128)));;

#ifdef _OPENMP
auto t1 = omp_get_wtime();
#else
auto t1 = std::chrono::steady_clock::now();
#endif

for(long int k=0; k<100000; ++k)
{

#pragma omp parallel for schedule(static, 16) num_threads(4)
for(long int i=0; i<NUM; ++i)
{
data[i] = cos(sin(i*i+ k*k));
}
}

#ifdef _OPENMP
auto t2 = omp_get_wtime();
auto duration = t2 - t1;
cout<<"OpenMP Elapsed time (second): "<<duration<<endl;
#else
auto t2 = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
cout<<"No OpenMP Elapsed time (second): "<<duration/1e6<<endl;
#endif

double tempsum = 0.;
for(long int i=0; i<NUM; ++i)
{
int nextind = (i == 0 ? 0 : i-1);
tempsum += i + sin(data[i]) + cos(data[nextind]);
}
cout<<"Raw data sum: "<<tempsum<<endl;
return 0;
}

访问紧密循环的 int 数组(大小 = 10000)并以并行或非并行方式更改其元素。
构建为
g++ -o test test.cpp 
或者
g++ -o test test.cpp -fopenmp
该计划将结果报告为:
No OpenMP Elapsed time (second): 427.44
Raw data sum: 5.00009e+09

OpenMP Elapsed time (second): 113.017
Raw data sum: 5.00009e+09

英特尔第 10 个 CPU,Ubuntu 18.04,GCC 7.5,OpenMP 4.5。
我怀疑缓存行中的错误共享导致 OpenMP 版本代码的性能不佳。
我在增加循环大小后更新了新的测试结果,OpenMP 运行得比预期的更快。
谢谢!

最佳答案

  • 由于您正在编写 C++,因此请使用 C++ 随机数生成器,它是线程安全的,与您正在使用的 C 传统生成器不同。
  • 此外,您没有使用数据数组,因此编译器实际上可以完全删除您的循环。
  • 在执行定时循环之前,您应该触摸一次所有数据。这样,您可以确保页面被实例化并且数据根据缓存进出缓存。
  • 你的循环很短。
  • 关于带有 OpenMP 的 C++ 尽量避免紧密循环数组的错误共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71646113/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com