简体   繁体   English

C ++ OpenMP和std :: vector <bool>

[英]C++ OpenMP and std::vector<bool>

Why does the following code not work (as excpected) for std::vector of bool ? 为什么以下代码对bool的std :: vector不起作用(如所考虑的)? Some elements are randomly false in the bool-vector. bool-vector中的一些元素是随机错误的。 For the int vector all works fine (tested with many more than just 3 loops). 对于int向量,所有工作正常(使用多于3个循环进行测试)。

I am on ubuntu 14.04 64bit with g++ 4.8.4. 我在ubuntu 14.04 64bit上使用g ++ 4.8.4。

#include <iostream>
#include <vector>

using namespace std;


class TestBool
{
public:
    TestBool() {}
    bool test() {return true;}
    int testInt() {return 10;}
};
void testBVec(vector<bool> &bv, size_t loop)
{
    cout << "boolvec loop " << loop << endl;
    for(size_t i = 0; i < bv.size(); i++) {
        if( ! bv[i])
            cout << "wholy shit with bool at index " << i << endl;
    }
}
void testIntVec(vector<int> &iv, size_t loop)
{
    cout << "intVec loop " << loop << endl;
    for(size_t i = 0; i < iv.size(); i++) {
        if( iv[i] != 10)
            cout << "wholy shit with int at index " << i << endl;
    }
}


int main()
{
    vector<TestBool> tv(10);
    size_t loops = 3;

    for(size_t i = 0; i < loops; i++ ) {
        vector<bool> bv(10);
        vector<int> iv(10);

        #pragma omp parallel for
        for(int j = 0; j < 10; ++j) {
            bv[j] = tv[j].test();
            iv[j] = tv[j].testInt();
        }
        testBVec(bv, i+1);
        testIntVec(iv, i+1);
    }

    return 0;
}

vector<bool> is the explicit template specialization which packs boolean values into bits of some integer variables. vector<bool>是显式模板特化,它将布尔值打包成一些整数变量的位。 To make the bits writable by semantically-correct subscript, vector<bool>::operator[] returns some proxy object which is convertible to bool and has assignment operator for bool. 为了通过语义正确的下标使位可写, vector<bool>::operator[]返回一些可转换为bool并具有bool赋值运算符的代理对象 The proxy objects for different indices may reference the same underlying memory, so simultaneous access to different bits is not guaranteed to be thread-safe. 不同索引的代理对象可以引用相同的底层内存,因此不能保证对不同位的同时访问是线程安全的。

For a competent proof that it's not a compiler bug, see'Data races' section of this page: 对于一个合格的证明,它不是一个编译器错误,see'Data种族一节这个页面:

Simultaneous access to different elements is not guaranteed to be thread-safe (as storage bytes may be shared by multiple bits). 不能保证对不同元素的同时访问是线程安全的(因为存储字节可以由多个位共享)。

or Section 23.2.2 of the C++ Standard : C ++标准的第23.2.2节:

  1. <...> implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting vector<bool> , are modified concurrently. 除了vector<bool> ,同时修改同一序列中不同元素中包含对象的内容时,需要实现以避免数据争用。
  2. <...> As an exception to the general rule, for a vector<bool> y , y[0] = true may race with y[1] = true . <...>作为一般规则的例外,对于vector<bool> yy[0] = true可以与y[1] = true竞争。

As @Anton advised, use a type other than bool . 正如@Anton建议的那样,使用bool以外的类型。

Most probably it's because vector<bool> transformed to array of bits by compiler. 很可能是因为vector<bool>被编译器转换为位数组。 Just use vector<int> or vector<char> storing 0s and 1s into it, if you don't need bit array. 如果你不需要位数组,只需使用vector<int>vector<char>存储0和1。

In addition to Sergey and Anton answers, let me point out that vector is known to be not thread-safe as described in the Data Races section in http://www.cplusplus.com/reference/vector/vector-bool . 除了谢尔盖和安东的回答之外,我还要指出,已知向量不是线程安全的,如http://www.cplusplus.com/reference/vector/vector-bool中的数据竞争部分所述。

Your alternatives are (as others suggested) either go to vector of other types or protect the statement 您的替代方案(正如其他人建议的那样)要么转到其他类型的向量,要么保护声明

bv[j] = tv[j].test();

with #pragma omp critical . #pragma omp critical

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

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