现代 C++ 中有[[likely]]和属性。G++ 和 clang++ 中[[unlikely]]都有相应的__builtin_expect(x, 1)内置函数。__builtin_expect(x, 0)但也有__builtin_unpredictable(x)和__builtin_expect_with_probability(x, 1, 0.5)或(同样)__builtin_expect_with_probability(x, 0, 0.5)内置函数,它告诉编译器防止 CPU 用来自(错误)预测分支的指令填充管道,因为从错误预测路径刷新+恢复管道的成本在统计上大于执行 w/o完全是投机执行。
在和分支上使用[[likely]]或同样[[unlikely]]使用属性(如以下代码片段所示)是否等同于使用假设属性?ifelse[[unpredictable]]
if (x) [[likely]] {
// "if" branch
} else [[likely]] {
// "else" branch
}
Run Code Online (Sandbox Code Playgroud)
或者
if (x) [[unlikely]] {
// "if" branch
} else [[unlikely]] {
// "else" branch
}
Run Code Online (Sandbox Code Playgroud)
据我所知,如果存在,if则编译器默认将分支视为默认情况,如果不存在(因为它通常是从当前函数提前退出的不愉快路径检查的形式)。因此,如果我只是省略任何一个属性,那么它并不等同于指定假设属性。[[likely]]else[[unlikely]]else[[unpredictable]]
c++ compiler-optimization speculative-execution branch-prediction c++-attributes
当我试图从一个大型复杂的例子(在模板实例化方面被修改为更复杂)来自boost精神Qi compiler_tutorial时,我收到以下错误消息:
debug\expression.o:-1: error: section .debug_frame$_ZNK5boost5proto3if_INS0_6detail7has_tagINS0_6tagns_3tag7greaterEEENS0_12reverse_foldINS0_1_ENS0_6_stateENS2_18reverse_fold_tree_IS6_NS_6spirit6detail18make_binary_helperINSC_13meta_compilerINSC_2qi6domainEE12meta_grammarEEEEEEESK_E4implIRNSG_4ruleINSC_3lex7lexertl8iteratorINSR_7functorINSR_14position_tokenIN9__gnu_cxx17__normal_iteratorIPKcSsEENS_3mpl6vectorISsN4mpl_2naES13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_S13_EENS12_5bool_ILb0EEEyEENSR_6detail4dataESZ_NS15_ILb1EEES16_EEEEFSt4listIN7client3ast10expressionIdEESaIS1H_EEvENSC_11unused_typeES1L_S1L_EENS_6fusion4consINSG_12literal_charINSC_13char_encoding8standardELb1ELb0EEENS1O_4nil_EEERS1L_EclES1N_RKS1V_S1W_: string table overflow at offset 10000433
Run Code Online (Sandbox Code Playgroud)
命令行:
c:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.2/cc1plus.exe -quiet -v -I c:/libs/boost/include -I ../src/compiler -I c:/libs/boost/include -I . -I c:/libs/Qt-static/mkspecs/win32-g++-x64-4.7.2-corei7-avx-corei7-avx -iprefix c:\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.2/ -D_REENTRANT -U_REENTRANT -D BOOST_THREAD_POSIX -D BOOST_THREAD_USE_LIB -D UNICODE -D QT_LARGEFILE_SUPPORT -D _DEBUG=1 -D DEBUG=1 -D BOOST_SPIRIT_QI_DEBUG=1 -D BOOST_SPIRIT_NO_PREDEFINED_TERMINALS=1 ../src/compiler/expression.cpp -quiet -dumpbase expression.cpp -m64 -march=corei7-avx -mtune=corei7-avx -mtls-dialect=gnu2 -auxbase-strip debug/expression.o -g -O0 -Wall -Wextra -std=gnu++11 -version -fsignaling-nans -fno-math-errno -frtti -fexceptions -o - |
Run Code Online (Sandbox Code Playgroud)
该平台:x64主机的mingw-builds(x64-4.7.2-release-posix-sjlj-rev5.7z)和-m64x64 Windows 7 HB上具有8GB物理内存的target()(符合gcc 4.7.2).
它看起来像是因为没有足够的内存.
我该怎么做才能避免这个问题?我确信这里没有递归模板.
我在业余时间开发代码。最好在调试模式下。最近,当我尝试构建发行版时,出现错误(运行时,输出:1\n2\n然后失败)。我位于一段代码(下图),其中包含错误,我发现,该错误只发生,当优化级别为-Os, -Ofast, -O2, -O3但不是-O, -O0, -O1, -Og。在发布模式下,我受调试能力的限制。错误原因是什么?查找此类错误的方法是什么?
#!/ usr / bin / env bash -vex WARN =“-W -Wall -Wextra” INCLUDE =“-isystem / c / libs / boost-trunk” OPT =“-O2” g ++ -x c ++--std = gnu ++ 1年$ INCLUDE
$ WARN $ OPT -oa << __ EOF && ./a && echo -e“ \ e [1; 32msucceeded \ e [0m” || 回声-e“ \ e [1; 31mfailed \ e [0m”
#include <iterator>
#include <string>
#include <iostream> …Run Code Online (Sandbox Code Playgroud) 将代码转换为什么的一般提示是constexpr什么?比方说,有一种算法可以对(输入)几何图形进行几何变换.输入和输出因性质和大小而不同,并且非常简单地相互依赖.目前它实现为一个类,目前使用std::map和std::vector(不失一般性).
什么是重构代码的方法,它使用动态内存来获取符合常量表达式要求的代码?
对于每个使用的constexpr容器,我可以想象一些兼容的容器和constexpr兼容的"堆栈分配器"(用于足够大的存储)的组合value_type.但是有一个问题:我从未遇到过这样的容器.但也许还有另外一种方法?
这是真的,即结构化绑定在clang(我用最近建造clang version 4.0.0 (trunk 282683))用一些东西来实现<tuple>,如括号,初始化列表可以使用的东西从<initializer_list>?
我编写了简单的代码只是为了使用一些最新的功能:
struct S { int a; char b; double c; };
auto [a, b, c] = S{1, '2', 3.0};
using A = decltype(a);
using A = int;
using B = decltype(b);
using B = char;
using C = decltype(c);
using C = double;
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,但是当我const之前添加限定符时auto:
struct S { int a; char b; double c; };
const auto [a, b, c] …Run Code Online (Sandbox Code Playgroud) 是否可以将-Wp,-D_FORTIFY_SOURCE=2选项(或=1)与-Og优化级别一起使用?引入的补丁FORTIFY_SOURCE包含一个注释/* Object size checking is only intended for -O[s123]. */。
是2004年。而且我不知道何时-Og引入密钥(可能稍后)。
哪些优化(优化标志)FORTIFY_SOURCE需要?
如何不用循环来实现对位掩码的操作,这两个位掩码a和b宽度的n给位掩码c宽度2 * n有以下特性:
i个位c只能设置是否有j在个位a,并k在第位b和j + k == iC++实现:
#include <bitset>
#include <algorithm>
#include <iostream>
#include <cstdint>
#include <cassert>
#include <x86intrin.h>
std::uint64_t multishift(std::uint32_t a, std::uint32_t b)
{
std::uint64_t c = 0;
if (_popcnt32(b) < _popcnt32(a)) {
std::swap(a, b);
}
assert(a != 0);
do {
c |= std::uint64_t{b} << (_bit_scan_forward(a) + 1);
} while ((a &= (a - 1)) …Run Code Online (Sandbox Code Playgroud) 当编译为支持AVX扩展的处理器(比如-m64 -march=corei7-avx -mtune=corei7-avx适用)时,同时使用-mfpmath=both -mavx密钥是否有意义?没有这么多,它会导致编译器使用三套指令(i87,SSE,AVX在同一时间)?或者只是i87为了标量(在某种意义上)和AVX仅用于向量?
新标准的功能是否会对C++ 11中的boost库实现产生重大影响?
鉴于存在可变参数模板,特别感兴趣的是boost::variant(BOOST_VARIANT_LIMIT_TYPES)和boost::spirit部分库.
有关于此的好文章吗?
是否有可能强制Boost.Spirit Qi以这种方式运行,生成的语法可以根据一些运行时可计算的条件/规则/速率进行调整?例如,输入由语言构造组成,这些构造在解析期间导致不同的替代方案,一些更频繁,另一些 - 更少.但是替代方案的顺序会影响效率,即语法的运行时最优性.在某些情况下,不可能事先确定在任意输入(可能强烈聚集)的情况下将更频繁地选择哪种替代方案.
我知道可以qi::symbols在运行时附加符号,但对于其他一些解析器来说,类似的行为是可取的.