C++ windows多线程程序到linux下运行失败,多线程无优化效果

本文探讨了C++多线程程序从Windows移植到Linux环境下遇到的问题及解决方案,包括链接错误修正、计时方法改进及多线程优化技巧。

C++ windows多线程程序到linux下运行失败


博客http://blog.csdn.net/monkey3233/article/details/71467574 中的多线程程序,在VS下运行正常,但是复制到ubuntu,clion运行就失败
报错如下:
undefined reference to `pthread_create'
解决办法:
在CMakeLists.txt中添加-lpthread
原:target_link_libraries(multi_thread)
修改后:target_link_libraries(multi_thread -lpthread)

多线程未能起到优化效果,原因是计时方式有问题


  1. 在windows下,VS运行时,并行时间约为串行的一半,并行为370ms,串行为600ms;
  2. 但是在ubuntu下,运行时间相当,并行为581ms,串行为576ms;
  3. 可以在CMakeLists.txt中开启多线程优化,此时,并行时间为:38ms,串行时间为:35ms;时间差不多,多线程没有起到优化效果,目前不清楚问题出在什么地方;
  4. 原程序所用的计时方式:clock_t类,是用的CPU运行周期来计时的,多线程下,总的周期和单线程差不多,因此看上去时间相同;现在改用系统时间计时,gettimeofday() 链接:获取系统时间中所用的方法即可实现,更新后的代码附在最后(PS:CMakList.txt相同);

函数原型

#include<sys/time.h>
int gettimeofday(struct  timeval*tv,struct  timezone *tz )

这个函数会把时间包装为一个结构体返回。包括秒,微妙,时区等信息:

struct  timeval{
       long  tv_sec;/*秒*/
       long  tv_usec;/*微妙*/
};
struct  timezone{
        int tz_minuteswest;/*和greenwich时间差*/
        int tz_dsttime; 
}
多线程时间为329ms,单线程594ms,基本实现了性能的提升;

clock_t计时代码如下:

#include <stdlib.h>
#include <iostream>
#include <thread>
#include <time.h>

using namespace std;
int N = 10000;


void thread_task()  //用于比较的函数
{
    long int sum2 = 0;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            sum2 += (i + j);
//        cout << "thread1: " << i << endl;
    }
    cout << "sum2: " << sum2 << endl;
}

int main()
{
    long int sum1 = 0;
    int j = 0;
    clock_t  clockBegin, clockEnd;

    clockBegin = clock(); // 计时开始

    thread t(thread_task);// 并行开始
//    thread_task();  //串行开始

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            sum1 += (i + j);
//        cout << "thread2: " << i << endl;
    }
    t.join();// 并行结束

    cout << "sum1: " << sum1 << endl;

    clockEnd = clock();  // 计时结束

    cout << "time is " << (clockEnd - clockBegin)/1000 << " ms" << endl;
//    system("pause");
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.7)
project(multi_thread)

#set(CMAKE_CXX_STANDARD 11)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -march=native -O3 -pthread" )

set(SOURCE_FILES main.cpp)
add_executable(multi_thread ${SOURCE_FILES})
target_link_libraries(multi_thread -lpthread)

采用gettimeofday系统时间计时


#include <stdlib.h>
#include <iostream>
#include <thread>
#include <sys/time.h>

using namespace std;
int N = 10000;


void thread_task1()
{
    long int sum1 = 0;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            sum1 += (i + j);
    }
    cout << "sum1: " << sum1 << endl;
}

void thread_task2()
{
    long int sum2 = 0;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            sum2 += (i + j);

    }
    cout << "sum2: " << sum2 << endl;
}


int main()
{
    long int sum1 = 0;
    int j = 0;
    float serial_time = 0 ,parallel_time = 0;

    struct timeval start;
    struct timeval end;

    cout << "Repeat time N is: " << N << endl;
    /********************* parallel compute *********************/

    gettimeofday(&start, NULL);
    thread t1{thread_task1};
    thread_task2();
    if(t1.joinable())
        t1.join();

    gettimeofday(&end,NULL);
    parallel_time = (end.tv_sec-start.tv_sec)*1000+(end.tv_usec-start.tv_usec)*0.001;
    /********************* parallel compute *********************/

    /********************* serial compute *********************/
    gettimeofday(&start, NULL);
    thread_task1();
    thread_task2();
    gettimeofday(&end,NULL);
    serial_time = (end.tv_sec-start.tv_sec)*1000+(end.tv_usec-start.tv_usec)*0.001;
    /********************* serial compute *********************/


    cout << "parallel compute time is " << parallel_time << " ms" << endl;
    cout << "serial compute time is " << serial_time << " ms" << endl;

    return 0;
}
Usage: /home/chenlianfu/chenlianfu_scripts/blast.pl [options] BLAST_DB file.fasta > out.txt --tmp-prefix default: blast 设置临时文件或文件夹前缀。默认设置下,程序生成command.blast.list,blast.tmp/等临时文件或目录。 --chunk default: 10 设置每个数据块的序列条数。程序会将输入FASTA文件中的序列从前往后分割成多份,每10条相邻的序列分配到一个FASTA文件中;在blast.tmp/临时文件夹下生成次级文件夹,每个文件夹做多放置10个FASTA文件;每个fasta文件写出一条BLAST命令到command.blast.list文件中;然后程序调用ParaFly进行并行化计算。 请注意:若数据块的数量超过100万个,默认设置下blast.tmp/文件夹中的目录数量太多(超过1万个),导致文件系统运行缓慢,ParaFly程序运行效率低下,无法充分利用服务器计算资源。此时推荐设置--chunk参数值为100。 --blast-program default: blastp 设置运行的BLAST命令,支持的命令有:blastn, blastp, blastx, tblastn, tblastx。 --CPU default: 1 设置并行运行的BLAST程序个数。 --blast-threads default: 1 设置BLAST命令的-num_threads参数值。该参数让每个BLAST命令可以多线程运行。 请注意:--blast-threads参数值和--CPU参数值的乘积不要超过服务器的CPU总计算线程数。 --evalue default: 1e-3 设置BLAST命令的-evalue参数值。 --outfmt default: 5 设置BLAST命令的-outfmt参数值。输出方式。若为5,则输出xml格式结果,若为6或7,则输出表格结果。 --max-target-seqs default: 20 设置BLAST命令的-max_target_seqs参数值。该参数设置BLAST最多能匹配数据库中的序列数量。 -clean 若添加该参数,则在运行程序成功后,会删除临时文件或文件夹。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值