融合一个三角形循环并行化,计算子指标
Fusing a triangle loop for parallelization, calculating sub-indices
一个常见的并行化技术是像这样融合嵌套的for循环
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
for(int x=0; x<n*n; x++) {
int i = x/n; int j = x%n;
我想知道如何做到这一点,以融合像这样的三角形循环
for(int i=0; i<n; i++) {
for(int j=0; j<i+1; j++) {
它有n*(n+1)/2
迭代。我们称融合迭代为x
。使用二次公式,我得出了这个:
for(int x=0; x<(n*(n+1)/2); x++) {
int i = (-1 + sqrt(1.0+8.0*x))/2;
int j = x - i*(i+1)/2;
与融合方形循环不同,这需要使用sqrt
函数并从int转换为float和从float转换为int。
我想知道是否有更简单或更有效的方法来做到这一点?例如,不需要sqrt
函数或从int到float或从float到int的转换的解决方案
编辑:我不想要一个依赖于以前或下一个迭代的解决方案。我只想要int i = funci(x) and int j = funcj(x,i)
下面是一些代码,显示这是有效的:
#include <stdio.h>
#include <math.h>
int main() {
int n = 5;
int cnt = 0;
for(int i=0; i<n; i++) {
for(int j=0; j<i+1; j++) {
printf("%d: %d %dn", cnt++, i,j);
}
} printf("n");
int nmax = n*(n+1)/2;
for(int x=0; x<nmax; x++) {
int i = (-1 + sqrt(1.0+8.0*x))/2;
int j = x - i*(i+1)/2;
printf("%d: %d %dn", x,i,j);
}
}
考虑到您正在尝试将三角形与并行化的意图融合在一起,不明显的解决方案是选择x到(i,j)的非平凡映射:
j | i ->
| ____
| | => |\ |
V |___ |_\__|
毕竟,你没有按照任何特殊的顺序处理它们,所以确切的映射是一个不关心的。
所以计算x->i,j
就像你对矩形做的那样,但如果i > j
那么{ i=N-i, j = N-j }
(镜像Y轴,然后镜像X轴)。
____
|\ | | |
|_\__| ==> |_ __ => |
/ | |
/__| |___
最合理的形式当然是第一种形式。
也就是说,融合形式更适合使用条件句:
int i = 0; int j = 0;
for(int x=0; x<(n*(n+1)/2); x++) {
// ...
++j;
if (j>i)
{
j = 0;
++i;
}
}
我想知道是否有更简单或更有效的方法来做到这一点?
是的,你必须开始的代码。请注意以下事项:
- 不存在浮点运算比普通整数更快的情况。 然而,在很多情况下,浮点数比普通整数慢得多。FPU或不FPU
- 在大多数系统中,Float变量通常比普通整数大,因此速度较慢。 第一个版本的代码可能是最友好的缓存内存。对于任何手动优化的情况,这完全取决于您使用的CPU。
- 除法在大多数系统上通常很慢,无论是对纯整数还是浮点数。 任何形式的复杂算术都比简单的计数要慢。
所以对于世界上任何给定的CPU,你的第二个例子几乎保证比第一个例子慢得多。此外,它也是完全不可读的。
相关文章:
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用 MPI 的远程内存访问 (RMA) 功能并行化数据聚合?
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 如何使用 OpenMP 并行化最近邻搜索
- Malloc 在使用线程并行化 SSH 调用时存在问题
- 如何使用 OpenMP 正确并行化 for 循环?
- 如何将矩阵的行随机复制到内存中的另一个矩阵的过程并行化?
- 如何使用 Pthreads 并行化图像翻转?
- MPI:反复并行化缓冲区
- 是否可以使用OpenMP并行化一个列表,该列表可以在每次迭代中添加新元素
- 如何在Visual Studio中并行化armadillo
- 嵌套循环 OpenMP 并行化、私有索引还是公共索引?
- 如何并行化增加循环的大小
- 在 C++ 中使用 OpenMP 并行化两个 for 循环不会提供更好的性能
- OpenMP C++:并行化 for 循环的负载不平衡
- OpenMP 条件并行化 - 并行部分中 if 子句的语法
- 尝试使用 OpenMP 并行化递归函数的冗余计算
- pi 计算的 OpenMP 并行化要么慢,要么错误
- 融合一个三角形循环并行化,计算子指标
- CUDA如何获取网格、块、线程大小和并行化非方阵计算