相关疑难解决方法(0)

是否允许编译器优化堆内存分配?

考虑以下使用的简单代码new(我知道没有delete[],但它与此问题无关):

int main()
{
    int* mem = new int[100];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否允许编译器优化new呼叫?

在我的研究中,g ++(5.2.0)和Visual Studio 2015不会优化new呼叫,而clang(3.0+)则可以.所有测试都是在启用完全优化的情况下进行的(-O3用于g ++和clang,用于Visual Studio的发布模式).

是不是new在引擎盖下进行系统调用,使编译器无法(并且非法)优化它?

编辑:我现在已经从程序中排除了未定义的行为:

#include <new>  

int main()
{
    int* mem = new (std::nothrow) int[100];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang 3.0不再优化它,但后来的版本确实如此.

编辑2:

#include <new>  

int main()
{
    int* mem = new (std::nothrow) int[1000];

    if (mem != 0)
      return 1;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang总是返回1.

c++ optimization gcc clang language-lawyer

66
推荐指数
4
解决办法
4867
查看次数

内存是否泄漏了C++中的"未定义行为"类问题?

事实证明,许多无辜的东西都是C++中未定义的行为.例如,一旦一个非空的指针已被delete"D 甚至在打印的是指针的值是未定义的行为.

现在内存泄漏肯定是坏事.但他们是什么类的情况 - 定义,未定义或其他类别的行为?

c++ memory-leaks memory-management undefined-behavior

14
推荐指数
5
解决办法
1898
查看次数

内存分配由编译器优化

在他的演讲"效率与算法,性能与数据结构"中,Chandler Carruth谈到了在C++中需要更好的分配器模型.当前的分配器模型侵入了类型系统,因此很难在许多项目中工作.另一方面,Bloomberg分配器模型不会入侵类型系统,而是基于虚函数调用,这使得编译器无法"看到"分配并对其进行优化.在他的演讲中,他谈到编译器重复删除内存分配(1:06:47).

我花了一些时间来找到一些内存分配优化的例子,但我发现这个代码示例,在clang下编译,优化掉所有的内存分配,只返回1000000而不分配任何东西.

template<typename T>
T* create() { return new T(); }

int main() {
    auto result = 0;
    for (auto i = 0; i < 1000000; ++i) {
        result += (create<int>() != nullptr);
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

以下论文http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3664.html也说分配可以在编译器中融合,似乎表明一些编译器已经做了那种排序东西的.

由于我对高效内存分配的策略非常感兴趣,我真的很想理解为什么Chandler Carruth反对Bloomberg模型中的虚拟调用.上面的例子清楚地表明,clang可以在看到分配时优化.

  1. 我希望有一个"真实代码",这个优化是有用的,并且由任何当前的编译器完成
  2. 您是否有任何代码示例,其中不同的分配由anu当前编译器融合?
  3. 你是否理解Chandler Carruth在1:06:47他的讲话中说编译器可以"重复删除"你的分配时的含义?

c++ memory optimization memory-management allocation

8
推荐指数
1
解决办法
1007
查看次数

Visual C++优化选项 - 如何改进代码输出?

是否有任何选项(/ O2除外)来改进Visual C++代码输出?在这方面,MSDN文档非常糟糕.请注意,我不是在询问项目范围的设置(链接时优化等).我只对这个特殊的例子感兴趣.

相当简单的C++ 11代码如下所示:

#include <vector>
int main() {
    std::vector<int> v = {1, 2, 3, 4};
    int sum = 0;
    for(int i = 0; i < v.size(); i++) {
        sum += v[i];
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

Clang的libc ++输出非常紧凑:

main: # @main
  mov eax, 10
  ret
Run Code Online (Sandbox Code Playgroud)

另一方面,Visual C++输出是一个多页面的混乱.我在这里遗漏了什么,还是VS真的很糟糕?

编译器资源管理器链接:https: //godbolt.org/g/GJYHjE

c++ visual-c++ c++11 cl

8
推荐指数
1
解决办法
1744
查看次数

new不分配内存

这应该每秒填充我的记忆大约100 MB.我用gnome-systemmonitor和htop跟踪内存.但不知怎的,它没有.为什么?

#include "unistd.h"
#include <iostream>

int main(int argc, char *argv[])
{
    while (true){
        std::cout << "New one" << std::endl;
        new char[100000000];
        sleep(1);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

跑步:

g++ -std=c++11 -O0  main.cpp; ./a.out  
Run Code Online (Sandbox Code Playgroud)

c++ memory

4
推荐指数
1
解决办法
192
查看次数

C++ clang数组比clang向量和gcc向量和数组快得多

下面的代码显示了我的测试用例.我用clang ++ --std = c ++ 11 -O2和g ++ --std = c ++ 11 -O2编译了两者.


long long *ary = new long long[100000000]();
for (long long i = 0; i < 100000000; ++i)
    ary[i] = i;
Run Code Online (Sandbox Code Playgroud)
std::vector<long long> vec(100000000, 0);
for (long long i = 0; i < 100000000; ++i)
    vec[i] = i;
Run Code Online (Sandbox Code Playgroud)

对于我来说,我只进行了初始化测试,然后是初始化和for循环.结果如下:

GCC:

  • 仅限阵列初始化:0.182秒
  • 数组初始化和for循环:0.250s
  • 仅矢量初始化:0.169s
  • 向量初始化和for循环:0.252

铛:

  • 仅限阵列初始化:0.004s
  • 数组初始化和for循环:0.004s
  • 仅矢量初始化:0.150
  • 矢量初始化和for循环:0.240s

gcc结果与传统认为向量与数组一样快.而且,矢量的clang和gcc结果非常一致.然而,铿锵声的结果是荒谬的,阵列表现得相当快.任何人都知道为什么会这样?

arrays performance gcc clang c++11

3
推荐指数
1
解决办法
666
查看次数