Rer*_*umu 135 c c++ benchmarking
当使用相同的代码时,只需更改编译器(从C编译器到C ++编译器)将更改分配的内存量。我不太确定为什么会这样,并且想进一步了解。到目前为止,我得到的最好的答复是“可能是I / O流”,它的描述性不是很强,这使我对C ++的“不用付钱,不用付钱”感到好奇。
我正在使用分别为7.0.1-8和8.3.0-6的Clang和GCC编译器。我的系统在最新的Debian 10(Buster)上运行。基准通过Valgrind Massif完成。
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所使用的代码不会更改,但是无论我是以C还是C ++进行编译,它都会更改Valgrind基准测试的结果。但是,这些值在编译器之间保持一致。该程序的运行时分配(峰值)如下:
为了进行编译,我使用以下命令:
clang -O3 -o c-clang ./main.c
gcc -O3 -o c-gcc ./main.c
Run Code Online (Sandbox Code Playgroud)
clang++ -O3 -o cpp-clang ./main.cpp
g++ -O3 -o cpp-gcc ./main.cpp
Run Code Online (Sandbox Code Playgroud)
对于Valgrind,我运行valgrind --tool=massif --massif-out-file=m_compiler_lang ./compiler-lang
每种编译器和语言,然后ms_print
显示峰。
我在这里做错什么了吗?
Nik*_* C. 148
堆用法来自C ++标准库。它在启动时分配内存供内部库使用。如果您不反对它,则C和C ++版本之间的差应该为零。使用GCC和Clang,可以使用以下命令编译文件:
g ++ -Wl,-根据需要main.cpp
这将指示链接器不要链接未使用的库。在您的示例代码中,未使用C ++库,因此它不应链接到C ++标准库。
您也可以使用C文件进行测试。如果您使用:
gcc main.c -lstdc ++
即使您已经构建了C程序,也会重新显示堆使用情况。
堆的使用显然取决于您正在使用的特定C ++库实现。在您的情况下,这就是GNU C ++库libstdc ++。其他实现可能不分配相同数量的内存,或者根本不分配任何内存(至少在启动时不分配)。例如,LLVM C ++库(libc ++)在启动时不进行堆分配,至少在Linux上不这样机:
clang ++ -stdlib = libc ++ main.cpp
堆的使用与完全不针对它进行链接相同。
(如果编译失败,则可能未安装libc ++。程序包名称通常包含“ libc ++”或“ libcxx”。)
Ste*_*ebb 15
GCC和Clang都不是编译器-它们实际上是工具链驱动程序。这意味着它们将调用编译器,汇编器和链接器。
如果使用C或C ++编译器编译代码,则将产生相同的程序集。汇编器将产生相同的对象。区别在于,工具链驱动程序将为两种不同的语言向链接器提供不同的输入:不同的启动程序(C ++需要代码来执行在名称空间级别具有静态或线程本地存储持续时间的对象的构造函数和析构函数,并且需要用于堆栈的基础结构例如在异常处理期间支持展开的框架,C ++标准库(在命名空间级别还具有静态存储持续时间的对象)以及可能的其他运行时库(例如,具有堆栈展开基础结构的libgcc)。
简而言之,不是编译器引起了占用空间的增加,而是您通过选择C ++语言选择使用的东西的链接。
C ++确实具有“只为所用内容付费”的理念,但是通过使用这种语言,您可以为此付费。您可以禁用部分语言(RTTI,异常处理),但是随后您将不再使用C ++。如另一个答案中所述,如果您根本不使用标准库,则可以指示驱动程序将其忽略(--Wl,-按需),但是如果您不打算使用任何功能,关于C ++或其库,为什么还要选择C ++作为编程语言?