我有一个相当简单的C程序,它在一个线程上比在多个线程上运行得快得多。 (我正在使用四核i5处理器。)
通过使用高度科学的"GDB halt debugging"技术,我确定它看起来只有一个线程实际上一次执行。
基本上,当我在GDB中点击^C
并输入info threads
时,我会得到这样的结果:
Id Target Id Frame
29 Thread 0x7ffff5cec700 (LWP 14787) "corr" __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
28 Thread 0x7ffff64ed700 (LWP 14786) "corr" __lll_unlock_wake_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:341
27 Thread 0x7ffff6cee700 (LWP 14785) "corr" 0x00007ffff752ca2c in __random () at random.c:296
26 Thread 0x7ffff74ef700 (LWP 14784) "corr" __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
* 1 Thread 0x7ffff7fd5740 (LWP 14755) "corr" 0x00007ffff78bf66b in pthread_join (threadid=140737342535424, thread_return=0x7fffffffdd80) at pthread_join.c:92
(线程1是主线程;线程26-29是工作线程。)
快速谷歌搜索似乎意味着这些功能与死锁检测有关,但我无法做到这一点。 这些功能是什么,为什么它们会变慢?
可能相关: 如果我在创建它之后立即加入每个线程,并且在创建其他线程之前(即,根本不是多线程,但仍然会产生线程开销),则不会发生此效果,并且我的程序运行得更快。
如果它有用,here's代码转储(159行)。
答案 0 :(得分:3)
你的线程正在争夺随机数生成器。只要一个线程可以访问其上下文,其他线程就必须等到它释放保护它的锁。您应该使用rand_r
(或lrand48_r
,或任何理智的随机数生成器满足您的需要)而不是rand
,因此每个线程都有自己的上下文。