最近,我开始使用带有g ++ 5.3.1的Ubuntu 16.04并检查我的程序运行速度慢了3倍.在此之前我使用过Ubuntu 14.04,g ++ 4.8.4.我使用相同的命令构建它:CFLAGS = -std=c++11 -Wall -O3
.
我的程序包含循环,充满数学调用(sin,cos,exp).你可以在这里找到它.
我尝试使用不同的优化标志(O0,O1,O2,O3,Ofast)进行编译,但在所有情况下都会重现问题(使用Ofast,两种变体运行速度更快,但第一次运行速度仍然慢3倍).
在我使用的程序中libtinyxml-dev
,libgslcblas
.但是它们在两种情况下都具有相同的版本,并且在性能方面没有在程序中(根据代码和callgrind概要分析)占用任何重要部分.
我已经进行了分析,但它并没有让我知道它为什么会发生.
Kcachegrind比较(左边比较慢).我只注意到现在程序使用与Ubuntu 14.04 libm-2.23
相比libm-2.19
.
我的处理器是i7-5820,Haswell.
我不知道为什么它会变慢.你有什么想法?
PS下面你可以找到最耗时的功能:
void InclinedSum::prepare3D()
{
double buf1, buf2;
double sum_prev1 = 0.0, sum_prev2 = 0.0;
int break_idx1, break_idx2;
int arr_idx;
for(int seg_idx = 0; seg_idx < props->K; seg_idx++)
{
const Point& r = well->segs[seg_idx].r_bhp;
for(int k = 0; k < props->K; k++)
{
arr_idx = seg_idx * …
Run Code Online (Sandbox Code Playgroud) 我在Clang 8.0.0,MSVC v19.20和GCC 8.3中成功编译了以下SSCCE代码段。MSVC和Clang都会使程序返回0,而GCC会使程序返回1(godbolt),所以两者之间存在差异,我不知道哪个编译器会产生正确的输出。
#include <type_traits>
template<typename T>
struct Foo {
template <typename U>
using inner = Foo<U>;
};
template<template<typename ...Ts> typename>
struct is_foo_template : std::false_type {};
template<>
struct is_foo_template<Foo> : std::true_type {};
template<typename T>
struct is_foo : is_foo_template<T::template inner> {};
int main() {
return is_foo<Foo<int>>::value;
}
Run Code Online (Sandbox Code Playgroud)
我认为该代码段返回is_foo<Foo<Int>>::value
,但是值是std::true_type::value
还是std::false_type::value
取决于是否选择了Foo-specialization is_foo_template
。但是从main
上面返回的所有三个编译器返回的值都不相同,因此在我看来并非所有编译器都选择相同的专业化。
问题:根据标准,应该选择Foo专业化还是应该选择非专业模板声明?
我想要一个排序的视图,std::vector<std::chrono::milliseconds>
但我不想修改原始容器.std::reference_wrapper
这似乎是完美的,它适用于整数向量.
我创建了这个小例子:
#include <chrono>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
int main()
{
std::vector<int> numbers{1, 42, 3, 9, 5};
std::vector<std::reference_wrapper<int>> sorted_numbers(numbers.begin(), numbers.end());
std::sort(sorted_numbers.begin(), sorted_numbers.end());
std::cout << "Numbers: ";
for (const auto& n : numbers)
std::cout << n << ' ';
std::cout << '\n';
std::cout << "Sorted numbers: ";
for (const auto& n : sorted_numbers)
std::cout << n << ' ';
std::cout << '\n';
std::cout << "Numbers: ";
for (const auto& n : numbers)
std::cout …
Run Code Online (Sandbox Code Playgroud) 在C ++中,至少在GCC和Clang上,嵌入在容器(std :: vector)中的超对齐类型似乎被不同地对待,具体取决于该类型是超对齐结构还是超对齐枚举。对于struct版本,每个元素都对齐,而对于枚举,只有整个缓冲区具有指定的对齐方式。该行为是否由标准指定?如果是这样,哪一部分提到了?还是实现定义的,不应该依赖?
考虑以下:
#include<cstdint>
#include<iostream>
#include<vector>
struct alignas(16) byte_struct {std::uint8_t value;};
enum alignas(16) byte_enum : std::uint8_t {};
int main() {
{//with struct
std::vector<byte_struct> bytes;
bytes.push_back(byte_struct{1});
bytes.push_back(byte_struct{2});
bytes.push_back(byte_struct{3});
for(auto it = bytes.begin(); it!= bytes.end(); ++it) {
std::cout<<&*it<<std::endl;
}
}
{//with enum
std::vector<byte_enum> bytes;
bytes.push_back(byte_enum{1});
bytes.push_back(byte_enum{2});
bytes.push_back(byte_enum{3});
for(auto it = bytes.begin(); it!= bytes.end(); ++it) {
std::cout<<&*it<<std::endl;
}
}
}
Run Code Online (Sandbox Code Playgroud)
具有过度对齐的结构的版本将打印以下内容
0x10a9ec0 0x10a9ed0 0x10a9ee0
带有过度对齐的枚举的版本将打印以下内容
0x10a9e70 0x10a9e71 0x10a9e72
在向量存储区中,每个byte_struct都对齐到16个字节的边界,而byte_enum的对齐方式只适用于整个缓冲区,而不适用于每个单独的元素。
在GCC 9.1和Clang 8.0上,此行为相同,而MSVC 19.20遇到内部编译器错误。
编译器资源管理器的链接为:https : //godbolt.org/z/GUg2ft
在另一个问题下的评论中,有人指出一个常见的错误是:
调用
std::function
它时调用会导致销毁它的对象
虽然在健壮的代码中显然可以避免这种“危险”的事情,但它实际上是错误的吗?我在标准中找不到任何确保以下内容的措辞:
std::function
不得被其目标可调用对象销毁std::function
的生命周期不能在其目标可调用对象执行期间结束据我所知,执行以下操作是合法且明确的(尽管品味不佳):
struct Foo
{
void baz()
{
delete this;
// Just don't use any members after this point
}
};
int main()
{
Foo* foo = new Foo();
foo->baz();
}
Run Code Online (Sandbox Code Playgroud)
这表明,在没有任何压倒一切的限制的情况下,我找不到任何一个,以下在技术上也是明确定义的:
#include <functional>
struct Bar
{
std::function<void()> func;
};
int main()
{
Bar* bar = new Bar();
bar->func = [&]() { delete bar; };
bar->func();
}
Run Code Online (Sandbox Code Playgroud)
不是这样吗?如果不是,哪个措辞禁止它?
(对于奖励积分,如果这比以前的标准有所改变,那将会很有趣。)
我需要 Python 中的一个结构,它将整数索引映射到浮点数向量。我的数据是这样的:
[0] = {1.0, 1.0, 1.0, 1.0}
[1] = {0.5, 1.0}
Run Code Online (Sandbox Code Playgroud)
如果我用 C++ 编写此代码,我将使用以下代码进行定义/添加/访问,如下所示:
std::unordered_map<int, std::vector<float>> VertexWeights;
VertexWeights[0].push_back(0.0f);
vertexWeights[0].push_back(1.0f);
vertexWeights[13].push_back(0.5f);
std::cout <<vertexWeights[0][0];
Run Code Online (Sandbox Code Playgroud)
Python 中 this 的等效结构是什么?
我想在没有不必要的移动或复制的情况下取出临时成员.
假设我有:
class TP {
T _t1, _t2;
};
Run Code Online (Sandbox Code Playgroud)
我想得到_t1
,_t2
来自TP()
.没有复制/移动成员是否可能?
我尝试过使用元组并试图"转发"(我认为不可能)成员,但我能得到的最好的是一个动作,或者成员立即死亡.
在下面的操场中使用B::as_tuple2
最终会员过早死亡,除非结果绑定到非ref类型,否则会移动成员.在客户端,B::as_tuple
简单的移动是安全的auto
.
我认为这应该在技术上是可行的,因为临时死亡,并且成员在他们可以绑定到调用站点上的变量时死亡(我错了吗?),并且类似结构的结构化绑定按预期工作.
是否可以将成员的生命延长/传递到外部变量,或者忽略移动/复制?我需要它与c ++ 14版本,但我无法让它在c ++ 17上工作,所以我对两者都感兴趣.
游乐场:
#include <tuple>
#include <iostream>
using std::cout;
class Shawty {
/**
* Pronounced shouty.
**/
public:
Shawty() : _id(Shawty::id++) {cout << _id << " ctor\n"; }
Shawty(Shawty && s) : _id(Shawty::id++) { cout << _id << " moved from " << s._id << "\n"; }
Shawty(const Shawty & s) …
Run Code Online (Sandbox Code Playgroud) 我大量使用noexcept,不幸的是如果一些传递依赖最终导致一个罕见的情况(我们不知道),崩溃是非常难以调试 - 因为被调用的noexcept
原因std::terminate
.
有没有办法在编译时检测这些违规?在下面的示例中,问题很明显,但默认情况下没有编译器捕获它.我意识到在所有情况下都不可能,但肯定更简单的情况应该是可能的
#include <stdexcept>
void baz()
{
throw std::runtime_error("std::terminate awaits");
}
void bar()
{
baz();
}
void foo() noexcept
{
bar();
}
Run Code Online (Sandbox Code Playgroud)
链接到godbolt:https://godbolt.org/z/Ooet58
是否有我不知道的编译器标志?如何捕获这个静态分析工具呢?
线程由启动std::async(func)
.
如果没有,我该怎么办?