多线程的问题

mz126 2015-10-25 11:21:32
老师上课给了多线程计算调和级数的demo,我改写了下。现在只运行单线程,我的代码比老师的demo慢了一倍多,求大神指导到底问题出在哪?原问题是计算 1 + 1/2 + 1/3 + ............1/n。其中n = 1000000000。线程数为1
老师的demo运行时间为:9.9s 我的代码运行时间为20.7s

下面先给出老师的demo:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define ERR_EXIT(msg)\
do{\
fprintf(stderr,"Usage: %s N NP\n",msg);\
exit(EXIT_FAILURE);\
}while(0)
#define ERR_EXIT1(msg)\
do{\
fprintf(stderr,"%s\n",msg);\
exit(EXIT_FAILURE);\
}while(0)
#define ERR_EXIT2(msg)\
do{\
perror(msg);\
exit(EXIT_FAILURE);\
}while(0)

typedef struct Arg
{
int id;
int begin;
int end;
int step;
}Arg;

double* res_arr = NULL;
pthread_t* pid_arr = NULL;

void* thread_func(void* arg);
double cal( int n , int n_part );

int main( int argc , char* argv[] )
{
double res = 0.0;
if( argc < 2 )
ERR_EXIT(argv[0]);

int n = atoi(argv[1]);
int n_part = atoi(argv[2]);
res = cal( n , n_part );
printf("Result is %lf\n" , res);

exit(EXIT_SUCCESS);
}
void* thread_func(void* arg)
{
Arg* _arg = (Arg*)arg;
int begin = _arg->begin;
int end = _arg->end;
int step = _arg->step;

double sum = 0;
int i = 0;

for( i = begin ; i <=end ; i += step )
{
sum += 1.0 / i;
}
res_arr[ _arg->id ] = sum;
free(arg);

pthread_exit(NULL);
}
double cal( int n , int n_part )
{
int i = 0;
int ret = 0;
double result = 0.0;

if( n <= 0 || n_part < 1 )
ERR_EXIT1("Argument to cal is not valid!");

res_arr = (double*)malloc( n_part*sizeof(double) );
if(!res_arr)
ERR_EXIT1("Not enough room!");
pid_arr = (pthread_t*)malloc( n_part*sizeof(pthread_t) );
if(!pid_arr)
ERR_EXIT1("Not enough room!");

// create the task and the thread
for( i = 0 ; i < n_part ; ++i )
{
Arg* arg = (Arg*)malloc(sizeof(Arg));
if(!arg)
ERR_EXIT1("Not enough room!");
arg->id = i;
arg->begin = i + 1;
arg->end = n;
arg->step = n_part;

ret = pthread_create( pid_arr+i , NULL , thread_func , (void*)arg );
if( -1 == ret )
ERR_EXIT2("pthead_create error");
}

// join the thread
for( i = 0 ; i < n_part ; ++i )
{
ret = pthread_join( pid_arr[ i ] , NULL );
if( -1 == ret )
ERR_EXIT2( "pthread_join error" );
}

// sum the result
for( i = 0 ; i < n_part ; ++i )
{
result += res_arr[i];
}

free(res_arr);
free(pid_arr);
return result;
}

下面给出我的代码:

/*************************************************************************
> File Name: my_common.h
> Author:
> Mail:
> Created Time: Wed 21 Oct 2015 08:36:57 PM CST
************************************************************************/
#ifndef MY_COMMON_H__
#define MY_COMMON_H__
#include <stdio.h>
#include <stdlib.h>

/* 异常处理 */
#define ERR_EXIT(msg)\
do{\
perror(msg);\
exit(EXIT_FAILURE);\
}while(0)
#define ERR_EXIT1(msg)\
do{\
fprintf( stderr , "%s\n" , msg );\
exit(EXIT_FAILURE);\
}while(0)

/* 配置信息 */
#define MAX_NUM 1000000000 // 计算最大数字
#define THREADS_NUM 1 // 线程数量
#define N 3 // 矩阵阶数

// 保存每个线程的计算结果
double res[THREADS_NUM];

typedef void* (*callback)(void*); // 回调函数

#endif
/*************************************************************************
> File Name: my_task.h
> Author:
> Mail:
> Created Time: Wed 21 Oct 2015 09:12:08 PM CST
************************************************************************/
#ifndef MY_TASK_H__
#define MY_TASK_H__
#include <stdio.h>
#include <pthread.h>

/* Definition of task node */
typedef struct task
{
size_t task_id;
size_t task_begin;
size_t task_end;
size_t task_step;
}task_t,*ptask_t;

void* task_handler( void* arg );

#endif
/*************************************************************************
> File Name: my_threads.h
> Author:
> Mail:
> Created Time: Wed 21 Oct 2015 08:40:55 PM CST
************************************************************************/
#ifndef MY_THREADS_H__
#define MY_THREADS_H__
#include <pthread.h>
#include "my_common.h"
#include "my_task.h"

/**
* @params tid_arr:线程队列
* @params tid_num:线程数量
* @params thread_func:线程体
* @params task_arr:任务队列
*/
void create_threads( pthread_t* tid_arr , size_t tid_num , callback thread_func , task_t* task_arr );
/**
* @params tid_arr:线程队列
* @params tid_num:线程数量
*/
void join_threads( pthread_t* tid_arr , size_t tid_num );

#endif
/*************************************************************************
> File Name: my_task.c
> Author:
> Mail:
> Created Time: Wed 21 Oct 2015 09:16:52 PM CST
************************************************************************/
#include "my_task.h"
#include "my_common.h"
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* task_handler( void* arg )
{
ptask_t ptask = (ptask_t)arg;

size_t id = ptask->task_id;
size_t b = ptask->task_begin;
size_t e = ptask->task_end;
size_t step = ptask->task_step;

int i = 0;
for( i = b ; i <= e ; i += step )
{
res[ id ] += 1.0 / i;
}

pthread_exit(NULL);
}
/*************************************************************************
> File Name: my_threads.c
> Author:
> Mail:
> Created Time: Wed 21 Oct 2015 08:50:20 PM CST
************************************************************************/
#include "my_threads.h"
#include "my_common.h"
#include <pthread.h>

void create_threads( pthread_t* tid_arr , size_t tid_num , callback thread_func , task_t* task_arr )
{
int i = 0;
int ret = 0;

if( NULL == tid_arr || tid_num < 1 || NULL == task_arr )
ERR_EXIT1("Argument to create_threads is not valid!");

for( i = 0 ; i < tid_num ; ++i )
{
ret = pthread_create( tid_arr + i , NULL , thread_func , (void*)(&task_arr[i]) );
if( -1 == ret )
ERR_EXIT( "pthread_create error" );
}

}// create_threads

void join_threads( pthread_t* tid_arr , size_t tid_num )
{
int i = 0;
int ret = 0;

if( NULL == tid_arr || tid_num < 1 )
ERR_EXIT1("Argument to join_threads is not valid!");

for( i = 0 ; i < tid_num ; ++i )
{
ret = pthread_join( tid_arr[i] , NULL );
if( -1 == ret )
ERR_EXIT("pthread_join");
}
}// join_threads
/*************************************************************************
> File Name: main.c
> Author:
> Mail:
> Created Time: Wed 21 Oct 2015 09:18:14 PM CST
************************************************************************/
#include "my_common.h"
#include "my_task.h"
#include "my_threads.h"
#include <strings.h>

// 任务数组
task_t task_que[THREADS_NUM];

// 线程数组
pthread_t tid_arr[THREADS_NUM];


int main( void )
{
int i = 0;
double result = 0.0;

// 创建任务队列
for( i = 0 ; i < THREADS_NUM ; ++i )
{
task_que[i].task_id = i;
task_que[i].task_begin = i + 1;
task_que[i].task_end = MAX_NUM;
task_que[i].task_step = THREADS_NUM;
}
bzero( res, sizeof(res) );

// 创建线程任务
create_threads( tid_arr , THREADS_NUM , task_handler , task_que );

// 等待线程执行结束
join_threads( tid_arr , THREADS_NUM );

// 累计结果
for( i = 0 ; i < THREADS_NUM ; ++i )
{
result += res[i];
}
printf("Result = %lf\n",result);

exit(EXIT_SUCCESS);
}


...全文
170 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
Demok-long 2015-11-04
  • 打赏
  • 举报
回复
同意楼上的答案
zhxianbin 2015-10-26
  • 打赏
  • 举报
回复
代码一样?计算机性能还不一样呢

23,217

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧