问题描述
- 为何使用openmp对程序进行加速,但效果并不理想
-
我需要多次(约30万次)对一个较大的矩阵(88147乘以2000)进行计算,而计算过程并不复杂,只是简单的将整个矩阵遍历一遍,做一些小的计算。
这30万次计算中的每一次都是基于上一次的计算结果。
我在一台32核的服务器上跑这个程序,因为计算一次的时间较长(约10分钟),30万次所需的时间太长,因此我想使用openmp来加速它,因为第一次使用openmp,我简单的使用了“for"来对for循环加速,下面是我的代码,openmp部分我重点标出:
我使用-fopenmp来编译运行,但是效果并不理想,和原来的速度相差无几,我想请问一下大家,这是为什么?
还可以使用什么其他方法来进行加速吗?#include<iostream> #include<fstream> #include<math.h> #include<omp.h> using namespace std; #define LONGTH 88147 int label[LONGTH] ; float data[LONGTH][2000] ; float w[2000]; float e[2000]; void Input() { ifstream fin; float a; fin.open("/home/data.train"); if (!fin) { cout << "file error"; return; } for (int i = 0; i < LONGTH; i++) { fin >> a; label[i] = int(a); for (int j = 0; j < 2000; j++) { fin>>data[i][j]; } } fin.close(); cout<<"input over"<<endl; return; } void Initial() { for (int i = 0; i < 2000; i++) { w[i] = 1; e[i] = 1; } return; } bool End() { for (int i = 0; i < 2000; i++) { if (fabs(e[i])>pow(0.1, 6)) return 0; } return 1; } float Tkj(int i, int j, int k,float w[2000]) { return w[i] * data[k][i] - w[j] * data[k][j]; } float En(int n)//******** { float result = 0; #pragma omp parallel for num_threads(64) reduction(+:result)//******** for (int k = 0; k < LONGTH; k++) { int tnum = omp_get_thread_num(); float tmp = 0; int i = label[k] - 1; for (int j = 0; j < 2000; j++) { if (j != i) { float l = 0; if (n == i) { l = data[k][i]; float e = exp(Tkj(i, j, k,w)); tmp = tmp + (-e*l) / pow(1 + e, 2); } else if (n == j) { l = -data[k][j]; float e = exp(Tkj(i, j, k,w)); tmp = tmp + (-e*l) / pow(1 + e, 2); } else { continue; } } } result = result + tmp; } return result; } float Ex(float w[2000])//******** { float result = 0; #pragma omp parallel for num_threads(64) reduction(+:result)//******** for (int k = 0; k < LONGTH; k++) { int i = label[k] - 1; float tmp = 0; int tnum = omp_get_thread_num(); for (int j = 0; j < 2000; j++) { if (j != i) { tmp = tmp + 1 / (1 + exp(Tkj(i,j,k,w))); } } result = result+tmp; } return result; } int main() { Input(); Initial(); float w2[2000] = { 0 }; float b = pow(0.1,5); int times = 0; while (!End()&×<=30000) { times++; cout<<times<<endl; for (int i = 0; i < 2000; i++) { e[i] = En(i); w2[i] = w[i] - b*e[i]; } if (Ex(w2)<=Ex(w))//better { b = b * 2; for (int i = 0; i < 2000; i++) w[i] = w2[i]; } else//worser { b = b / 2; } } ofstream fout("/home/w.txt"); for(int i=0;i<2000;i++) { fout<<w[i]<<' '; } fout.close(); return 0; }
解决方案
多核加速的效果取决于两个:一个是并行代码占总程序的比率。你可以在运行程序的时候打开任务管理器,如果cpu的占用不是100%,偏少,说明没有充分并行。
另一个取决于你在多个核之前通讯的开销,特别是你的服务器如果有2个cpu,可能是numa架构的,那么不同cpu group之间的通讯开销是很大的。
解决方案二:
多核加速的效果取决于两个:一个是并行代码占总程序的比率。你可以在运行程序的时候打开任务管理器,如果cpu的占用不是100%,偏少,说明没有充分并行。
另一个取决于你在多个核之前通讯的开销,特别是你的服务器如果有2个cpu,可能是numa架构的,那么不同cpu group之间的通讯开销是很大的
解决方案三:
多核加速的效果取决于两个:一个是并行代码占总程序的比率。你可以在运行程序的时候打开任务管理器,如果cpu的占用不是100%,偏少,说明没有充分并行。
另一个取决于你在多个核之前通讯的开销,特别是你的服务器如果有2个cpu,可能是numa架构的,那么不同cpu group之间的通讯开销是很大的。
时间: 2024-09-24 01:14:00