Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个特定Perl脚本的线程版本比非线程版本慢200倍?_Perl_Multithreading - Fatal编程技术网

为什么这个特定Perl脚本的线程版本比非线程版本慢200倍?

为什么这个特定Perl脚本的线程版本比非线程版本慢200倍?,perl,multithreading,Perl,Multithreading,2003年Perl会议上的一篇文章包括两个质数查找脚本示例。是线程化的,而不是。在运行脚本(打印行被注释掉)时,我在非线程版本上得到了0.011s的执行时间,在线程版本上得到了2.343(!)秒的执行时间。是什么原因造成了时间上的惊人差异 我对Perl中的线程有一些经验,并且以前注意到线程创建时间可能特别残酷,但这似乎不是Goikham示例中的瓶颈。您有多少处理器?一般来说,当线程数>处理器数时,任何计算密集型任务都会变慢。这是因为在线程之间切换(“上下文切换”)代价高昂。上下文切换涉及停止一个

2003年Perl会议上的一篇文章包括两个质数查找脚本示例。是线程化的,而不是。在运行脚本(打印行被注释掉)时,我在非线程版本上得到了0.011s的执行时间,在线程版本上得到了2.343(!)秒的执行时间。是什么原因造成了时间上的惊人差异


我对Perl中的线程有一些经验,并且以前注意到线程创建时间可能特别残酷,但这似乎不是Goikham示例中的瓶颈。

您有多少处理器?一般来说,当线程数>处理器数时,任何计算密集型任务都会变慢。这是因为在线程之间切换(“上下文切换”)代价高昂。上下文切换涉及停止一个线程,保存它的上下文,然后将另一个线程的上下文放入处理器,以便它可以运行。这一切都是为了什么?所以线程A可以计算12321是否可以被7整除,而不是线程B


如果你有2个进程,我敢打赌一个有2个线程的版本可能是最快的,4个进程->使用4个线程,等等。

我是Python的人,不是Perl,所以我对代码的作用只有一个模糊的概念。但是,当您看到队列时,请务必小心。Python有一个线程安全队列,看起来Perl也有。它们非常出色,为您提供了线程安全保护,但它们通常涉及大量昂贵的队列锁定和解锁,这可能是您所有时间的目的地。

Jay p.是正确的:

~$ strace -c ./threads.pl
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.80    0.116007       10546        11           futex
  0.20    0.000229           6        36           mmap2
  0.00    0.000000           0        31           read
  0.00    0.000000           0        49        13 open
  0.00    0.000000           0        36           close
与之相比:

~$ strace -c ./no-threads.pl
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 90.62    0.000261         261         1           execve
  9.38    0.000027           0       167           write
  0.00    0.000000           0        12           read
  0.00    0.000000           0        38        13 open
  0.00    0.000000           0        25           close

这有点病态。真正的答案是:在开始使用PerlIthreads之前,您需要了解一些事情是如何工作的。众所周知,他们在某些方面效率低下(共享数据),而在其他方面则表现出色(它们是并行的)

如果与从一个线程向另一个线程发送数据的次数相比,您让子线程执行的工作块将显著增加大约,那么事情看起来就大不相同了


与像Jay p这样的Python线程相比:正如他正确指出的那样,Python线程是协作的,只在一个核心上运行。Perl的读取非常不同。每个线程都可以在一个内核上运行,但要做到这一点,基本上每个线程都有一个单独的解释器。这使得线程之间的通信类似于进程间通信,包括相关的开销。

您的“一个”和“其他”链接是反向的。您现在可能要花费0.0055秒来查找素数,2.3375秒来使问题线程化。另外,CPython有一个“GIL”的概念(全局解释器锁),这本质上使CPython对“线程化以提高性能”毫无用处(它不会跨内核扩展),尽管python中的线程仍然可以用来绕过阻塞(系统)调用的限制(当然,这不包括调用与GIL无关的线程感知C扩展的情况)。我在1个单芯盒和2个四核盒上试过。两者的对比结果相似。谢谢你的确认。我希望我能接受两个答案。。)