我遇到了一个罕见的程序崩溃,我相信(我很确定)正在调整跨线程访问的向量。我在后推功能中添加了一个互斥锁(下图)。我想我可能会看到一些情况,导致在另一个线程X中调整向量的大小,而线程Y试图从其中一个向量成员复制一个值 - 这导致复制的大小为0,后来导致std :: out_of_range访问。
class TvectorPM {
public:
pthread_mutex_t lock;
std::vector<PopulationMember> v;
TvectorPM();
virtual ~TvectorPM();
void add(PopulationMember p);
};
void TvectorPM::add(PopulationMember p) {
pthread_mutex_lock(&lock);
v.push_back(p);
pthread_mutex_unlock(&lock);
}
我并不热衷于为矢量读取添加互斥锁,因为代码中的大多数位置只需要读取,性能是此软件的一个大问题。下面是一个虚假的例子
void EvolutionManager::mutateSingleNode(int num_needed, int pool_size) {
#pragma omp parallel
{
#pragma omp for schedule(dynamic) nowait
for (int x = 0; x < num_needed; x ++) {
// Copy the original RPN Vec, create a new member
int rand_member = tornament(pool_size);
PopulationMember p;
p.rpn_node_vec = population_manager.populationlist.v.at(rand_member).rpn_node_vec;
p.change();
population_manager.populationlist.add(p);
}
}
}
在我看来,我可以
a) - 获取性能命中和互斥读取
b) - 检查p.rpn_node_vec的大小是否> 0或重读(再次表现一些性能,和hacky)
c) - 在开始循环之前,如果有办法为矢量分配额外的内存以避免需要调整大小,请问好人们。
答案 0 :(得分:2)
如果要为矢量预先分配内存,可以采用以下几种方法:
// constructor parameter, creates 100 default constructed objects
// giving v1.size() == 100;
std::vector<int> v1(100);
std::vector<int> v2;
// resize() will actually resize the vector making size match the parameter passed in
v2.resize(100);
// again, v2.size() == 100;
std::vector<int> v3;
// reserve just "sets aside" memory for the vector to use later
v3.reserve(100);
// now, v3.size() == 0, but v3.capacity() == 100