c++ - 融合三角循环进行并行化,计算子索引

标签 c++ c math for-loop

并行化中的一种常见技术是像这样融合嵌套的 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) 和 int j = funcj(x,一)

这里有一些代码表明这是可行的:

#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 %d\n", 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 %d\n", x,i,j);
    }       
}

最佳答案

考虑到您正试图融合一个三角形以实现并行化,非显而易见的解决方案是选择 x 到 (i,j) 的非平凡映射:

j |\ i ->
  | \             ____
| |  \    =>    |\\   |
V |___\         |_\\__|

毕竟,您没有按任何特殊顺序处理它们,因此无需关心确切的映射。

所以像计算矩形一样计算 x->i,j,但是如果 i > j 那么 { i=N-i, j = N-j }(镜像Y轴,然后镜像X轴)。

   ____
 |\\   |      |\           |\
 |_\\__|  ==> |_\  __  =>  | \
                  / |      |  \
                 /__|      |___\

关于c++ - 融合三角循环进行并行化,计算子索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24013832/

相关文章:

c++ - _mm_shuffle_ps 即使包含 header 也未声明

c - 释放分配的内存时堆损坏 (C)

c - malloc 优缺点的宏包装器

Python2 math.fsum 不准确?

c++ - 数据转换解决方案

c++类 friend

在 beaglebone 中创建服务器套接字

java - groovy 的矩阵库

javascript - Angular 的平方根

c++ - 在 C++ 中使用有界数组的正确方法是什么?