在多维数组的Leu中使用哈希表

时间:2015-09-16 00:18:01

标签: c arrays multidimensional-array hash neural-network

编辑:找到解决方案!与评论者建议的一样,使用memset是一种非常好的方法。用

替换整个for循环

memset(lookup->n, -3, (dimensions*sizeof(signed char)));

,其中

long int dimensions = box1 * box2 * box3 * box4 * box5 * box6 * box7 * box8 * memvara * memvarb * memvarc * memvard * adirect * tdirect * fs * bs * outputnum;

简介

现在,我正在寻找一个for循环的野兽:

    for (j = 0;j < box1; j++)
        {
            for (k = 0; k < box2; k++)
            {
                for (l = 0; l < box3; l++)
                {
                    for (m = 0; m < box4; m++)
                    {
                        for (x = 0;x < box5; x++)
                        {
                            for (y = 0; y < box6; y++)
                            {
                                for (xa = 0;xa < box7; xa++)
                                {
                                    for (xb = 0; xb < box8; xb++)
                                    {
                                        for (nb = 0; nb < memvara; nb++)
                                        {
                                            for (na = 0; na < memvarb; na++)
                                            {
                                                for (nx = 0; nx < memvarc; nx++)
                                                {
                                                    for (nx1 = 0; nx1 < memvard; nx1++)
                                                    {
                                                        for (naa = 0; naa < adirect; naa++)
                                                        {
                                                            for (nbb = 0; nbb < tdirect; nbb++)
                                                            {
                                                                for (ncc = 0; ncc < fs; ncc++)
                                                                {
                                                                    for (ndd = 0; ndd < bs; ndd++)
                                                                    {
                                                                        for (o = 0; o < outputnum; o++)
                                                                        {
                                                                            lookup->n[j][k][l][m][x][y][xa][xb][nb][na][nx][nx1][naa][nbb][ncc][ndd][o] = -3;     //set to default value

                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

问题

在主运行的每个循环中调用此循环,以将值重置为初始状态。不幸的是,程序结构必须将这么多值保存在单个数据结构中。

这是踢球者:对于每60秒的程序运行时间, 57秒单独使用此功能

问题

我的问题是:哈希表是否适合替代线性数组?该数组具有O(n ^ 17)基数,但哈希表具有O(1)的理想值。

  • 如果是这样,你会推荐什么哈希库?该程序在C中,没有本机哈希支持。
  • 如果没有,你会推荐什么?
  • 您能否提供一些关于您认为应如何实施的伪代码?

注释

  1. OpenMP用于尝试并行化此循环。许多实现只会导致运行时间略有增加。
  2. 内存使用不是特别重要的问题 - 此程序旨在在疯狂的高规格计算机上运行。
  3. 我们是学生研究人员,进入一个迄今为止未知的优化和并行化世界 - 请耐心等待我们,并感谢您的帮助

1 个答案:

答案 0 :(得分:2)

Hash vs Array

正如评论所指出的那样,数组在这里应该不是问题。查找具有已知偏移量的数组 O(1)

瓶颈

在我看来,这里的大部分工作(以及它很慢的原因)是内循环中指针去引用的数量。

要更详细地解释一下,请考虑以下代码中的myData[x][y][z]

for (int x = 0; x < someVal1; x++) {
   for (int y = 0; y < someVal2; y++) {
      for (int z = 0; z < someVal3; z++) {
         myData[x][y][z] = -3; // x and y only change in outer-loops.
      }
   }
}

要计算-3的位置,我们会进行查找并添加一个值 - 一次用于myData[x],然后再次转到myData[x][y],再一次用于myData[x][y][z] 1}}。

由于此查找位于循环的最内部,因此我们有冗余读取。正在重新计算myData[x]myData[x][y],即使只有z的值正在发生变化。查找是在上一次迭代期间执行的,但结果未存储。

对于你的循环,每次迭代都会计算多个层次的查找,即使只有o的值在该内循环中发生变化

瓶颈的改进

为每个循环迭代进行一次查找,每个循环级别,只需存储中间查找。使用int*作为间接(虽然任何类型都适用于此处),上面的示例代码(使用myData)将变为:

int **a, *b;
for (int x = 0; x < someVal1; x++) {
   a = myData[x]; // Store the lookup.
   for (int y = 0; y < someVal2; y++) {
      b = a[y]; // Indirection based on the stored lookup.
      for (int z = 0; z < someVal3; z++) {
         b[z] = -3; // This can be extrapolated as needed to deeper levels.
      }
   }
}

这只是示例代码,可能需要进行小的调整才能进行编译(强制转换等等)。请注意,使用此方法与三维数组可能没有任何优势。但是,对于具有简单内循环操作(例如赋值)的17维大型数据集,这种方法应该会有所帮助。

最后,我假设您实际上并不只是分配-3的值。您可以使用memset更有效地实现该目标。