Почему мой цикл замедляется, когда я удаляю код - PullRequest
4 голосов
/ 13 апреля 2011

Когда я удаляю тесты для вычисления минимума и максимума из цикла, время выполнения на самом деле больше, чем с тестом.Как это возможно?

Редактировать: после выполнения большего количества тестов кажется, что время выполнения не является постоянным, то есть один и тот же код может выполняться за 9 секунд или 13 секунд .... Так что это было просто повторяемое совпадение.Повторяется до тех пор, пока вы не сделаете достаточно тестов, которые ...

Некоторые детали:

  • время выполнения с тестом min max: 9 секунд
  • время выполнения без minмакс тест: 13 сек
  • CFLAGS=-Wall -O2 -fPIC -g
  • gcc 4.4.3 32-битный удаляемый раздел теперь указан в коде

Некоторые предположения: плохое взаимодействие с кешем?

void    FillFullValues(void)
{
    int i,j,k;
    double  X,Y,Z;
    double  p,q,r,p1,q1,r1;
    double  Ls,as,bs;
    unsigned long t1, t2;

    t1 = GET_TICK_COUNT();  
    MinLs = Minas = Minbs = 1000000.0;
    MaxLs = Maxas = Maxbs = 0.0;

    for (i=0;i<256;i++)
    {
        for (j=0;j<256;j++)
        {
            for (k=0;k<256;k++)
            {
                X = 0.4124*CielabValues[i] + 0.3576*CielabValues[j] + 0.1805*CielabValues[k];
                Y = 0.2126*CielabValues[i] + 0.7152*CielabValues[j] + 0.0722*CielabValues[k];
                Z = 0.0193*CielabValues[i] + 0.1192*CielabValues[j] + 0.9505*CielabValues[k];

                p = X * InvXn;
                q = Y;
                r = Z * InvZn;

                if (q>0.008856)
                {
                    Ls = 116*pow(q,third)-16;
                }
                else
                {
                    Ls = 903.3*q;
                }

                if (q<=0.008856)
                {
                    q1 = 7.787*q+seiz;
                }
                else
                {
                    q1 = pow(q,third);
                }

                if (p<=0.008856)
                {
                    p1 = 7.787*p+seiz;
                }
                else
                {
                    p1 = pow(p,third);
                }

                if (r<=0.008856)
                {
                    r1 = 7.787*r+seiz;
                }
                else
                {
                    r1 = pow(r,third);
                }

                as = 500*(p1-q1);
                bs = 200*(q1-r1);

                //
                // cast on short int for reducing array size
                // 
                FullValuesLs[i][j][k] = (char) (Ls);
                FullValuesas[i][j][k] = (char) (as);
                FullValuesbs[i][j][k] = (char) (bs);

                            //// Remove this and get slower code    
                if (MaxLs<Ls)
                    MaxLs = Ls;
                if ((abs(Ls)<MinLs) && (abs(Ls)>0))
                    MinLs = Ls;

                if (Maxas<as)
                    Maxas = as;
                if ((abs(as)<Minas) && (abs(as)>0))
                    Minas = as;

                if (Maxbs<bs)
                    Maxbs = bs;
                if ((abs(bs)<Minbs) && (abs(bs)>0))
                    Minbs = bs;
                            //// End of Remove

            }
        }
    }

    TRACE(_T("LMax = %f LMin = %f\n"),(MaxLs),(MinLs));
    TRACE(_T("aMax = %f aMin = %f\n"),(Maxas),(Minas));
    TRACE(_T("bMax = %f bMin = %f\n"),(Maxbs),(Minbs));
    t2 = GET_TICK_COUNT();
    TRACE(_T("WhiteBalance init : %lu ms\n"), t2 - t1); 
}

Ответы [ 2 ]

2 голосов
/ 13 апреля 2011

Я думаю, что компилятор пытается развернуть внутренний цикл, потому что вы удаляете зависимость между итерациями. Но как-то это не помогает в вашем случае. Возможно, потому что цикл слишком большой и использует слишком много регистров для развертывания.

Попробуйте отключить развертывание и снова опубликовать результаты.

Если это так, я бы посоветовал вам сообщить о проблеме производительности в gcc.

PS. Я думаю, что вы можете объединить if (q>0.008856) и if (q<=0.008856).

1 голос
/ 13 апреля 2011

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

РЕДАКТИРОВАТЬ: Как вы теперь пояснили, что это было только измерение, я могу только порекомендовать (или лучшую команду ;-) вам), что когда вы хотите получить числа времени выполнения: ВСЕГДА помещайте его в некоторый цикл и усредняйте его. Лучше всего делать это вне вашей программы (в сценарии оболочки), чтобы ваш кеш еще не был заполнен нужными данными.

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