对于 gcc,这个答案告诉我们如何验证是否执行了链接时优化。对于 clang,我看不到任何类似于 的条目.gnu.lto。
更具体地说,我有一个二进制文件,我非常确定 LTO 应该有显着的好处,但我什么也没看到。我想知道 cmake 是否真的做了正确的事情。
有没有办法通过查看二进制文件或 *.o 文件来判断 clang 是否执行了 LTO?
打开整个程序(也称为链接时)优化后,内联是否会受到方法实现位置的影响?
如果没有打开整个程序优化,在标头中公开声明但在匹配的 cpp 中实现的方法显然无法在编译不同的翻译单元(包含上述标头的不同 cpp)期间内联。因此,如果您希望该方法可内联,则必须在导出标头中实现它。
通过整个程序优化,无论该方法是否在标头中实现,在内联方面是否有任何区别?也就是说,编译器是否有可能错过内联在 cpp 中实现的方法的机会,而如果该方法是在标头中实现的,则编译器不会错过这个机会?
-flto我对 Apple 的 Clang (标志)和 Visual Studio (/GL标志)的答案特别感兴趣。
我在使用参数构建的Windows上使用Mingw-w64 v7 和g++ 10.2 。我已经从这里下载并解压了bzip2 1.0.6:https : //sourceforge.net/projects/bzip2/。现在我在MSys2控制台中像这样构建boost 1.76.0 :--mode=gcc-10.2.0 --arch=x86_64 --buildroot=/c/mingw-builds/BuildRoot --update-sources --exceptions=seh --threads=posix --enable-languages=c++ --jobs=48 --rt-version=v7
./bootstrap.sh --with-libraries=iostreams --prefix=c:/Libraries/boost_1_76_0/InstallRelease
./b2 --layout=system variant=release link=shared address-model=64 threading=multi optimization=speed runtime-link=shared -s BZIP2_SOURCE=C:/Libraries/bzip2-1.0.6 install
我想使用Boost.Iostreams用bzip2压缩一些流。因此,我创建了一个包含以下内容的测试文件 main.cpp:
#include <iostream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
int main() 
{
    {
        std::ofstream file("hello.z", std::ios_base::out | std::ios_base::binary);
        boost::iostreams::filtering_ostream out;
        out.push(boost::iostreams::bzip2_compressor());
        out.push(file);
        
        out << "Hello World!" << std::endl;
    }
    {
        std::ifstream file_in("hello.z", …c++ segmentation-fault boost-iostreams mingw-w64 link-time-optimization
我在 CMake 3.14.0 中有以下项目,它为 Visual Studio 2017 64 位生成器构建一个项目(最低版本为 3.10.0,因为其他开发人员可以拥有以前版本的 CMake,但大于 3.9.0):
cmake_minimum_required (VERSION 3.10.0)
project (data)
add_definitions (-DDATA_EXPORTS)
include_directories (${CMAKE_CURRENT_SOURCE_DIR}/..)
set (PROJECT_SRC
  Player.cpp
  LLA.cpp
  Attitude.cpp
  )
add_library (${PROJECT_NAME} SHARED ${PROJECT_SRC})
target_compile_features (${PROJECT_NAME} PUBLIC cxx_std_17)
# Enable IPO
include(CheckIPOSupported)
check_ipo_supported(RESULT iporesult)
if(iporesult)
  message (STATUS "IPO supported for project ${PROJECT_NAME}")
  set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
我添加了一些命令,用于在 Visual Studio 中添加对 LTO 的支持。我已经看到我必须检查对 IPO 的支持,如果可以,我必须设置INTERPROCEDURAL_OPTIMIZATION属性,这就是我所做的
当我运行该项目时,我收到以下消息(我也在使用 vcpkg,这就是第一行的原因):
[cmake] IPO supported for project data
...
[cmake] CMake Warning (dev) at D:/Projects/vcpkg/scripts/buildsystems/vcpkg.cmake:198 …首先,只是为了避免XY问题:此问题来自https://github.com/cnjinhao/nana/issues/445#issuecomment-502080177。库代码可能不应该这样做(依赖于未使用的全局对象的构造),但是问题更多的是关于它是否是有效的LTO行为,而不是代码质量问题。
展示相同问题的最小代码(未经试验,只是为了使示例更小):
// main.cpp
#include <lib/font.hpp>
int main()
{
    lib::font f;
}
// lib/font.hpp
namespace lib
{
struct font
{
    font();
    int font_id;
};
}
// lib/font.cpp
#include <lib/font.hpp>
#include <lib/font_abstraction.hpp>
namespace lib
{
font::font()
{
    font_id = get_default_font_id();
}
}
// lib/font_abstraction.hpp
namespace lib
{
int get_default_font_id();
void initialize_font();
}
// lib/font_abstraction.cpp
#include <lib/font_abstraction.hpp>
namespace lib
{
static int* default_font_id;
int get_default_font_id()
{
    return *default_font_id;
}
void initialize_font()
{
    default_font_id = new int(1);
}
}
// lib/platform_abstraction.hpp …c++ ×4
clang ×2
c ×1
cmake ×1
compilation ×1
gcc ×1
llvm ×1
lto ×1
mingw-w64 ×1
optimization ×1