按行向Eigen :: MatrixXd进行线程安全写入 [英] Thread-safe writing to Eigen::MatrixXd by row

查看:146
本文介绍了按行向Eigen :: MatrixXd进行线程安全写入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单,希望也有一个不错的答案:当我构造了 Eigen :: MatrixXd 矩阵时,我可以使用多个线程来填充行吗?同时矩阵(如果我可以确保没有并发写入任何行),还是必须在每个线程中创建临时行对象,然后将它们复制(哦...)作为归约操作复制到矩阵中? / p>

My question is very simple, and hopefully has a nice answer too: When I have a constructed Eigen::MatrixXd matrix, can I use multiple threads to populate rows in the matrix at the same time (if I can assure that no rows are being concurrently written), or must I create temporary row objects in each thread, and then copy (ugh...) them into the matrix as a reduce operation?

推荐答案

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

While it may be thread safe in terms of not writing to the same address from different threads, because Eigen::MatrixXd is of column major storage, you will likely be wrecking havoc on the cache (basically, it's false sharing). It may be faster to create a temporary row major matrix and then copying it over to the column major matrix.

或者(也可以是更好的IMO),您可以在将您现有的矩阵作为行(确保尺寸已切换/匹配),然后执行 m.transposeInPlace() 。取决于矩阵的形状和对齐方式,这可能比 m = m.transpose()。eval()更有效。

Alternatively (and better IMO), you can treat the columns in your existing matrix as rows (make sure the dimensions are switched/match) and then do a m.transposeInPlace(). Depending on the matrix shape and alignment, this may be more efficient than m = m.transpose().eval().

如果矩阵足够大并且ID从零开始且连续(例如,使用OMP或类似功能,则不是),也可能使用线程的ID std :: thread ,而无需自己跟踪不同的ID)。
这还需要对矩阵进行填充,以使行数是缓存行大小的倍数,并且每一列都从对齐的内存块开始。
假定缓存行是64个字节。如果处理整数倍的块,则可以避免错误共享,因为每个线程仅接触其自己的高速缓存行。如果可以这样做,则应该没有多余的临时文件或副本/交换。

Also may be possible to use the threads' IDs if the matrix is large enough and the IDs are zero based and consecutive (e.g. with OMP or similar, not e.g. std::thread without keeping track of the different IDs on your own). This also requires padding the matrix so that the number of rows is a multiple of the cache line size and each column starts at an aligned block of memory. Assume the cache line is 64 bytes. If you treat blocks of an integer multiple of that, then you could avoid false sharing, as each thread only touches its "own" cache lines. If you can do this, then there should be no extra temporaries or copies/swaps.

这篇关于按行向Eigen :: MatrixXd进行线程安全写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆