相关疑难解决方法(0)

clang vs gcc - 优化包括operator new

我有一个我正在测试的简单示例,我注意到当涉及operator new时,gcc优化(-O3)似乎不如clang那样好.我想知道可能是什么问题,是否有可能迫使gcc以某种方式生成更优化的代码?

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;
}


#clang3.6++ -O3 -s --std=c++11 test.cpp
#size a.out
   text    data     bss     dec     hex filename
   1324     616       8    1948     79c a.out
#time ./a.out 
real 0m0.002s
user 0m0.001s
sys  0m0.000s

#gcc4.9 -O3 -s --std=c++11 test.cpp
#size a.out
   text    data     bss     dec     hex filename
   1484 …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang compiler-optimization c++11

7
推荐指数
3
解决办法
1409
查看次数

为什么允许 C++ 编译器优化具有副作用的内存分配?

另一个问题讨论优化器删除对以下调用的合法性new是否允许编译器优化堆内存分配?。我已阅读问题、答案和N3664

根据我的理解,编译器可以在“as-if”规则下删除或合并动态分配,即,相对于标准中定义的抽象机,结果程序的行为就像没有进行任何更改一样。

我测试了使用 clang++ 和 g++ 编译以下两个文件程序以及-O1优化,但我不明白如何允许删除分配。

// main.cpp
#include <cstdio>

extern int g_alloc;

static int* foo(int n)
{
  // operator new is globally overridden in the other file.
  return new int(n);
}

int main(int argc, char** argv)
{
  foo(argc);
  foo(argc*2);
  printf("allocated: %d\n", g_alloc);
  return g_alloc;
}
Run Code Online (Sandbox Code Playgroud)
// new.cpp
#include <cstdio>
#include <cstdlib>
#include <new>

int g_alloc = 0;

void* operator new(size_t n)
{
  g_alloc += n;
  printf("new %lu\n", n);
  return malloc(n); …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

7
推荐指数
1
解决办法
344
查看次数

为什么gcc缺乏在本地上下文中优化堆分配?

请考虑以下简化示例:

#include <utility>
#include <memory>

int test_lack()
{
    auto lam = []
    {
        return 10;
    };

    // move lam to the heap
    void* ptr = new decltype(lam)(std::move(lam));

    // retrieve the result of lam
    int res = (*static_cast<decltype(lam)*>(ptr))();

    if (ptr) // important
        delete static_cast<decltype(lam)*>(ptr);

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

GCC 5.2 -O3将其编译为:

test_lack():
  sub   rsp, 8
  mov   edi, 1
  call  operator new(unsigned long)
  mov   esi, 1
  mov   rdi, rax
  call  operator delete(void*, unsigned long)
  mov   eax, 10
  add   rsp, 8
  ret
Run Code Online (Sandbox Code Playgroud)

Clang …

c++ optimization gcc

6
推荐指数
0
解决办法
90
查看次数

我想我能理解N4140中的§5.3.4/ 11,但是扩展的分配函数的概念对我来说是不可理解的

以下两段是从N4140复制的(重点是我的).

§5.3.4/ 11:

当一个新的表达式调用的分配功能和分配已经 被延长,则新的表达通过的空间要求的分配的功能类型的第一个参数的量std::size_t.该参数不得小于正在创建的对象的大小; 仅当对象是数组时,它可能大于正在创建的对象的大小.对于数组charunsigned char,new-expression的结果之间的差异并且分配函数返回的地址应该是任何对象类型的最严格的基本对齐要求(3.11)的整数倍,该对象类型的大小不大于正在创建的数组的大小.[注意:因为假定分配函数返回指向存储的指针,该存储适当地对齐具有基本对齐的任何类型的对象,所以这种对数组分配开销的约束允许分配字符数组的常用习惯用法,稍后将放置其他类型的对象. - 尾注]

§5.4.3/ 12

当一个新的表达式调用的分配功能和分配 被延长,其尺寸参数来分配呼叫不得超过上述指定尺寸被省略呼叫的总和,再加上大小为扩展呼叫有它未被扩展,加上在分配的内存中对齐已分配对象所需的任何填充.

我可以理解§5.3.4/ 11,但如上文§5.4.3/ 12所述,扩展的分配函数的概念对我来说是不可理解的.

c++ new-operator language-lawyer c++14

6
推荐指数
1
解决办法
273
查看次数

在针对 C++ (CLion) 的 GCC 编译器中进行优化时,不同构建类型有何差异?

仅供参考:我在 CLion。这只是我好奇的事情,但我编写了一个程序来使用我所有的内存来娱乐。它创建了一个int* array = new int[3'900'000'000]{};.

当我在调试构建选项中运行该程序时,它确实使用了我的所有内存。但在发布模式下,它不会耗尽我的任何内存。我什至尝试修改数组中的某些值,看看这是否会强制编译器创建完整的数组。在发布模式下,我还尝试使用该方法fill并手动使用for循环来填充数组中的每个数字。

c++ ram gcc compiler-optimization clion

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

与使用模板函数相比,使用“function”对象的代码的执行速度

我知道这std::function是用类型擦除惯用法实现的。类型擦除是一种方便的技术,但它的缺点是它需要在堆上存储底层对象的寄存器(某种数组)。

因此,当创建或复制function对象时,需要进行分配,因此该过程应该比简单地将函数作为模板类型进行操作要慢。

为了检查这个假设,我运行了一个测试函数,该函数累积n = cycles连续的整数,然后将总和除以增量数n。首先编码为模板:

#include <iostream>
#include <functional>
#include <chrono>
using std::cout;
using std::function;
using std::chrono::system_clock;
using std::chrono::duration_cast;
using std::chrono::milliseconds;

double computeMean(const double start, const int cycles) {
    double tmp(start);
    for (int i = 0; i < cycles; ++i) {
        tmp += i;
    }
    return tmp / cycles;
}

template<class T>
double operate(const double a, const int b, T myFunc) {
    return myFunc(a, b);
}
Run Code Online (Sandbox Code Playgroud)

main.cpp

int …
Run Code Online (Sandbox Code Playgroud)

c++ templates functional-programming function-object c++11

0
推荐指数
1
解决办法
81
查看次数