zxczxcvvvvv 2015-05-12 14:50 采纳率: 0%
浏览 3144

为何使用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()&&times<=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;
}



  • 写回答

3条回答 默认 最新

  • threenewbee 2015-05-12 14:56
    关注

    多核加速的效果取决于两个:一个是并行代码占总程序的比率。你可以在运行程序的时候打开任务管理器,如果cpu的占用不是100%,偏少,说明没有充分并行。
    另一个取决于你在多个核之前通讯的开销,特别是你的服务器如果有2个cpu,可能是numa架构的,那么不同cpu group之间的通讯开销是很大的。

    评论

报告相同问题?

悬赏问题

  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)