我刚刚在我的程序上运行了一个并发分析器,发现了一行经常在内存中的线程之间争用的代码,即;
// declarations shown here to clarify type:
size_t const timeSteps;
typedef Eigen::Array<float, Eigen::Dynamic, Eigen::Dynamic> Signal2D;
Signal2D Activations(timeSteps, desc.length()); // this line is contended
请注意,我声明了#define EIGEN_DONT_PARALLELIZE
以避免特征运算的隐式并行化。
上述行在多个线程上并发执行,但desc
实例是线程的本地类。那么,为什么这段代码在线程之间竞争呢?
在VS2013分析器中,它说正在争用的特定代码是Eigen::DenseStorage<float,-1,-1,-1,0>::resize
。为什么会这样?Eigen 是否以某种方式跟踪线程之间创建和销毁了哪些数组?为什么?我该如何关闭它?
我想这是因为这个调整大小函数通过对 malloc 的系统调用来执行内存分配。所以我认为实际问题出在malloc。最好的解决方案是通过预先分配所需的数组来避免动态内存分配,并迁移到更类似于 C 的 API 进行激活()。