c++ - 使用 gsl 库并行化线性代数

标签 c++ parallel-processing linear-algebra gsl

在我的 C++ 脚本中,我有许多 for 循环来计算线性代数运算。我想知道使循环并行的最佳方法是什么?一个示例是以下函数,它计算两个矩阵的克罗内克积。

void Kronecker(const gsl_matrix *K, const gsl_matrix *V, gsl_matrix *H) 
{
    for (size_t i=0; i<K->size1; i++) {
        for (size_t j=0; j<K->size2; j++) {
            gsl_matrix_view H_sub=gsl_matrix_submatrix (H, i*V->size1, j*V->size2, V->size1, V->size2);
            gsl_matrix_memcpy (&H_sub.matrix, V);
            gsl_matrix_scale (&H_sub.matrix, gsl_matrix_get (K, i, j));
        }
    }
    return;
}

当我有可以并行的 for 循环 时,我怎样才能提高我的代码的计算时间?

最佳答案

在不知道底层 gsl 调用中的内存布局、分配、系统调用和潜在副作用的情况下,实现并行化的一种真正简单的方法是通过 OpenMP。这当然会引入依赖关系并需要编译器支持,但它对像您这样的简单循环特别有效。未经测试,可能需要更多以确保正确编写 H,但类似于:

#pragma omp parallel for private(i, j)
for (size_t i=0; i<K->size1; i++) {
    for (size_t j=0; j<K->size2; j++) {
        gsl_matrix_view H_sub=gsl_matrix_submatrix (H, i*V->size1, j*V->size2, V->size1, V->size2);
        gsl_matrix_memcpy (&H_sub.matrix, V);
        gsl_matrix_scale (&H_sub.matrix, gsl_matrix_get (K, i, j));
    }
}

参见 https://curc.readthedocs.io/en/latest/programming/OpenMP-C.html了解更多详情。

如果您不想引入依赖关系或有一些其他约束(例如,OpenMP 在库代码中可能有问题),您始终可以通过在线程中使用内部 for 循环来自己完成,启动 N 个线程在开始和结束时加入。这当然是假设您有足够的工作量,如果矩阵足够大,您可能会这样做。

关于c++ - 使用 gsl 库并行化线性代数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73599405/

相关文章:

matlab - 在定义的圆锥区域内创建随机单位向量

c++ - 将 double 降级为 float 时没有警告

c++ - v8、libuv、nodejs、win32 api - 如何调用 EnumWindows 并回调调用 javascript 函数?

c++ - 将表示二进制的字符串转换为表示等效十六进制的字符串

python - 如何始终并行运行 n 个进程,而不等待前 n 个进程完成?

c - 使用 OpenMP 进行分解的并行 GMP-Chudnovsky 中内核的作用

java - 并行流哈希集

c++ - 为什么我的翻译矩阵需要转置?

java - 我需要构造一个带有扩展 header 的 IPv6 数据包。

matlab - 如何在图像上应用 SVD 后检查图像是否被压缩(关于磁盘上压缩图像的大小)