我观察到一些我无法解释的奇怪行为.代码如下所示:
#include <memory>
#include <vector>
#include <algorithm>
int main(){
std::vector<double> t1(10, 5.0);
std::vector<double*> t2(10);
std::transform(t1.begin(), t1.end(), t2.begin(), std::addressof<double>);
//std::transform(t1.begin(), t1.end(), t2.begin(), [](double& a){return &a;});
}
Run Code Online (Sandbox Code Playgroud)
这里有一个版本来玩https://godbolt.org/g/YcNdbf 问题是这个代码使用gcc4.9-6.3编译好但在gcc 7.1下失败.Clang也不喜欢它.
(编辑)来自gcc 7.1的错误消息:
<source>: In function 'int main()':
8 : <source>:8:76: error: no matching function for call to 'transform(std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double*>::iterator, <unresolved overloaded function type>)'
std::transform(t1.begin(), t1.end(), t2.begin(), std::addressof<double>);
^
In file included from /opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/algorithm:62:0,
from <source>:3:
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/stl_algo.h:4281:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)
transform(_InputIterator …Run Code Online (Sandbox Code Playgroud) 使用gcc 7.1.0 std::mem_fn能够检测成员函数指针上的noexcept-ness.它是如何做到的?我认为说明noexcept符不是函数类型的一部分?
更令人困惑的是,当我从https://wandbox.org/permlink/JUI3rsLjKRoPArAl中移除一个方法上的noexcept说明符时,所有noexcept值都会发生变化,如https://wandbox.org/permlink/yBJ0R4PxzAXg09ef所示.当一个人不是新的时候,所有人都不是例外.怎么样?这是一个错误吗?
该程序包含如下代码:
int size;
...
int *pi = (int*)calloc(size, sizeof(int));
...
Run Code Online (Sandbox Code Playgroud)
这是用gcc7.2编译时的错误信息?
错误:参数 1 范围 [18446744071562067968, 18446744073709551615] 超过最大对象大小 9223372036854775807 [-Werror=alloc-size-larger-than=]
当我
int *pi = (int*)calloc(size, sizeof(int)); 改为
int *pi = (int*)calloc((unsigned int)size, sizeof(int));
错误消失了。
但是,在程序中,有很多malloc和calloc我原来的版本一样使用。
为什么gcc只检测到一个错误?
我对L1缓存的理解是内存提取加载了缓存行.假设高速缓存行大小为64个字节,如果我在地址访问存储器p,它将从加载整个块p到p + 64到缓存中.因此,最好从左到右(而不是从右到左)迭代一个数组,以最大化缓存局部性.
但是,我编写了一个示例C代码,它分配了一个包含1亿个字符的数组,将随机值写入其中并对其求和(下面复制以供参考).一个版本的代码从左到右,另一个从右到左.当我对它进行基准测试时,我得到了非常类似的结果(其中"时钟周期"是根据测量的clock.代码是在没有优化的情况下编译的.
所以我的问题是:现代处理器做的不仅仅是"缓存读取+ 64字节"吗?他们是向前和向后缓存吗?编译器可以"告诉"处理器代码向后迭代吗?
作为参考,我正在Mac OS X 10.13.3使用gcc-7 (Homebrew GCC 7.2.0_1) 7.2.0具有64字节缓存行的x86-64 Intel处理器.
Benchmakrs:
$ ./a.out
Backward Iterating...took 150101 clock cycles
$ ./a.out
Forward Iterating...took 146545 clock cycles
Run Code Online (Sandbox Code Playgroud)
我希望前向迭代速度大约快64倍,因为每64个元素应该是缓存命中,而对于反向迭代,每个元素应该是缓存未命中.
所以,我打电话给cachegrind.两者的缓存命中率几乎相同:
# Left to right iteration
==21773==
==21773== I refs: 4,006,996,067
==21773== I1 misses: 5,183
==21773== LLi misses: 3,019
==21773== I1 miss rate: 0.00%
==21773== LLi miss rate: 0.00%
==21773==
==21773== D refs: 1,802,393,260 (1,401,627,925 rd + …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 Jetson Nano 上编译 C 代码,但在编译过程中出现此错误。我尝试删除任何出现的 'm -64',但它似乎是自动添加的。这是 cmd 失败的地方: /usr/bin/gcc-7 -Wall -Wextra -Wconversion -pedantic -Wshadow -m64 -Wfatal-errors -O0 -g -o CMakeFiles/dir/testCCompiler.c.o -c /home/user/dir/CMakeFiles/CMakeTmp/testCCompiler.c
uname -a: Linux jetson-nano 4.9.140-tegra aarch64 aarch64 aarch64 GNU/Linux
gcc-7 -v: Using built-in specs.
COLLECT_GCC=gcc-7
COLLECT_LTO_WRAPPER=/usr/lib/gcc/aarch64-linux-gnu/7/lto-wrapper
Target: aarch64-linux-gnu
gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1)
Run Code Online (Sandbox Code Playgroud)
CMAKE_C_COMPILER = gcc-7
CMAKE_CXX_COMPILER = g++-7
CXX_COMPILE_FLAGS = "-Wall -Werror -Wextra -Wnon-virtual-dtor -Wconversion -Wold-style-cast -pedantic -Wshadow"
C_COMPILE_FLAGS = "-Wall -Wextra -Wconversion -pedantic -Wshadow"
Run Code Online (Sandbox Code Playgroud)
gcc-7:错误:无法识别的命令行选项“-m64”
考虑:
#include <variant>
#include <iostream>
int main()
{
double foo = 666.666;
std::variant<double, uint64_t> v = foo;
std::cout << std::get<uint64_t>(v) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这导致:
terminate called after throwing an instance of 'std::bad_variant_access'
what(): Unexpected index
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
为什么?
我知道这std::variant将是union. 但如果这种基本的东西失败了,它有什么好处呢?