在多线程中初始化向量
Initializing vector in multithread
我有一个大型向量std::vector<some_class> some_vector
,我需要用不同的构造函数some_class(constructor_parameters)
初始化。正常的方法是:
std::vector<some_class> some_vector
some_vector.reserve(length)
for (...) some_vector.push_back(some_class(constructor_parameters))
但是,由于这个向量很大,所以我想并行执行此操作。是否有任何方法可以将向量和 push_back
在q的不同位置分开,以便每个线程可以开始初始化向量的不同部分?
我通过分裂/加入向量阅读了一些答案,但尚未发现任何有用的答案。由于我的向量确实很大,因此我必须避免使用为每个线程创建新向量,然后将它们复制到原始的矢量 - 我只能使用一大块内存。
我尝试使用some_vector.at(some_loc) = some_class(constructor_parameters)
,但这不是与非初始化的向量一起使用的。
我可以将向量初始化为某些转储值,然后使用at
将其启动到适当的值,但不是有效的。
所以我的问题 - 如何有效地(就内存消耗和计算时间而言)初始化大型向量?
编辑:回答评论:
size - 在程序运行期间,容器不会更改其大小,但是在编译时,大小不知道。大小很大,因为这只是问题的范围 - 我正在执行宇宙学n体模拟,其中粒子/网格细胞的数量很容易被1024^3及更多。
ctors - 现在它们只是为类成员分配值(3〜7分配),但我打算添加一些计算
成员 - 很容易共配,通常为2 std::vector(3)
为什么向量 - 我最初仅使用基本类型数组和new / delete
指令。我想使用矢量,因为它们的各种功能,自动内存(DE)分配,使用迭代器等。我只是假设它们应该易于使用所有其他好的属性实现到多线程中...
对于常规类型T
,您描述的问题是要跟踪已构建的T
中的哪个并且没有。
如果您将"这是有效的值"数据压缩到比特字段中,则检查有效性是非常不连贯的。
一种简单的方法是C 17中的vector<optional<T>>
或使用Boost。预先示例(到nullopt
),然后使用emplace
在您想要的任何线程中构造术语。
最后,考虑不使用单个向量。写一个包装器,将多个向量拼接到一个可见的容器中。
我能想到两种解决方案。
一种是使用并发数据结构,例如TBB的concurrent_vector
。查看其文档
第二个是编写一个自定义分配器,当无参数调用时,其construct
成员不会调用默认构造函数。然后将向量分配一次,然后并行初始化每个元素。需要注意确保这样的construct
不会稍后会引起麻烦。如果您可以在构造新元素时使用C 11 MOVE语义,则它将最有效。在这种情况下,您在主线程中唯一需要做的就是分配内存,这是您几乎无法避免任何方式的成本。
这是一个具体的例子,
template <std::size_t n, std::size_t m>
class StirlingMatrix2
{
public:
StirlingMatrix2()
{
// compute the matrix of Stirling numbers
// relatively expensive
}
double operator()(std::size_t i, std::size_t j) const
{
return data_[i * (m + 1) + j];
}
private:
double data_[(n + 1) * (m + 1)];
}; // class StirlingMatrix
template <typename T, bool InvokeConstructor = true>
class Allocator
{
public:
// other member functions and types
template <typename U>
void construct(U *ptr)
{
construct_dispatch(
ptr, std::integral_constant<bool, InvokeConstructor>());
}
template <typename U, typename Arg, typename... Args>
void constrct(U *ptr, Arg &&arg, Args &&... args)
{
std::allocator<T>::construct(
ptr, std::forward<Arg>(arg), std::forward<Args>(args)...);
}
private:
template <typename U>
void construct_dispatch(U *ptr, std::true_type)
{
std::allocator<T>::construct(ptr);
}
template <typename U>
void construct_dispatch(U *, std::false_type)
{
}
}; // class Allocator
// specialization for void type is needed
int main()
{
constexpr n = 100;
constexpr m = 100;
using T = StirlingMatrix2<n, m>;
// each element will be constructed, very expensive
std::vector<T> svec1(N);
// allocate memory only
std::vector<T, Allocator<T, false>> svec2(N);
// within each thread
// invoke inplace new to construct elements
}
为此,不能有指针成员或班级成员并不小。否则,没有办法安全。如果您不必使用容器类,可以使用类似的技术,而是通过malloc
手动管理内存等等。
- 为什么我在向量初始化时收到此错误?
- 使用向量初始化参数化构造函数的对象数组
- C++向量初始化遗传算法的代理向量
- shared_ptr类的向量的向量初始化问题
- 如何实现使用 gcc-4.4 编译的大向量初始化?
- 使用向量初始化C++中的链表
- C++ 中的向量初始化
- 如何使用嵌套初始化构造函数中的一维向量初始化矩阵
- std::另一个函数中的向量初始化
- 理解向量初始化时出现问题
- 静态常量 std::<char>没有堆的向量初始化?
- 向量初始化在 C++ 类中失败
- 具有从特定范围的随机数初始化特征矩阵或向量初始化特征矩阵或向量的有效方法
- 关于向量初始化的一些问题
- 了解C 中的向量初始化
- 设置::使用数字中的引号进行向量初始化
- VS2010中的向量初始化
- C++:构造函数中的向量初始化
- 如何从向量初始化数组?(如何将指针强制转换为数组?)
- 给我一个向量初始化的提示或(答案)