多线程-为何使用openmp对程序进行加速,但效果并不理想

问题描述

为何使用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;
}

解决方案

多核加速的效果取决于两个:一个是并行代码占总程序的比率。你可以在运行程序的时候打开任务管理器,如果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

多线程-为何使用openmp对程序进行加速,但效果并不理想的相关文章

Linux下C语言多线程,网络通信简单聊天程序

原文:Linux下C语言多线程,网络通信简单聊天程序 功能描述:程序应用多线程技术,可是实现1对N进行网络通信聊天.但至今没想出合适的退出机制,除了用Ctr+C.出于演示目的,这里采用UNIX域协议(文件系统套接字),程序分为客户端和服务端.应用select函数来实现异步的读写操作. 先说一下服务端:首先先创建套接字,然后绑定,接下进入一个无限循环,用accept函数,接受"连接"请求,然后调用创建线程函数,创造新的线程,进入下一个循环.这样每当有一个新的"连接"被

使用CDN对动态网站内容加速有效果吗

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 随着加速乐.Webluker等云加速平台的流行,CDN不再是少数网站的专享产品,而逐渐成为中小网站的普遍选择;使用CDN,可以在网站和用户之间增加一层网络架构,把内容分发到接近用户的网络"边缘",让用户更快地通过CDN节点获取内容,从而实现用户访问网站时的加速. 目前,使用CDN对静态网站内容加速的效果,多数人都认可,已经

用C语言加速程序进而加速硬件速度

今天的电子设备,不管是嵌入.工业.消费.娱乐,还是通讯电子设备,它们中的应用程序,都比过去需要在更短的时间内处理更多的数据.一般来说,开发者通常会选用某种通用型处理器或数字信号处理器(DSP),对那些适应性为先的应用程序来说,通用型处理器一直都是最佳的架构选择,而同时DSP也是用于提高运算能力的首选.在许多情况中,既需要适应性,同时也需要强大的运算能力,当为了增加通用型处理器的执行能力而提高时钟频率时,也会带来成本与电能消耗的增加.为满足今日计算的要求,在这些设备中加入了硬件加速或某些特别的辅助

多线程 复制 linux-多线程复制程序的求解

问题描述 多线程复制程序的求解 我写了一个多线程复制程序遇到下面问题,不知道该怎么解决,求各位大神cp_thread_mutex.c: 在函数'main'中: cp_thread_mutex.c:98: 警告:传递'pthread_mutex_destroy'的第 1 个参数时在不兼容的指针类型间转换 /usr/include/pthread.h:738: 附注:需要类型'union pthread_mutex_t ',但实参的类型为'union pthread_mutex_t **' cp_t

java多线程入门知识及示例程序_java

为什么需要多线程?模型的简化,如某些程序是由多个相对独立任务的运行: 图形界面的出现,输入.输出的阻塞 多核CPU的更好利用 异步行为的需要 Java多线程的特性: 程序的入口main本身是一个线程 线程是并发的,无序执行的 线程内部是顺序执行的 共享数据 Java多线程的风险: 安全风险:由于线程的操作顺序是不确定的,某些在单线程下能运行的程序到多线程下会出现意外的结果. 性能风险:服务器的吞吐量.响应性.资源消耗 Java多线程API: Java可以通过两种形式创建线程:一.实现Runnab

【Python之旅】第五篇(四):基于Python Sockct多线程的简版SSH程序

 还是继续延续篇五中前三节的例子,通过对代码的修修补补,把它改成一个可以在连接后就能在Client端执行Server端命令的程序,所以就有点类似于SSH连接程序了.     至于还是用前面的例子来改嘛,是因为上课也一直这么干,而且老师也讲得非常不错,自己吸收后也作为一个学习的记录吧,因为确实是非常不错的!     之所以能对前面的例子如这样的修改,应当有这样的思想:前面的例子中,Server端能够返回Client端输入的字符串,那么如果Client端输入的是Linux的shell命令,Serve

用netbeans 6.9.1写Swing程序,预览效果和实际效果怎么不一样

问题描述 用netbeans6.9.1写Swing程序,直接拖拽了几个空间上去,结果预览效果和实际效果不一样.实际效果和AWT的一样,怎么回事? 解决方案 解决方案二:用eclipse也会吧,预览和实际多少会有差别的解决方案三:那你调用的是swing包还是awt包呢,要是调用的awt的包不一样就对了,因为当时awt的api会调用系统平台的api,说白了就是在不同的平台下面显示效果会有些差别,当然如果全部是用swing写的就不应该出现lz所说的了解决方案四:自己顶起,解决了解决方案五:netbea

加速乐WordPress专用加速包效果实测

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 前几天,加速乐推出了一个WordPress专用加速包,介绍中说可以提升WordPress网站速度2到10倍以上,本着"实事求是"的态度,加上刚出来时0.5元/月,因此直接买了半年,准备测试一下性能,看网站到底提升了多少速度. 在我的潜意识里面,搭载了太多插件的WordPress网站非常占用资源,512M内存的VPS都很难让

总结Ubuntu上使用Android SDK开发经验

测试硬件环境: 打开了Intel VT的PC (使用KVM时需要VT支持的) 测试软件环境: Ubuntu 12.04 x86_64 ADT Bundle Linux x86_64 (在android官网下载:https://developer.android.com/sdk/index.html ) 1. 下载所需的Image和创建AVD: 可以在Eclipse(ADT)中,"Window" -> "Andorid SDK Manager"来打开SDK管理器