g++编译器提示在堆栈上进行分配

g++ compiler hints to allocate on stack

本文关键字:分配 堆栈 编译器 提示 g++      更新时间:2023-10-16

是否有任何方法可以向编译器提示某些对象可能具有更静态的行为,并在堆栈而不是堆上分配东西?例如,字符串对象在某些函数中可能具有某种常量大小。我之所以这么问,是因为我正试图通过使用OpenMP来提高应用程序的性能。我已经将串行部分从50秒提高到了20秒,并行性提高到了12秒(提到大多数代码都可以并行运行)。我正在努力继续进步。我认为一个限制与在同一过程中动态内存的连续分配和释放有关。到目前为止,串行优化与合并到更为ANSI C的方法有关,使用更硬编码的变量分配(它们是动态分配的,但考虑到最坏的情况,所以所有东西都分配一次)。现在我几乎陷入了困境,因为我已经完成了代码中有很多C++方法的部分。

标准的std::basic_string模板(std::string是其中的一个专门化)接受分配器作为其第三个参数,您可以提供自己的基于堆栈的分配器而不是std::分配器,但这将是脆弱和棘手的(您可以使用alloca(3)并确保所有分配都是内联的;如果它们不是alloca就不会像你想要的那样工作。)。我不推荐这种方法。

一个更可行的方法可能是拥有自己的竞技场或基于区域的分配器。参见std::allocater_traits

您也许可以简单地在足够大的本地缓冲区(例如char buf[128];)上使用Csnprintf(3)

我认为您正在寻找一个小的缓冲区优化。详细描述可在此处找到。基本思想是向类中添加一个并集,该并集将保存缓冲区:

class string
{
  union Buffer
  {
    char*    _begin;
    char[16] _local;
  };
  Buffer _buffer;
  size_t _size;
  size_t _capacity;
  // ...
};

那么您是在通过使用静态分析来查找性能回归来查找不足之处吗?

这是一个好主意,cppcheck有一些,但这些都是非常初级的。到目前为止,我还不知道有什么工具能做到这一点。

然而,有一些工具可以做不同的事情:

jemalloc

jemalloc有一个分配探查器。(请参见:http://www.canonware.com/jemalloc/)也许这对你有帮助。到目前为止,我自己还没有尝试过,但我希望它能发布对象的生存期和对分配器产生最大压力的对象(首先找到最伤人的部分)。

cacheGrind

Valgrind还有一个缓存和分支预测模拟器。http://valgrind.org/docs/manual/cg-manual.html

叮当声检查

如果您发现自己有太多的空闲时间,可以尝试使用clang-check运行自己的检查工具。

谷歌性能工具

googleperf工具还有一个堆探查器。https://code.google.com/p/gperftools/