简体   繁体   English

在OpenMP并行区域中使用向量push_back是否安全?

[英]Is it safe to use vector push_back in an OpenMP parallel region?

I know I am not supposed to throw any uncaught exceptions from inside an openmp parallel region. 我知道我不应该在openmp并行区域内引发任何未捕获的异常。 Therefore I do not think the following loops are safe because the push_back function of vector could cause a reallocation of memory which could potentially throw an exception. 因此,我认为以下循环并不安全,因为vector的push_back函数可能导致内存重新分配,从而有可能引发异常。

I looked up the documentation and it says that If a reallocation happens, the strong guarantee is also given if the type of the elements is either copyable or no-throw moveable. 我查阅了文档,并说If a reallocation happens, the strong guarantee is also given if the type of the elements is either copyable or no-throw moveable.

So is my code here safe? 那我的代码安全吗? Star is a basic data struct containing floats. Star是包含浮点数的基本数据结构。

        std::vector<Star> stars;

        #pragma omp parallel for
        for(size_t i = 1; i < (gimg.height() - 1) * 2; i++)
        {
            float i_ = i / 2.0f;

            for(float j = 1; j < gimg.width() - 1; j += 0.5f)
            {
                //a b c
                //d e f
                //g h k

                quantum_t e = gimg.bilinear(j, i_);

                quantum_t a = gimg.bilinear(j - 1, i_ - 1);
                if(a >= e) continue;

                quantum_t b = gimg.bilinear(j, i_ - 1);
                if(b >= e) continue;

                quantum_t c = gimg.bilinear(j + 1, i_ + 1);
                if(c >= e) continue;

                quantum_t d = gimg.bilinear(j - 1, i_);
                if(d >= e) continue;

                quantum_t f = gimg.bilinear(j + 1, i_);
                if(f >= e) continue;

                quantum_t g = gimg.bilinear(j - 1, i_ + 1);
                if(g >= e) continue;

                quantum_t h = gimg.bilinear(j, i_ + 1); 
                if(h >= e) continue;

                quantum_t k = gimg.bilinear(j + 1, i_ + 1);
                if(k >= e) continue;

                bool ismax = d >= a && d >= g && h >= g && h >= k && f >= k && f >= c && b >= c && b >= a;

                if(ismax)
                {
                    Star s;
                    s.brightness = e;
                    s.location = Point<float>(j, i_);

                    #pragma omp critical
                    stars.push_back(s);
                }
            }
        }

The OpenMP standard says, near the end of section 2.7.1 : OpenMP标准在第2.7.1节结尾处说:

A throw executed inside a loop region must cause execution to resume within the same iteration of the loop region, and the same thread that threw the exception must catch it. 在循环区域内执行的throw必须使执行在循环区域的同一迭代中恢复,并且引发异常的同一线程必须捕获该异常。

So enclosing your push_back() with a try - catch construct, itself within the critical region should make you code safe. 因此,将push_back()构造本身包含在try - catch构造中,使其位于critical区域内,应该可以确保您的代码安全。

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

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