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

Ric*_*ões 9 perl multithreading

一个演示文稿迈克·Goikhman从2003年的Perl会议包括一对黄金数量调查脚本的例子.一个是线程,另一个不是.在运行脚本(打印行注释掉)后,我在非线程版本上的执行时间为0.011秒,在线程版本上的执行时间为2.343(!)秒.是什么导致了时代的惊人差异?

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

bis*_*ish 15

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
Run Code Online (Sandbox Code Playgroud)

与之相比:

~$ 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
Run Code Online (Sandbox Code Playgroud)


小智 12

我是一个Python人,而不是Perl,所以我对代码的作用只有一个模糊的概念.但是,当您看到队列时,请务必小心.Python有一个线程安全的队列,看起来像Perl也是如此.它们非常棒,因为它们可以为您提供线程安全性,但它们通常涉及大量昂贵的锁定和解锁队列,这可能是您所有时间的所在.

  • 顺便说一下,CPython有一个"GIL"(全局解释器锁)的概念,它本质上使得CPython无法用于"线程性能"(它不会跨核心扩展),尽管python中的线程仍可用于绕过限制阻塞(系统)调用.(这不包括调用与GIL无关的线程感知C扩展的情况,当然). (3认同)

noc*_*ura 7

你有几个处理器?通常,当线程数>处理器数时,任何计算密集型任务都会变慢.这是因为在线程之间切换是很昂贵的("上下文切换").上下文切换涉及停止1个线程,保存其上下文,然后将另一个线程的上下文放入处理器中,以便它可以运行.一切都是为了什么?所以线程A可以计算12321是否可以被7整除而不是线程B?

如果你有2个触发器,我敢打赌,2个线程的版本可能是最快的,4个触发器 - >使用4个线程,等等.