是否可以避免 for 循环来计算矩阵条目
Is it possible to avoid the for-loop to compute matrix entries?
我必须使用嵌套的for循环来计算Eigen::MatrixXd类型矩阵输出的条目。这里 input[0]、input[1] 和 input[2] 被定义为 Eigen::ArrayXXd,以便使用元素运算。这部分似乎是我代码的瓶颈。谁能帮我加速这个循环?谢谢!
for (int i = 0; i < r; i++) {
for (int j = 0; j < r; j++) {
for (int k = 0; k < r; k++) {
output.col(i * (r * r) + j * r + k) =
input[0].col(i) * input[1].col(j) * input[2].col(k);
}
}
}
在考虑优化 for 循环的代码时,思考"是否有我可以消除的冗余计算?
请注意,在最内部的循环中,只有k
在变化。您应该将所有不涉及k
的可能计算移出该循环:
for (int i = 0; i < r; i++) {
int temp1 = i * (r * r);
for (int j = 0; j < r; j++) {
int temp2 = j * r;
for (int k = 0; k < r; k++) {
output.col(temp1 + temp2 + k) =
input[0].col(i) * input[1].col(j) * input[2].col(k);
}
}
}
请注意i * (r * r)
是如何一遍又一遍地计算的,但答案总是相同的!您只需在i
增量时重新计算此值。j * r
也是如此.
希望这有帮助!
要减少翻牌次数,您应该缓存 input[0]*input[1]
的结果:
ArrayXd tmp(input[0].rows());
for (int i = 0; i < r; i++) {
for (int j = 0; j < r; j++) {
tmp = input[0].col(i) * input[1].col(j);
for (int k = 0; k < r; k++) {
output.col(i * (r * r) + j * r + k) = tmp * input[2].col(k);
}
}
}
然后,要充分利用您的 CPU,请启用具有 -march=native
的 AVX/FMA,当然还有编译器优化 (-O3
(。
要了解您可以获得更多收益,请准确测量该部分所花费的时间,计算乘法次数(r^2*(n+r*n((,然后计算您每秒实现的浮点运算数。然后将其与 CPU 的容量进行比较。如果你很好,那么唯一的选择是使用多线程一个for循环,例如OpenMP。选择哪个 for 循环取决于输入的大小,但您可以尝试使用外部循环,确保每个线程都有自己的tmp
数组。
相关文章:
- C++方法实现:是否可以避免每次都键入类名?
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- 我可以避免通过time_t打印时间点吗
- 有什么技巧可以避免在模板类中使用"typename"关键字吗
- 在这种情况下,我可以避免使用带有主体的纯虚函数吗?
- 是否可以避免将参数复制到 lambda 函数?
- 是否有一种方法可以避免标头文件中使用的constexpr函数输入全局范围,而无需额外的名称空间
- 浮点计算可以用于任何可靠的函数,特别是容器和算法吗?
- 如果BOOL仅从false到true一次,我可以避免锁定布尔
- 是否有一种方法可以避免在RVALUE和LVALUE参考中创建功能时避免重复的代码
- 在这种情况下是否可以避免使用虚拟方法调用?
- 是否可以避免在前向声明中使用嵌套命名空间?
- 使用GCOV时,是否有一种方法可以避免使用CPP文件中包含的标头文件进行仪器
- 是否可以避免 for 循环来计算矩阵条目
- 在Thrift中,有没有一种方法可以避免生成C++setter
- 我可以避免在std ::变体中明确编写每个结构的构造函数
- 是否可以避免使用lambda中的尾随返回型语法
- 在GPU上调用函数时,我可以避免__device__限定符吗
- 我是否可以避免由特定类定义的限定名称
- 我是否可以避免模板化需要模板化成员的类