简体   繁体   English

在线程上的2D向量上push_back是否安全?

[英]It is safe to push_back on a 2D vector on threads?

Lets say I have a 2D array and this function: 可以说我有一个2D数组和这个函数:

void addVec(std::vector<std::vector<short> >& arr, size_t idx){ 
   arr[idx].push_back(idx);
}

std::vector<std::vector<short> > arr(2);
boost::threads th1(addVec, boost::ref(arr), 0);
boost::threads th2(addVec, booost::ref(arr), 1);
th1.join();
th2.join();

By now I should have arr[0][0] = 0; 现在,我应该有arr [0] [0] = 0; and arr[1][0] = 1; 并且arr [1] [0] = 1; The questions is if this is safe? 问题是这是否安全? Internally the threads should add values to different parts of vector memory, and because it is constructed at the beginning of size 2 only the internal vectors get resized, witch have thread exclusive access. 在内部,线程应将值添加到向量存储器的不同部分,并且由于它是在大小2的开头构造的,因此仅内部向量会被调整大小,因此线程具有独占访问权限。

This should be safe since each thread accessing a separate vector. 这应该是安全的,因为每个线程都访问一个单独的向量。 If however you do anything that might cause arr to resize, then all bets are off... 但是,如果您做任何可能导致arr调整大小的操作,那么所有投注都将关闭...

I would suggest that you take a step back and consider what your goal is, before you continue down the path you are on. 我建议您退后一步,考虑自己的目标,然后再继续前进。

First off, why do you want to parallelize your code? 首先,为什么要并行化代码? I assume you want your program to run faster. 我假设您希望程序运行得更快。 That means 那意味着

  1. You should start by writing a working sequential implementation. 您应该首先编写一个有效的顺序实现。
  2. You should profile and tune that implementation. 您应该分析并调整该实现。
  3. If (and only if) your program is still too slow for your purpose you should parallelize it if: 如果(且仅当)您的程序仍然太慢而无法满足您的目的,则在以下情况下应并行化它:
    1. A large part of the program can be parallelized (check out Amdahl's law ). 程序的大部分可以并行化(请查看阿姆达尔定律 )。
    2. Your sequential implementation makes good use of the cache . 您的顺序实现充分利用了缓存 The cache is very likely to be a bottleneck even for sequential code, so if your code isn't cache-efficient it will probably be slower when you parallelize it. 即使对于顺序代码,高速缓存也很可能成为瓶颈,因此,如果您的代码不是高速缓存的,则在并行化它时可能会变慢。

Points 1. and 2. is probably where you should be devoting your time. 要点1.和2.可能是您应该花费时间的地方。 Odds are that a highly tuned sequential implementation is more than adequate for your needs and it will be much cheaper/easier/faster to develop and maintain. 赔率是一个高度优化的顺序执行是绰绰有余您的需求,这将是便宜/容易/更快的开发和维护。

If you do decide to parallelize your code, you should take a look at OpenMP . 如果您决定并行化代码,则应该看一下OpenMP Threads are probably one of the worst ways to write parallel programs known to man. 线程可能是编写人类已知的并行程序的最糟糕的方法之一。 You may think that OpenMP's runtime system is too slow for you but again, you should take a step back and think about why. 您可能认为OpenMP的运行时系统对您来说太慢了,但是再次,您应该退后一步,想一想为什么。

If your algorithm requires a lot of locks and barriers, you can get a minor speedup by using faster locks and barriers. 如果您的算法需要大量的锁和障碍,则可以通过使用更快的锁和障碍来获得较小的加速。 If you improve your algorithm to use fewer locks and barriers, you can achieve a much larger speedup. 如果您改进算法以使用更少的锁和障碍,则可以实现更大的加速。

这是安全的,尽管从设计的角度来看,只给每个线程提供其内部矢量会更安全,所以将来发生不安全行为的可能性较小

Yes, it is safe in your use case, because you don't modify the shared data. 是的,在您的用例中是安全的,因为您无需修改​​共享数据。 However, I would prefer to pass the reference to the std::vector<short> to each thread to simplify the usage: 但是,我希望将对std::vector<short>的引用传递给每个线程以简化用法:

void addVec(std::vector<short> & arr)
{ 
   arr.push_back(some_data);
}

std::vector<std::vector<short> > arr(2);
boost::threads th1(addVec, boost::ref(arr[0]));
boost::threads th2(addVec, booost::ref(arr[1]));
th1.join();
th2.join();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM