【问题标题】:Parallelize for-loop in c++ - memory error在 C++ 中并行化 for 循环 - 内存错误
【发布时间】:2023-01-04 15:16:31
【问题描述】:

我试图在 C++ 中并行化一个 for 循环,但每次我尝试将此循环用于更大的数据集时,我都会收到此错误: 进程返回 -1073741819 (0xC0000005)

对于小数据集,循环有效,对于更大的数据集,初始化有效,但在此之后我遇到内存错误。 我正在使用 Codeblocks 和 GNU GCC 编译器。 在这个循环中,我想运行几次优化进化启发式迭代。 我正在使用 openmp 并试图将在多个线程中使用的变量保密。

#include <omp.h>

void search_framework(Data &data, Solution &best_s)
{
    vector<Solution> pop(data.p_size);
    vector<Solution> child(data.p_size);
    for (int i = 0; i < data.p_size; i++)
    {
        pop[i].reserve(data);
        child[i].reserve(data);
    }

    // parent index in pop
    vector<tuple<int, int>> p_indice(data.p_size);
    bool time_exhausted = false;
    int run = 1;
    #pragma omp parallel for firstprivate(pop, pop_fit, pop_argrank, child, child_fit, child_argrank, p_indice)
    for (int run = 1; run <= data.runs; run++)
    {
        run++;
        int no_improve = 0;
        int gen = 0;
        initialization(pop, pop_fit, pop_argrank, data);
        local_search(pop, pop_fit, pop_argrank, data);

        while (!termination(no_improve, data))
        {
            gen++;
            // printf("---------------------------------Gen %d---------------------------\n", gen);
            no_improve++;
            // select parents
            select_parents(pop, pop_fit, p_indice, data);
            // do local search for children
            local_search(child, child_fit, child_argrank, data);
            // replacement
            replacement(pop, p_indice, child, pop_fit, pop_argrank, child_fit, child_argrank, data);
            // update best
            argsort(pop_fit, pop_argrank, data.p_size);
            update_best_solution(pop[pop_argrank[0]], best_s, used, run, gen, data);
            if (data.tmax != NO_LIMIT && used > clock_t(data.tmax))
            {
                time_exhausted = true;
                break;
            }
        }
        if (time_exhausted) run = data.runs;
    }
}

编辑:这是初始化 pop 等的部分:

void initialization(vector<Solution> &pop, vector<double> &pop_fit, vector<int> &pop_argrank, Data &data)
{
    int len = int(pop.size());
    for (int i = 0; i < len; i++)
    {
        pop[i].clear(data);
    }
   for (int i = 0; i < len; i++)
   {
            data.lambda_gamma = data.latin[i];
            new_route_insertion(pop[i], data);
   }
    for (int i = 0; i < len; i++)
    {
        pop_fit[i] = pop[i].cost;
    }
    argsort(pop_fit, pop_argrank, len);
}

【问题讨论】:

  • 该错误通常意味着您正在访问不属于您的内存 - 例如错误的索引。您是否尝试过使用调试器单步执行代码或检查核心转储?它会告诉您哪个访问有问题。
  • 当我调试时它工作正常并且我在每个线程中为私有变量提供了不同的内存空间。我认为我的程序在调试时没有并行执行。当它并行工作时如何测试它?
  • 由于您使用的是 C++,因此请使用 .at() 索引。那会告诉你哪里出错了。
  • pop[i]child[i] 都没有任何初始化元素,它们只保留了内存。如果您以后不初始化它们,那么访问仍然是未定义的行为。问题出在代码中未显示的某处。

标签: c++ parallel-processing memory-leaks openmp codeblocks


【解决方案1】:

你复制了增加run
一个for (int run = 1; run &lt;= data.runs; run++)
正下方run++
我不知道这种情况下的“数据”是什么,但我想这是不稳定的。
如果不是,我猜data.runs的类型是unsigned long,小心
for (int run = 1; run &lt;= data.runs; run++)
int的范围是“-2147483648到2147483647”,如果data.runs的值超出了int的范围,这是非常危险的,可能会造成死循环。

【讨论】:

  • 谢谢!我改变了它。但我仍然遇到同样的错误。
【解决方案2】:

尝试使用 OMP_STACKSIZE 环境变量增加每个 OMP 线程的堆栈大小。

https://gcc.gnu.org/onlinedocs/gcc-12.1.0/libgomp/OMP_005fSTACKSIZE.html

我认为私有数据结构被放在堆栈上。所以增加问题的大小最终会超过保留的堆栈空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    相关资源
    最近更新 更多