c++ 蒙宝石:如何写出矩阵-矩阵乘积A=B*c,以便只计算A中的一些元素?

yi0zb3m4  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(153)

我正在计算两个矩阵的乘积,比如A=B×C。但我只关心A中的一些元素,而不是全部。例如,如果E_ij > 0,则需要计算A_ij。是否有任何相关的C/C++或Python库来完成这项任务。
我不能计算出A中的所有元素,因为我必须在更短的时间内计算。任何帮助都很感激。
你试了什么?
特征值:(E > 0).选择(B*C),非常慢.
for循环:ret = B * C

#pragma omp parallel for
for (int i = 0; i < B.rows(); i++){
    vector<int> cal_ind;
    for (int j = 0; j < C.columns(); j++){
        if (E(i, j) > 0){
            cal_ind.push_back(j);
        }
    }
    if (cal_ind.size() == 0){
        continue;
    }
    VectorXd d_xi_c = B.row(i) * C(Eigen::all, cal_ind);
}

blaze:我修改了mmm函数,使它只计算一些元素,但是原始mmm和修改后的mmm都非常慢。
你在期待什么
例如size(A)=(100,100),A中有10,000个元素,如果只需要计算1,000个元素,用什么运算可以在更短的时间内完成这个任务?

1tu0hz3e

1tu0hz3e1#

我不认为你能轻易地实现你想要的:当进行全矩阵乘法时,当前矩阵乘法算法的主要加速来自以下事实:它们逐块地进行乘法,并且利用CPU的SIMD指令,以及针对CPU的各种高速缓存大小进行优化。库中的优化算法比通过3个嵌套循环的简单方法快10 - 100倍。然而,这些算法不是一次计算一个单独的元素,而是一次计算多个元素。(正如我所说:它们按块方式操作。)
如果在您的情况下,您只想计算元素的某个子集,除非元素以系统的方式组织(例如,仅左N列,或前M行,或类似的东西),则将计算限制到仅那些元素的唯一方法是显式地写入所有3个嵌套循环。这将比使用现代库提供的优化GEMM算法效率更低。
您可能最好做的事情大概就是在OpenMP示例中所做的事情,因为您已经将库的产品实现用于最内部的循环。(如果您使用一些巧妙的技巧,您可能会避免为索引向量分配一些内存,但除此之外,我看不到有多少优化潜力。
如果有一些额外的系统对元素(例如几乎所有的集群都在矩阵的特定块中),那么您可以使用该信息针对您的特定用例进行更多的优化。(假设您事先知道此行为,并且不必在运行时检测它。)
但说实话,如果你提供的数字是现实的,并且你正在计算10'000个元素中的1000个元素,那么我认为你永远不会比使用一个像样的库的完整GEMM实现来计算所有元素更快,即使大多数都不需要,只是因为与单独计算元素相比,完整算法提供了多少加速。你要么只需要计算比这个少的元素,要么你需要有一个非常系统的方法来确定需要计算的元素。(这并不依赖于为每个元素单独计算条件。)
也许如果你在这里提供更多关于你想要解决的实际问题的信息,可能会有一个聪明的方法来实现这一点-但当只看矩阵乘法部分时,我怀疑你是否能够加快速度。

相关问题