r - 多线程为稀疏矩阵赋值时的段错误
问题描述
我打算用从一系列步骤派生的值填充一个稀疏矩阵,以提高效率,OpenMP 用于加速这些进程,我发现它在使用 1 个线程时工作正常,但在多线程时遇到了段错误,我准备了一个简单的演示代码来重现错误,真诚地希望有人能帮我一个忙。
#include <RcppArmadillo.h>
#include <omp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(bigmemory, BH)]]
using namespace std;
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
arma::sp_mat test(arma::vec x, int n, int threads = 1){
omp_set_num_threads(threads);
arma::sp_mat m(n, n);
#pragma omp parallel for schedule(dynamic)
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
m(i, j) = x[i * n + j];
}
}
return m;
}
# run
a<-test(sample(c(0,1,2),100*100,rep=T), n=100, threads=1)
a<-test(sample(c(0,1,2),100*100,rep=T), n=100, threads=10)
解决方案
tl;博士:你不能。
更长的故事:(Rcpp)Armadillo 的主要优势之一是在底层操作之上的非常好的和一致的 API,这些操作介于令人困惑和难以使用之间。缺点之一是我们很容易忽视底层数据结构。
密集矩阵是(基本上总是)固定的内存块。本质上,一个大小为行 x 列的向量。这使我们能够在 R 和 (Rcpp)Armadillo 之间进行有效的“零拷贝”传输。它还允许我们同时处理不重叠的块。这很重要,例如RcppParallel 充分利用了它。OpenMP 在这里工作。
稀疏矩阵是(我在这里简化)具有相互依赖关系的动态列表/向量类型。所以并发工作根本无法工作。伤心。但事实就是如此。一旦您更仔细地查看稀疏矩阵的常见数据结构(如R 的 Matrix 包所做的那样),就会清楚。例如,这个维基百科的文章是一个相当不错和彻底的介绍。
推荐阅读
- python - TypeError:函数接受 1 个位置参数,但给定了 2 个 kivy python
- stm32 - STM32 | SPI从机发送数据的问题
- excel - 在 Excel 上加载 PowerPoint 对象库 - “加载 dll 时出错”
- c++ - 如何将文本从网站复制到 C++ 中的字符串?
- python - gspread:有没有办法将字典加载到 sheet.update_cells() 中?
- python - 熊猫信息未显示所有列和数据类型
- java - 识别 Spring WebClient 使用的 UriBuilder 实现
- r - 在 fanplot 包中创建扇形图
- r - 微阵列元分析和跨平台
- azure - 如何从 azure 门户下载 json 格式而不是 csv 的活动日志