You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RSA加密并行计算中大量Sparks被GC回收的原因是什么?

问题分析:par/pseq并行失效与Par monad的优势

为什么par/pseq实现中大量Sparks被GC回收?

你的auxPar1实现没有真正让m1和m2并行计算,核心问题出在求值顺序和par的特性上:

  1. par的“提示”而非强制特性:par只是向运行时发出“可以并行计算m1”的提示,但不保证一定会并行执行。当主线程后续需要m1的值时,如果对应的spark还没被工作线程调度执行,主线程会直接自行计算m1,此时这个spark就失去了存在意义,最终被GC回收。
  2. m2的同步求值逻辑:m2 pseq m强制主线程先完成m2的计算,再推进到m的计算。而m依赖m1,所以主线程在算完m2后会立刻去计算m1,完全没给m1的spark留下执行时间。
  3. 无有效并行度:整个过程中m2完全由主线程同步计算,m1的spark也很快被主线程接管,实际并行度几乎为0,导致elapsed时间和total时间差距极小,大量spark因未被使用而被GC回收。

Par monad为什么效果更好?

auxPar4用Par monad实现的并行是显式且可靠的:

  • spawnP会将expmod p c dP和expmod q c dQ两个计算任务提交到Par调度器,调度器会主动将任务分配给空闲工作线程,确保两个计算任务真正并行执行。
  • get操作会阻塞等待对应任务的结果,主线程不会提前自行计算任务内容,避免了par模式下主线程“抢任务”的问题。
  • 从统计结果看,elapsed时间(11.113s)远小于total时间(20.541s),说明多CPU核心被有效利用,并行效果显著。

针对par/pseq的优化建议

如果一定要用par/pseq实现正确并行,需要确保m1和m2都被作为spark提交,并且主线程在需要结果前给足并行调度时间,示例代码如下:

auxPar1Fixed :: Integer -> Integer 
auxPar1Fixed c = 
    let m1 = expmod p c dP
        m2 = expmod q c dQ
        h = (qInv * (m1 - m2)) `mod` p
        m = m2 + h * q
    in m1 `par` m2 `par` (m1 `pseq` m2 `pseq` m)

这里同时将m1和m2作为spark提交,再用pseq强制主线程等待两个结果(或自行计算),能提升并行执行的概率,但这种方式仍依赖GHC运行时调度,可靠性不如Par monad。


内容的提问来源于stack exchange,提问作者Maq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 10:42:29