我正在尝试将前向-后向算法多线程化,以计算边缘概率。这将作为训练CRF的一个子模块。以下是针对单个示例进行CRF训练的前向部分的伪代码(来源自这里)。
for i in 0 .. T-1: for j in 1 ... N: for k in 1 ... N: p = alpha[(i-1)][k] + trans[k][j] + obvs[j][i] alpha[i][j] = logadd(alpha[i][j], p)
我的计划是使用N个线程(在我的用例中,N最多为10,这是合理的)来独立计算alpha矩阵的列,并在完成每行计算后通过一个屏障进行同步,但实际上这比原始的顺序代码运行得更慢。
我认为同步机制带来的开销是导致这个问题的根源,因为我使用的是线程池和可重用的屏障来处理所有操作。是否有更好的设计方案我应该考虑,或者由于N值较小,不值得并行计算alpha的列?
回答:
导致我代码变慢的原因是使用了多线程库而不是Python的多进程库。由于GIL(全局解释器锁)的性质,实际上每次只能有一个线程在运行。对于一个计算受限且不需要任何IO操作的程序来说,这是非常低效的。上下文切换只会让我的代码运行得更慢。在不同进程之间共享同步原语是另一个完全不同的问题,我还不确定如何处理…