微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

由于开销和caching问题,OpenMP代码不能缩放

struct xnode { float *mat; }; void testScaling( ) { int N = 1000000; ///total num matrices int dim = 10; //memory for matrices std::vector<xnode> nodeArray(N); for( int k = 0; k < N; ++k ) nodeArray[k].mat = new float [dim*dim]; //memory for Y std::vector<float*> Y(N,0); for( int k = 0; k < N; ++k ) Y[k] = new float [dim]; //shared X float* X = new float [dim]; for(int i = 0; i < dim; ++i ) X[i] = 1.0; //init mats for( int k = 0; k < N; ++k ) { for( int i=0; i<dim*dim; ++i ) nodeArray[k].mat[i] = 0.25+((float)i)/3; } int NTIMES = 500; //gemv args char trans = 'N'; int lda = dim; int incx = 1; float alpha =1,beta = 0; //threads int thr[4]; thr[0] =1 ; thr[1] = 2; thr[2] = 4; thr[3] = 8; for( int t = 0; t<4; ++t )//test for nthreads { int nthreads = thr[t]; double t_1 = omp_get_wtime(); for( int ii = 0; ii < NTIMES; ++ii )//do matvec NTIMES { #pragma omp parallel for num_threads(nthreads) for( int k=0; k<N; ++k ) { //compute Y[k] = mat[k] * X; GEMV(&trans,&dim,&alpha,nodeArray[k].mat,&lda,X,&incx,&beta,Y[k],&incx); //GEMV(&trans,nodeArray[0].mat,&incx); } } double t_2 = omp_get_wtime(); std::cout << "Threads " << nthreads << " time " << (t_2-t_1)/NTIMES << std::endl; } //clear memory for( int k = 0; k < N; ++k ) { delete [] nodeArray[k].mat; delete [] Y[k]; } delete [] X; }

上述代码将大小为dim的N个matrix的matrix向量乘积并行化,并将结果存储在N个输出向量中。 将500个产品的平均值作为每个matrix向量乘积的时间。 上例中的matrix向​​量产品都是相同的大小,因此线程应该是完美平衡的 – 我们应该实现接近理想8倍的性能缩放。 以下是观察结果(机器 – 英特尔至强3.1GHz处理器,每个8核,启用了超线程,Windows,VS2012,英特尔MKL,英特尔OMP库)。

观察1:

dim = 10 N = 1000000

线程1 – 时间0.138068s

线程2 – 时间0.0729147s

线程4 – 时间0.0360527s

线程8 – 时间0.0224268s(8线程6.1倍)

观察2:

dim = 20 N = 1000000

线程1次0.326617

线程2时间0.185706

线程4次0.0886508

线程8次0.0733666(在8个线程上4.5倍)。

注 – 我在这个案例上运行了VTune。 它显示cpuTime 267.8秒,架空时间43秒,旋转时间 – 8秒。 开销时间全部用在libiomp函数(intel库)中。 这种情况下,8线程/ 1线程缩放比较差。

八度 – 内存不足或维度过大,八度的索引types

如果有2个matrixa和b,a(b)在matlab中做什么?

rand()不返回随机

在正方形上使用时出现C ++旋转matrix问题

什么是最快的方法/库来计算在C ++matrix的排名

接下来,在gemv for循环中,我们将nodeArray [k] .mat更改为nodeArray [0] .mat(请参阅注释语句),以便只有第一个matrix用于所有matrix向量乘积。

观察3

dim = 20 N = 1000000

线程1次0.152298(连续时间减半)

线程2时间0.0769173

线程4次0.0384086

线程8时间0.019336(8线程上的7.87倍)

因此,我得到了几乎理想的缩放比例 – 这是为什么? VTune表示,大部分cpu时间花费在同步和线程开销上。 这里似乎没有负载均衡和线程同步之间的关系。 随着matrix大小的增加,粒度应该增加,线程开销应该成比例的小。 但是,随着我们从10到20的增长,规模正在减弱。 当我们使用nodeArray [0] .mat(只有第一个matrix)做所有的matrix向量积时,caching只更新一次(因为编译器在优化过程中知道这一点),我们得到接近理想的缩放比例。 因此,同步开销似乎与某些caching相关的问题有关。 我已经尝试了一些其他的东西,如设置KMP_AFFINITY和不同的负载分配,但没有买我什么。

我的问题是:

1.关于高速caching性能如何影响openMP线程同步,我没有一个清晰的概念。 有人可以解释这个吗?

来自“简明英汉词典”可以做什么来提高规模和减less开销?

谢谢

远程linux服务器到远程linux服务器大型稀疏文件复制 – 如何?

GNU八度,以一个数字为单位精度

matrix库大matrix?

改进稀疏线性系统的解法

这可能是在Anaconda 2.5.0环境中的scipy.sparse.linalg.eigs函数中的错误

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐