我记得最初的P4微架构的一个有趣的特点是它是双泵ALU.我认为英特尔称它为快速执行单元,但基本上它意味着ALU中的每个执行单元实际上以两倍的频率运行,并且可以在一个周期内处理两个简单的ALU操作,即使它们是依赖的.
这个功能在某些时候消失了(在P4之前或同时),但是有没有一个带有双重转储ALU 的64位 P4?P4的64位变体在2004年推出,大约是在最初的32位发布后的四年,但我不清楚双速ALU是否已经消失.似乎宽度流水线方法用于加倍速度对64位来说很难,这激起了我的好奇心.
由于人们可能仍然需要支持一些(显然很旧的)64位P4硬件,因此了解ALU行为对于优化很有意义.
想象一下,我有一个X宏,用于定义如下内容的项目列表:
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
FN(zip)
Run Code Online (Sandbox Code Playgroud)
这很好用,我可以调用它来生成为每个元素模板化的相同代码,例如:
#define xstr(s) str(s)
#define str(s) #s
#define PRINT_X(E) void print_ ## E () { std::cout << str(E); };
X_MACRO(PRINT_X)
Run Code Online (Sandbox Code Playgroud)
这会void print_foo() { std::cout << "foo"; };为每个X_MACRO元素生成类似的函数.到现在为止还挺好.
但是,现在,我希望X宏元素列表以预处理器宏为条件.例如,zip元素应仅包含在X宏中(如果USE_ZIP已定义).当然,我不能把#ifdefX宏放在里面,比如:
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
#ifdef USE_ZIP
FN(zip)
#endif
Run Code Online (Sandbox Code Playgroud)
我可以改为将列表写两次,一次使用zip,一次不使用,基于USE_ZIP类似:
#ifdef USE_ZIP
#define X_MACRO(FN) \
FN(foo) \
FN(bar) \
FN(zip)
#else
#define X_MACRO(FN) \
FN(foo) \
FN(bar) …Run Code Online (Sandbox Code Playgroud) 考虑一下 C++ 中的这个函数:
void foo(uint32_t *a1, uint32_t *a2, uint32_t *b1, uint32_t *b2, uint32_t *o) {
while (b1 != b2) {
// assert(0 <= *b1 && *b1 < a2 - a1)
*o++ = a1[*b1++];
}
}
Run Code Online (Sandbox Code Playgroud)
其目的应该足够明确。不幸的是,b1包含随机数据并垃圾缓存,成为foo我的程序的瓶颈。无论如何我可以优化它吗?
这是一个 SSCCE,应该类似于我的实际代码:
#include <iostream>
#include <chrono>
#include <algorithm>
#include <numeric>
namespace {
void foo(uint32_t *a1, uint32_t *a2, uint32_t *b1, uint32_t *b2, uint32_t *o) {
while (b1 != b2) {
// assert(0 <= *b1 && *b1 < a2 - …Run Code Online (Sandbox Code Playgroud) 据我所知,memcpy进入未初始化的存储不能安全地用于创建源对象的副本。
但是,在去年 open-std WG21“ub”列表上的这个线程中,参与者提到了新的 memcpy 生命周期启动规则:
这似乎没有上升到错误报告的级别,但它可能与新的 memcpy 生命周期启动规则有关。他们会为源字节和目标字节分配一些静态类型吗?
Based on the context of the question and small amount of type-erasure example code, it appears that it may be related to creating new objects in aligned_storage via memcpy.
Search as I might, I can't find a reference to the new rules. I'm particularly curious if they only apply to replacing the contents of an already created object, or if they change …
有这样一个演讲,CppCon 2016:Chandler Carruth \xe2\x80\x9cGarbage In,Garbage Out:争论未定义的行为...”,其中 Carruth 先生展示了 bzip 代码中的一个示例。他们已将其用作uint32_t i1索引。在 64 位系统中,数组访问block[i1]将执行*(block + i1)。问题是block是 64 位指针,而i1是 32 位数字。加法可能会溢出,并且由于无符号整数已定义溢出行为,因此编译器需要添加额外的指令确保即使在 64 位系统上也确实实现了这一点。
我还想用一个简单的例子来展示这一点。所以我尝试了++i使用各种有符号和无符号整数的代码。以下是我的测试代码:
#include <cstdint>\n\nvoid test_int8() { int8_t i = 0; ++i; }\nvoid test_uint8() { uint8_t i = 0; ++i; }\n\nvoid test_int16() { int16_t i = 0; ++i; }\nvoid test_uint16() { uint16_t i = 0; ++i; }\n\nvoid test_int32() { int32_t i = 0; ++i; }\nvoid …Run Code Online (Sandbox Code Playgroud) 我有一个类型为type的非类型模板参数的函数int,如下所示:
template <int N>
int foo() { /*...*/ }
Run Code Online (Sandbox Code Playgroud)
我想对该函数N从0到32的所有值进行单元测试。我有一个函数int expected(int n)采用相同的N值并返回期望值。实际上,我想要:
if (foo<0>() != expected(0)) { /* fail... */ }
if (foo<1>() != expected(1)) { /* fail... */ }
if (foo<2>() != expected(2)) { /* fail... */ }
// 30 more lines
Run Code Online (Sandbox Code Playgroud)
我不想手工写出所有33个测试用例,而且由于N编译时的原因,我不能轻易使用运行时循环。
如何BOOST_PP_REPEAT在C ++ 11中让编译器以简单的方式为我生成测试用例,而无需-style技巧或代码生成?
作为构建过程的一部分,我想运行以下两个命令:
sudo chmod a+r /dev/cpu/*/msr
sudo setcap cap_sys_rawio=ep ./bench
Run Code Online (Sandbox Code Playgroud)
这会将内核模块/dev/cpu/*/msr公开的文件设置msr为世界可读,并设置./bench实际读取这些文件所需的二进制文件(作为构建的一部分生成)的额外权限。
问题是这需要 root 权限,因此sudo.
我想要一个类似于 setuid root 脚本的东西来完成这两个特定的事情,但是在现代 Linux 上不推荐和禁用setuid root 脚本。
对于一个简单的解决方案,我有哪些选择?
仅适用于第二行 (the setcap)的解决方案也很有趣,因为我需要这个来运行每个构建,而chmod每次启动只需要运行一次。
执行 a 所需的时间是否在rdmsr很大程度上取决于寄存器读取?
我想针对 C 和 C++ 项目的三个编译器版本进行构建:gcc、gcc-8 和 clang(对于 C 编译器),对于 C++ 编译器,它们应该分别使用 g++、g++-8 和 clang++。
总共3个配置。我不想使用所有 C 和 C++ 编译器版本的产品进行构建,即。没有 gcc/g++-8 等。
如何指定具有这三种配置的矩阵,每种配置都设置两个变量?
目前我正在使用它(请注意,指定了 2 个操作系统,因此总共有 6 个配置):
strategy:
matrix:
os: [ubuntu-16.04, ubuntu-latest]
cpp_compiler: [g++, g++-8, clang++]
include:
- c_compiler: gcc
- cpp_ompiler: g++-8
c_compiler: gcc-8
- cpp_compiler: clang++
c_compiler: clang
Run Code Online (Sandbox Code Playgroud)
本质上就是把C++编译器( cpp_compiler)作为主版本,然后include用hacky的方式c_compiler根据cpp_compiler版本来设置,但一定有更好的...