2017-02-17 29 views
2

我的问题很简单,并希望有一个很好的答案:当我有一个构造的Eigen::MatrixXd矩阵,我可以使用多个线程填充行矩阵中的相同时间(如果我可以确保没有行正在同时写入),还是必须在每个线程中创建临时行对象,然后将它们(呃...)复制到矩阵中作为减少操作?线程安全地写入Eigen :: MatrixXd按行

回答

3

虽然它可能是线程安全的,因为不从不同的线程写入相同的地址,因为Eigen::MatrixXd是列主存储器,您可能会破坏缓存(基本上,它是错误的共享)。创建临时行主矩阵然后将其复制到列主矩阵可能会更快。

或者(和更好的国际海事组织),您可以将现有矩阵中的列视为行(确保尺寸切换/匹配),然后执行m.transposeInPlace()。根据矩阵形状和对齐,这可能比m = m.transpose().eval()更有效。

而且可以有可能使用的线程的标识,如果矩阵足够大,ID是零基础,连续的(例如用OMP或类似的,而不是如std::thread没有跟踪不同的ID在你自己)。 这也需要填充矩阵,以便行数是高速缓存行大小的倍数,并且每列都从对齐的内存块开始。 假设缓存线是64字节。如果您将块的整数倍视为块,那么您可以避免错误共享,因为每个线程只会触及其“自己的”缓存行。如果你能做到这一点,那么不应该有额外的临时或副本/掉期。

+0

在Eigen :: MatrixXd上使用Eigen :: RowXpr的情况如何?它是否具有相同的缓存惩罚?我得到了这个工作 - 传递Eigen :: RowXpr - 但事实上,它似乎并没有比创建临时和直接使用那样更快或更好。 – ibell

+0

“问题”是内存的底层布局,以及写入同一缓存行中相邻地址的不同线程,而不是写入表达式的方式。如果您有更具体的问题或问题,您应该发布[mcve]。 –