我需要多次(约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;
}