2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Время выполнения программы
Сообщение26.11.2009, 18:50 


08/09/08
40
Написал программу реализующую метод Гаусса для трехдиагональной матрицы.
В ней есть участок кода(обратный ход)
Код:

   d=y2[n]=f1[n]/b1[n];
   for (i=n-1; i>=0; i--)
   {
      d = (f1[i]-c[i]*d)/b1[i];
      y2[i]  = d;
   }

если деление в нем поменять на умножение:
Код:

   d=y2[n]=f1[n]/b1[n];
   for (i=n-1; i>=0; i--)
   {
      d = (f1[i]-c[i]*d)*b1[i];//Здесь
      y2[i]  = d;
   }

то время работы этого куска возрастает в 7-8 раз.
Посмотрел в дизассемблере
Код:
//вариант с умножением------------------------------------------------------------
.text:00401358 loc_401358:                             ; CODE XREF: _main+168j
.text:00401358                 fmul    qword ptr [eax+409550h]
.text:0040135E                 sub     eax, 8
.text:00401361                 cmp     eax, 0FFFFFCE8h
.text:00401366                 fsubr   qword ptr [eax+40A1F8h]
.text:0040136C                 fmul    qword ptr [eax+409ED0h]    //отличие
.text:00401372                 fst     qword ptr [eax+40A520h]
.text:00401378                 jge     short loc_401358
//вариант с делением---------------------------------------------------------------
.text:00401358 loc_401358:                             ; CODE XREF: _main+168j
.text:00401358                 fmul    qword ptr [eax+409550h]
.text:0040135E                 sub     eax, 8
.text:00401361                 cmp     eax, 0FFFFFCE8h
.text:00401366                 fsubr   qword ptr [eax+40A1F8h]
.text:0040136C                 fdiv    qword ptr [eax+409ED0h]    //отличие
.text:00401372                 fst     qword ptr [eax+40A520h]
.text:00401378                 jge     short loc_401358



Подскажите, пожалуйста, почему происходит увеличение времени выполнения.

P.S. n=100 но сам цикл выполняется сотни тысяч раз.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение26.11.2009, 19:02 
Заслуженный участник


04/05/09
4593
Потому что деление - гораздо медленнее, чем умножение.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение26.11.2009, 19:04 
Аватара пользователя


25/03/09
94
Деление выполняется намного медленнее, fmul выполняется 2-3 такта, fdiv около 40.
Если каждое b1[i] используется несколько раз, их можно один раз поделить (b2[i] = 1/b1[i]) и во внутренних циклах уже умножать на b2.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение26.11.2009, 19:20 
Заслуженный участник


09/08/09
3438
С.Петербург
sasha-parazit в сообщении #265546 писал(а):
В ней есть участок кода(обратный ход)
...
если деление в нем поменять на умножение:
...
то время работы этого куска возрастает в 7-8 раз.
...
Подскажите, пожалуйста, почему происходит увеличение времени выполнения.

venco в сообщении #265549 писал(а):
Потому что деление - гораздо медленнее, чем умножение.

Возможно, я что-то опять не так понял, но мне кажется у автора ровно обратная ситуация: умножение выполняется медленнее деления.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение26.11.2009, 19:55 
Аватара пользователя


25/03/09
94
Ого.
По идее, там куча танцев с оптимизацией, этим должен компилятор сам заниматься.

Ну и, точно также, если компилятор не хочет оптимизировать, можно вручную взять обратное и в цикле уже на него делить :) Но очень уж бредово звучит.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение26.11.2009, 20:06 
Заслуженный участник


04/05/09
4593
Maslov в сообщении #265556 писал(а):
sasha-parazit в сообщении #265546 писал(а):
В ней есть участок кода(обратный ход)
...
если деление в нем поменять на умножение:
...
то время работы этого куска возрастает в 7-8 раз.
...
Подскажите, пожалуйста, почему происходит увеличение времени выполнения.

venco в сообщении #265549 писал(а):
Потому что деление - гораздо медленнее, чем умножение.

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

-- Чт ноя 26, 2009 12:09:05 --

covax в сообщении #265557 писал(а):
Ого.
По идее, там куча танцев с оптимизацией, этим должен компилятор сам заниматься.

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

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 11:58 


08/09/08
40
Цитата:
Я думаю, автор перепутал, и имел в виду скорость выполнения, т.к. деление совершенно точно медленнее умножения.
Если же автор не перепутал, то возможно замена умножения делением меняет, например, количество итераций какого-нибудь цикла. При этом результат получается неправильный, но гораздо быстрее.


Нет, я не перепутал. Вариант с делением работает быстрее варианта с умножением. --- В этом-то и парадокс.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 12:16 
Заслуженный участник


09/08/09
3438
С.Петербург
sasha-parazit в сообщении #265678 писал(а):
В этом-то и парадокс.
Действительно, парадокс. А как Вы время меряли?

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 12:26 
Заслуженный участник
Аватара пользователя


13/08/08
14496
А что если Вам этот кусок выделить в отдельную программу и прогнать его в цикле?
Не существует ли особых случаев, когда деление определённых чисел на определённые числа выполняется быстрее их умножения?

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 13:41 
Заслуженный участник


09/08/09
3438
С.Петербург
gris в сообщении #265682 писал(а):
А что если Вам этот кусок выделить в отдельную программу и прогнать его в цикле?

Выделил. Прогнал (VS2008).
Программа:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
int main()
{
    int n = 100;
    double f1[100], y2[100], b1[100], c[100], d;
    int i;
    for (i = 0; i < 100; i++) {
        f1[i] = i+2;
        b1[i] = i+2;
        c[i] = i+1;
    }
    for (long m = 0; m < 5000000; m ++) {
        d=y2[n]=f1[n]/b1[n];
        for (i=n-1; i>=0; i--)
        {
            d = (f1[i]-c[i]*d)*b1[i];
            //                ^ умножение на деление меняем здесь
            y2[i]  = d;
        }
    }
    return 0;
}
 

Ключи компиляции:
Код:
/O2 /Oi /Os /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FD /EHsc /MD /Gy /fp:fast /FAs /Fa"Release\\" /Fo"Release\\" /Fd"Release\vc90.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt

Результаты:

1. Intel Pentium 4 HT (Northwood) 2.8 GHz
С умножением: 16.5 сек.
С делением: 9.4 сек.
Ничего не перепутал: с делением на 75% быстрее.

2. Intel Core 2 Duo (Merom) T7700 2.40GHz
С умножением: 7.7 сек.
С делением: 8.3 сек.
Опять ничего не перепутал: с делением на 7% медленнее.

Сгенерированный код отличается, как и положено, в одной команде FMUL/FDIV.
Пока не знаю, что и думать.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 14:21 
Заслуженный участник
Аватара пользователя


13/08/08
14496
Когда компутер делит одинаковые числа, он соображает, что делает? Одно дело умножить 57486453 на 57486453, а другое разделить. Не сокращается ли драматически время деления в этом случае?

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 15:49 
Заслуженный участник


09/08/09
3438
С.Петербург
gris в сообщении #265702 писал(а):
Одно дело умножить 57486453 на 57486453, а другое разделить. Не сокращается ли драматически время деления в этом случае?
Да не должно. Вряд ли он сначала сравнивает операнды деления на полное совпадение. Да и потом, у нас вроде другой случай.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 16:53 
Аватара пользователя


25/03/09
94
При умножении возникает переполнение, из-за этого, скорее всего.
Например, если тут 100 поменять на 1000, то умножение у меня отстает уже раз так в 50.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 16:54 
Заслуженный участник


04/05/09
4593
Во первых, ваша программа заходит за границы массивов в первом операторе цикла по m.
Что при этом портится, и что в результате получается - трудно сказать.
Если массивы сделать на один больше, то вариант с умножением станет быстрее, чем с делением.

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

-- Пт ноя 27, 2009 08:58:02 --

covax в сообщении #265734 писал(а):
При умножении возникает переполнение, из-за этого, скорее всего.
Согласен. Вычисление с особыми значениями, типа бесконечности или NaN, могут работать медленнее.

 Профиль  
                  
 
 Re: Время выполнения программы
Сообщение27.11.2009, 17:07 
Заслуженный участник


19/07/08
1266
Ну раз пошёл мозговой штурм... Не может быть так, что какой-нибудь кэш в игру вступает? Если умножение чуть-чуть быстрее деления, так что кэш успевает закончиться (а при делении чуть медленнее, так что процу никогда не приходится ждать загрузки данных), то в принципе могло бы быть что-то похожее. Как относительная скорость выполнения зависит от $n$? Или никак не зависит?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group