堆解决方案优于堆栈?

时间:2013-05-29 06:58:44

标签: c++ c

我正在对C模拟进行编码,其中,给定一系列要验证的规则,我们将其分解为“切片”并验证每个切片。 (基本思想是顺序很重要,规则的实际含义受到上面某些规则的影响;我们可以为每个规则制作一个“切片”,只有与它重叠的那些规则。我们然后验证切片,通常比整个序列小得多。)

我的问题如下。

我有一个struct(policy),它包含一个struct(规则)数组和一个int(length)。 我最初的实现使用了malloc和realloc:

struct{
  struct rule *rules;
  int length;
}policy;
...
struct policy makePolicy(int length)
{
  struct policy newPolicy;
  newPolicy.rules = malloc(length * sizeof(struct rule));
  newPolicy.length = length;
  return newPolicy;
}
...
struct policy makeSlice(struct policy inPol, int rulePos)
{
  if(rulePos > inPol.length - 1){
    printf("Slice base outside policy \n");
    exit(1);
   }
  struct slice = makePolicy(inPol.length);
  //create slice, loop counter gets stored in sliceLength
  slice.rules = realloc(slice.rules, sliceLength * sizeof(struct rule));
  slice.length = sliceLength;
  return slice;
}

由于这使用malloc的内存,我假设它大量使用堆。 现在我正在尝试移植到一个没有malloc的实验性并行机器。

我很遗憾地用固定大小的数组分配了所有内容。

现在这是令人震惊的。

新代码运行速度较慢。慢得多。

(原始代码用于在切片长度为200时结束等待分钟,也可能在300以上时等待一小时...现在当切片长度为70,80时已经这样做了...花费数小时说120.仍然不是200。)

唯一的问题是,现在切片被赋予与完整策略相同的内存(MAXBUFLEN为10000),但整体似乎没有内存耗尽。 'top'表示消耗的总内存非常适中,数十兆字节范围与以前一样。 (当然,当我存储长度时,我并没有遍历整个事物,只是具有真实规则的部分。)

有人可以帮忙解释为什么它突然变得如此之慢?

1 个答案:

答案 0 :(得分:3)

似乎当你将结构的大小固定为更大的大小(例如10000个规则)时,你的缓存局部性可能会比原始局部性差得多。您可以使用分析器(Valgrind中的oprofile或cachegrind)来查看缓存是否有问题。

在原始程序中,一个缓存行最多可以容纳8 struct policy(在具有64byte缓存行的32位机器上)。但是在修改后的版本中,它只能容纳一个,因为它现在比缓存行大小要大得多。

在这种情况下,向上移动length字段可以提高性能,因为现在length和前几个struct rule可以放入单个缓存行中。

struct policy{
  int length;
  struct rule rules[10000];
};

要解决此问题,您需要编写自己的自定义分配器以确保缓存位置。如果您正在编写此程序的并行版本,还要记住将不同线程使用的内存隔离到不同的缓存行中,以避免缓存行争用。