我有一个需要执行的功能n=1000
.此函数执行蒙特卡罗样式模拟并返回int
结果.我想nthreads=4
和平奔跑.每当一个线程完成一个循环时,它应该将结果放入a std::vector<int>
.因此,在1000个循环后,我有一个1000 int
s 的向量,可以通过统计检查.
由于a std::vector
不是线程安全的,我想std::mutex
(这肯定会起作用).
但我想知道我是否可以声明一个矢量是原子的,从而绕过互斥体?有没有可能std::atomic<std::vector<int>>
?我可以使用push_back
等吗?
我有一个std::vector<int>
指针指向int*
向量中的元素.假设指针指向第三个元素:pointer=&vector.at(2)
.如果我现在对矢量进行混洗,它是否仍然指向相同的元素(第三个),还是它指向新的位置,而这个元素曾经是第三个元素现在已经移动了?
在那之后,我想让问题更加通用:当向量扩展或缩小时,向量中元素的指针和迭代器如何表现?
我std::variant
可以是空的(std::monostate
),包含一个int
,一个std::string
或一个bool
.
当我想用字符串提供它时,给定为var = "this is my string"
,它将转换为a bool
而不是字符串.如果我明确声明类型,它可以工作var = std::string("this is my string")
.为什么会这样,我能做些什么来避免它?
#include <string>
#include <variant>
#include <iostream>
int main()
{
using var = std::variant<std::monostate, int, std::string, bool>;
var contains_nothing;
var contains_int = 5;
var contains_string = "hello";
var contains_expl_string = std::string("explicit hello");
var contains_bool = false;
auto visitor = [](auto&& arg){
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same<T, std::monostate>())
std::cout<<"nothing\n";
else if constexpr …
Run Code Online (Sandbox Code Playgroud) 我正在研究在格子中移动的粒子的随机游走模拟.出于这个原因,我必须创建大量的随机数,大约10 ^ 12及以上.目前我正在使用C++ 11提供的可能性<random>
.在分析我的程序时,我发现花了大量的时间<random>
.绝大多数这些数字在0到1之间,均匀分布.在这里,我需要一个二项分布的数字.但重点在于0..1数字.
问题是:我可以做些什么来减少生成这些数字所需的CPU时间以及对其质量的影响?
正如您所看到的,我尝试了不同的引擎,但这对CPU时间没有太大影响.此外,我uniform01(gen)
和generate_canonical<double,numeric_limits<double>::digits>(gen)
无论如何有什么区别?
编辑:通过阅读答案,我得出的结论是,对于我的问题,没有理想的解决方案.因此,我决定首先使我的程序具有多线程功能,并在不同的线程中运行多个RNG(以一个random_device编号+一个线程单独增量播种).目前这种接缝是最不可避免的步骤(无论如何都需要多线程).作为进一步的步骤,等待确切的要求,我考虑切换到建议的英特尔RNG或Thrust.这意味着我的RNG实现不应该是复杂的,当前不是.但是现在我喜欢专注于我的模型的物理正确性而不是编程的东西,只要我的程序输出在物理上是正确的. 推力 关于英特尔RNG
这是我目前所做的事情:
class Generator {
public:
Generator();
virtual ~Generator();
double rand01(); //random number [0,1)
int binomial(int n, double p); //binomial distribution with n samples with probability p
private:
std::random_device randev; //seed
/*Engines*/
std::mt19937_64 gen;
//std::mt19937 gen;
//std::default_random_engine gen;
/*Distributions*/
std::uniform_real_distribution<double> uniform01;
std::binomial_distribution<> binomialdist;
};
Generator::Generator() : randev(), gen(randev()), uniform01(0.,1.), binomial(1,1.) {
}
Generator::~Generator() { }
double Generator::rand01() {
//return uniform01(gen);
return generate_canonical<double,numeric_limits<double>::digits>(gen);
} …
Run Code Online (Sandbox Code Playgroud) 该函数可以按原样编译。auto
在这里运作良好。但是这样一个函数的显式返回类型是什么?
auto rangeTest()
{
static const std::vector<int> vi{1,2,3,4,5,6,7,8,9,10};
auto rng = vi | ranges::view::remove_if([](int i){return i % 2 == 1;})
| ranges::view::transform([](int i){return std::to_string(i);});
return rng;
}
Run Code Online (Sandbox Code Playgroud) 我有一种情况,函数必须返回从表中获取的值.此表中的单元格(假设表格正常工作......)可能包含值,或者可能不包含值.该值也可以是以下几种类型之一:( int, double, string, date
但没有其他类型).
这样的函数会返回什么?回来是个好主意std::optional<std::variant<std::string, int, double, std::chrono::time_point>>
吗?
那会是一个很好的使用optional
和variant
?
我需要std::string
在所有空间拆分.但是,结果范围应该将其元素转换为std::string_view
s.我正在努力研究该系列的"元素类型".我想,类型就像是一个类似的东西c_str
.如何将"分裂"部分转换为string_view
s?
#include <string>
#include <string_view>
#include "range/v3/all.hpp"
int main()
{
std::string s = "this should be split into string_views";
auto view = s
| ranges::view::split(' ')
| ranges::view::transform(std::string_view);
}
Run Code Online (Sandbox Code Playgroud) 在下面的代码中,每10个整数的许多向量构造有60%的几率,或者现有的向量被删除,有40%的几率.因此,会有很多调用new/malloc和delete.由于所有这些载体类型vector<int>
,可以在这里自定义分配器的帮助,以减少电话new
和delete
,从而提高性能?这个想法是删除的矢量的空间可以由新构造的空间重用.这样的分配器怎么样?
注意:这个问题是关于分配器,它减少了对new
和的调用delete
.
#include <iostream>
#include <vector>
#include <random>
using namespace std;
int main()
{
// Random generator and distribution
mt19937 gen(123456);
uniform_real_distribution<> dis01(0., 1.);
// Make or delete 10E6 vectors.
vector< vector<int> > v; //the inner vectors will make many calls to new and delete
v.reserve(10E5); //assume some size.
for(int i=0; i<10E6; ++i)
{
if(dis01(gen)<0.6) // if true: make new sub-vector
{
v.emplace_back(); //new sub-vector
v.back().reserve(10);
for(int k=0; k<10; ++k) …
Run Code Online (Sandbox Code Playgroud) 我有一个函数来检查是否std::string
包含子字符串.我将字符串传递给std::string_view
,因此不会发生任何复制.
bool containsSubstr(std::string_view str, std::string_view substr)
{
return str.find(substr) != std::string::npos;
}
Run Code Online (Sandbox Code Playgroud)
我现在想要使用新的C++ 17折叠表达式来创建一个函数,以检查字符串是否包含多个子字符串.再一次,我想通过std::string_view
s 传递它们.
我怎样才能做到这一点?
template<typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
Run Code Online (Sandbox Code Playgroud)
据我所知,上面的版本将子字符串作为它们所来自的类型.所以a std::string
将被复制.我该如何修改类型std::string_view
?就像是:
template<> // does not compile
bool containsAllSubstr(std::string_view str, std::string_view... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
Run Code Online (Sandbox Code Playgroud) c++ ×9
c++17 ×3
vector ×3
c++11 ×2
range-v3 ×2
variant ×2
allocator ×1
build-system ×1
meson-build ×1
optional ×1
performance ×1
pointers ×1
qt-creator ×1
random ×1
string ×1
string-view ×1