我如何在此 for 循环中使用 openMP 进行循环并行

How can I use openMP for loop parallel in this for loop?

本文关键字:循环 openMP 并行 for      更新时间:2023-10-16

是否可以在此代码中使用openMP进行循环并行?我试过了,它显示"中断"有错误。谁能帮我指导如何与 openMP 并行?此代码的目的是为值生成算术表达式的可能排列。例如 5+5+1=11,可能还有更多表达式可以得到 11。
问题是我想使用 openMP 来相提并论。但我不知道如何让它成为 openMp 和C++的新手。

vector<string> solve(vector<int> question, vector<char> operands) 
{
    int targetAnswer = question.back(); //Get the final answer
    question.pop_back();    //remove the final answer from question list
    long int totalLoopingCount_Operands = pow(operands.size(),question.size()); // Calculate total looping numbers(operands)
    bool isRedundantAnswer;
    vector<string> answer;
    sort(question.begin(), question.end());
    do{
        isRedundantAnswer = false;
        vector<int> operationSequence;
        //Fill up the operation sequence with first priority operands (int this case '*')
        for (int i = 0; i < question.size(); i++) {
            operationSequence.push_back(0);
        }
                                        //Start the answer seeking algorithm here
        for (long int i = 0; i < totalLoopingCount_Operands-1; i++) {
            if (operands[operationSequence[0]] == '*' || operands[operationSequence[0]] == '/') {
                operationSequence[0]++;
                continue;
            }
            string checkResult = checkAnswer(targetAnswer, operands, question, operationSequence);  //Check the current equation
            //check redundant answer
            for (vector<string>::iterator it = answer.begin(); it != answer.end();it++) {
                if (*it == checkResult) {
                    isRedundantAnswer = true;
                }
            }
            //if result == -1, means this is not a solution
            if (checkResult != "-1" && !isRedundantAnswer) {
                answer.push_back(checkResult);  //insert the answer into the list
            }
            //increment the operationSequence will change the equation
            operationSequence[0]++;
            for (int j = 0; j < question.size() - 1; j++) {
                if (operationSequence[j] == operands.size()) {
                    operationSequence[j] = 0;
                    operationSequence[j + 1] ++;
                }
            }
            if (operationSequence[i % (question.size() - 1)] == 5) {
                cout << "error" << endl;
                break;
            }
        }

    } while (next_permutation(question.begin(),question.end()));
    return answer;
}
在此

解决方案中,错误由foundError布尔值控制,该布尔值在发现错误时尽快修改,并防止线程选择其他迭代以继续处理。#pragma omp flush确保对 boolen 变量的修改在修改后或读取之前立即发送到主内存。

这是基于 http://www.thinkingparallel.com/2007/06/29/breaking-out-of-loops-in-openmp 中讨论的解决方案。另请注意,解决方案需要详细研究哪些变量应该私有化或保持共享#pragma omp parallel for

    bool foundError = false;
    #pragma omp parallel for
    for (long int i = 0; i < totalLoopingCount_Operands-1; i++) {
        #pragma omp flush(foundError)
        if (!foundError)
        {
            if (operands[operationSequence[0]] == '*' || operands[operationSequence[0]] == '/') {
                operationSequence[0]++;
                continue;
            }
            string checkResult = checkAnswer(targetAnswer, operands, question, operationSequence);  //Check the current equation
            //check redundant answer
            for (vector<string>::iterator it = answer.begin(); it != answer.end();it++) {
                if (*it == checkResult) {
                     isRedundantAnswer = true;
                }
            }
            //if result == -1, means this is not a solution
            if (checkResult != "-1" && !isRedundantAnswer) {
                answer.push_back(checkResult);  //insert the answer into the list
            }
            //increment the operationSequence will change the equation
            operationSequence[0]++;
            for (int j = 0; j < question.size() - 1; j++) {
                if (operationSequence[j] == operands.size()) {
                    operationSequence[j] = 0;
                    operationSequence[j + 1] ++;
                }
            }
            if (operationSequence[i % (question.size() - 1)] == 5) {
               foundError = true;
               #pragma omp flush(foundError)
            }
        }
    }
    if (foundError) {
        cout << "error" << endl;
    }