主题:【求助】:请教信息技术方面的大牛有关多线程的问题 -- newtime
请教为何多线程执行起来花费时间比单线程要多呢?
非常感谢!!!
问题如下:
函数是用MONT CARLO方法计算圆周率。单线程计算函数两次共耗费大约是97s;而两个线程分别计算函数一次耗费的时间是392s.
环境:
CPU: i7920 4核
内存:3GB
操作系统:Windows Vista
编译器:Intel Fortran 90
程序如下:
多线程主程序:
Program TESTPROC0
use ifmt
use threadfunction
implicit none
integer,parameter::n_thread=2,n_c=2
integer(INT_PTR_KIND())::Threads_Handle(n_thread),waitresult,cend,retlog,retint,&
thread_handle_1,thread_handle_2
integer(INT_PTR_KIND()), PARAMETER :: security = 0
integer(INT_PTR_KIND()), PARAMETER :: stack_size = 0
integer(INT_PTR_KIND()) :: thread_id,rc
integer(4)::i,slot
real(kind(1d0))::pi,time_begin,time_end,t0,t1
call cpu_time(time_begin)
slot=0
Thread_Handle_1= CreateThread(security,stack_size,Thread_Proc0,loc(i), 0, thread_id)
Thread_Handle_2=CreateThread(security,stack_size,Thread_Proc0,loc(i), 0, thread_id)
waitresult=waitforsingleobject(thread_handle_1,infinite)
waitresult=waitforsingleobject(thread_handle_2,infinite)
cend=closehandle(thread_handle_1)
cend=closehandle(thread_handle_2)
call cpu_time(time_end)
t1=time_end-time_begin
write(6,*) "multithread computation takes time",t1,t1/n_c
pause
end program TESTPROC0
单线程主程序:
Program TESTPROC0
use threadfunction
implicit none
integer,parameter::n_c=2
integer(INT_PTR_KIND()) :: thread_id,rc
integer(4)::i,slot
real(kind(1d0))::pi,time_begin,time_end,t0,t1
call cpu_time(time_begin)
do i=1,n_c
pi=Thread_Proc0(i)
enddo
call cpu_time(time_end)
t0=time_end-time_begin
write(6,*) "computation takes time",t0,t0/n_c
pause
end program TESTPROC0
函数:
Module threadfunction
contains
real(kind(1d0)) function Thread_Proc0(arg) implicit none
!DEC$ ATTRIBUTES STDCALL, ALIAS:"_thread_proc0" :: Thread_Proc0
integer(4),intent(in):: arg
integer(4),parameter::j=999999999
integer(4)::i
real(kind(1d0))::x,y,u,q
q=0
do i=1,j
call random_number(x)
call random_number(y)
u=x**2.0d0+y**2.0d0
if (u<1.0d0) then
q=q+1.0d0
endif
enddo
Thread_proc0=q/j*4
end function Thread_Proc0
end Module threadfunction
A light weight process, ie, the thread, must do substantial chunk of work to gain sufficient efficiency. In your case, I highly suspect it's because the threads are not doing enough work, so your CPU spends most of the time creating and destroying the threads instead of doing calculation, the real work.
not Mont Carlo, but that's for sure just a typo.
多线程因为有额外的工作要做来产生和管理线程,当然需要花更多的时间。。。除非你写一个程序可以同时利用多个CPU来产生多线程,那么因为多个CPU同时进行计算,时间就可以短了。。。。
那么为了通过多线程来节省总计算时间,你最好换一个用native线程来产生多线程的语言,这样就可充分利用硬件的4核处理器。。。。。
小妹延长了函数的loop数目,但是无论我如何让函数运算复杂,多线程程序仍然比单线程慢。哭啊
什么是绿色线程和native 线程?忘了提一句,我也试过用omp parallel,但是问题依然存在。
我用的编译软件是 intel fortran 10.1 for windows,这种编译器只能产生绿色线程吗?
河友是搞科研的?哪个领域的?
惭愧,俺乃是搞那个已经臭名昭著的经济学滴
只是觉得现在经济学研究里的哲学成分少了些。。。不过现在的主流哲学本身的智慧成分就很少。。。西方哲学家的兴趣是在如何把哲学科学化。。。如有兴趣,我们或许可以探讨一下经济学里的哲学。。。:)
在单核状态下:
线程并不是越多越好,
线程启停以及线程上下文切换都会引起额外的开销,所以消耗的时间比单线程多。
采用多线程方法设计程序时,如果产生的额外开销大于线程的工作任务,就没有并行的必要。
对于多核多线程的编程,我了解不多.......
你有必要查阅一下<<多核程序设计技术>>这本书
一般多线程运用的场景是:
存在一个或几个运算密集型任务,多个IO密集型任务;
一个运算密集型任务,并且该任务可以切分为多个互不干扰的子任务;
所以你应该看看你的子任务中,是否存在任务竞争或者等待或者交叉使用某资源等情况。如果存在的话,多线程的效果不会很好。
另外,如果确定没有上述情况,可以尝试多进程模型,让每个进程绑定在一个CPU上运行(操作系统应该会提供这类的API),看看效果有没有改善?不过我不知道Fortran能不能做到这点,因为这似乎要直接调用操作系统的API,而这些API,一般都是C的接口。
Fortran我都忘光了,你得程序有点看不懂,怀疑是编译问题,你看看是否用了正确的编译模式,以及链接库是否用的是多线程的库。
很多数学函数本身很可能不能够多线程操作的,比如random_number,每次产生的数与前面的数相关,这样的话多个线程并发会导致频繁的自旋锁操作,可能是慢的原因之一。
看看运算过程中你的各个CPU的负载情况,是两个核在跑还是一个核在跑。
是两个核在跑。
两线程的cpu使用大约是单线程的两倍多。但是两线程所需要的时间却比单线程长得多。很不明白为什么。