Как найти ошибку G ++ оптимизировать код C ++? - PullRequest
1 голос
/ 27 августа 2010

Сегодня я сталкиваюсь со странной проблемой.Мой код на С ++ может работать в режиме отладки.используя g ++ -g для компиляции кода.Тем не менее, когда я использую g ++ -O для оптимизации кода.Это где-то застрянет.Кажется, там мертвая петля.Кто-нибудь знает, как найти такую ​​ошибку?Когда я отлаживаю код с помощью отладчика DDD, он работает нормально.Спасибо!

Часть кода (я обнаружил, что застрявший пришел из этой части) вставлен ниже:

void Solver::reduceRoutes()
{
    int V=pinst->get_V();   //get the given number of vehicles
    if(int(curSol_.size())<=V)    // return when solution has no extra routes 
        return;

    int routeNum1,routeNum2;   // the two routes modified

    listSize=int(0.2*pinst->get_N());

    short TheNode,anode;          // the second node
    float totalInc;               //the obj increase of a candidate position
    Route::iterator it;
    vector<short> candidateList;
    vector<short> validCandidateList;  //nodes can be moved to
    vector<float> totalImpList;
    int solSize=int(curSol_.size());

    while(solSize>V)
    {
        //  cout <<"debug6.0 ";
        routeNum1=psol->findRouteWithMinC(curSol_);
        cout <<" debug6.1 "<<curSol_.size()<<" "<<routeNum1;
        while(curSol_[routeNum1].size()>2)
        {
            it=curSol_[routeNum1].begin();
            it++;
            TheNode=*it;
            candidateList=pinst->get_PNL(TheNode,listSize);

            // evaluate the effect of moving the node to each possible position

            for(unsigned int i=1;i<candidateList.size();i++)      //the first node is itself
            {
                anode=candidateList[i];

                routeNum2=RouteNumList[anode];  //find the route of second node
                if(routeNum2!=routeNum1)         //inter route move
                {  
                    totalInc=evaluateAreduceRouteMove(curSol_,routeNum1,routeNum2,TheNode,anode);
                    totalImpList.push_back(totalInc);
                    validCandidateList.push_back(anode);
                }
            }

            //find the best position to insert the
            int ii=(min_element(totalImpList.begin(),totalImpList.end())-totalImpList.begin());
            anode=validCandidateList[ii];

            it=find(curSol_[routeNum1].begin(),curSol_[routeNum1].end(),TheNode);
            curSol_[routeNum1].erase(it);       //remove from route1

            routeNum2=RouteNumList[anode];
            it=find(curSol_[routeNum2].begin(),curSol_[routeNum2].end(),anode);
            ++it;
            curSol_[routeNum2].insert(it,TheNode);  //insert to the second route
            RouteNumList[TheNode]=routeNum2;        //update route number
            //improve the modified routes

            psol->doTwoOpt(curSol_[routeNum2]);
            totalImpList.clear();
            validCandidateList.clear();
        }

        //update route number list
        for(unsigned int i=routeNum1+1;i<curSol_.size();i++)
        {
            for(it=curSol_[i].begin();it!=curSol_[i].end();it++)
                RouteNumList[*it]-=1;

        }

        RouteNumList[0]=0;
        // eliminate the empty route
        curSol_.erase(curSol_.begin()+routeNum1);
        solSize=curSol_.size();
        cout <<" debug6.3 "<<solSize<< " \n";

    }

    return;
}

Спасибо, что ответили на мои вопросы.Теперь мой код работает без оптимизации.Мне просто интересно, что делает оптимизатор, поэтому код работает.Если режим оптимизации не сильно улучшает скорость, то не стоит его использовать.Кто-нибудь может прокомментировать силу режима оптимизации?Еще раз спасибо.

Ответы [ 6 ]

2 голосов
/ 27 августа 2010

Если вы не столкнулись с ошибкой компилятора (а я столкнулся с ошибкой менее одного за десятилетие), проблема заключается в том, что у вас есть код, который не имеет полностью определенного поведения, и он компилируется односторонним образом в режиме отладки идругой способ при оптимизации.Люди, которые пишут оптимизаторы, обычно не несут ответственности за неопределенное или неопределенное поведение;если код неправильный, то вывод тоже.

Вы пробовали включить все возможные предупреждения?Некоторые из них могут дать вам некоторое представление о том, что не так.Быстрый просмотр кода, который вы включили, ничего мне не подсказывает.

Также возможно, что у вас есть неопределенное поведение в других местах вашей программы, скорее всего, повреждение кучи.Это всегда интересно выяснить.

2 голосов
/ 27 августа 2010

Почему в начале цикла вы ввели тип solSize в int int solSize=int(curSol_.size());, но не сделали этого в цикле while solSize=curSol_.size();.Возможно, вы захотите изучить значения в отладке и оптимизированной версии.

Кроме того, в коде, кажется, есть места, где есть числа с плавающей запятой / двойные числа, которые сравниваются (могут быть) с целыми числами.Может быть, это причина бесконечного цикла.

1 голос
/ 27 августа 2010

Я нашел ошибку.Задача, полученная из сравнения переменных типа float.Из-за точности сравнение вызвало бесконечный цикл.Спасибо, ребята.Вы действительно полезны.

1 голос
/ 27 августа 2010

Первое, что нужно сделать, это убедиться, что весь ваш код компилируется.
Большинство этих типов ошибок приводят к тому, что вы используете (невольно) какое-то неопределенное поведение или случайно делаете что-то глупое.Компилятор предупредит вас о большинстве таких ситуаций, поэтому вы можете использовать это в своих интересах.

Добавьте следующее:

-ansi -pedantic -W -Wall -Werror

Это заставит вас решить все простые проблемы.

1 голос
/ 27 августа 2010

Возможно, вы сможете использовать пару звонков на pstack, чтобы узнать, где находится ваша программа, когда она зацикливается. Если это недоступно или не дает удовлетворительных результатов, ваша лучшая ставка - cout с ... МНОГО cout с, в каждой точке функции сузить, где именно она висит. Без этой информации мы просто угадываем слепых. Скомпилируйте с -Wall и убедитесь, что нет никаких предупреждений.

1 голос
/ 27 августа 2010

Откуда ты знаешь, что это где ты вешаешь?Это было из отладки printf / cout?Если это так, вы на правильном пути.Это может быть мощным инструментом в подобных ситуациях.

Я согласен с Гангадхаром, проверь свои типы.Если указать другие уровни оптимизации, он все еще зависает?Что если вы выключите оптимизацию и не включите символы отладки (без параметров -O или -g)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...