Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исключения / Speedtest 
:(
    Опции темы
SABROG
  Дата 25.9.2008, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Изучая тему исключений решил проверить так ли страшны исключения как их малюют. Написал две тестовые програмки:

//exception.cpp
Код

#include <iostream>
#include <time.h>

bool func();

using namespace std;

int main(int argc, char *argv[])
{
    int numtest;
    if (2 > argc)
    {
        numtest = 100000000;
    }
    else
    {
        numtest = atoi(argv[1]);
    }
    volatile clock_t c1;
    volatile clock_t c2;


    volatile int value = 0;
    volatile double avg = 0;
    c1 = clock();
    for (volatile int i=0; i < numtest; i++)
    {
        try
        {
            func();
        }
        catch(bool)
        {
            value++;
        }
    }
    c2 = clock();
    avg+=double(c2-c1)/CLOCKS_PER_SEC;
    printf("%f\n", avg);
    return 0;
}

bool func()
{
    throw true;
    return true;
}




//standard.cpp
Код

#include <iostream>
#include <time.h>

bool func();

using namespace std;

int main(int argc, char *argv[])
{
    int numtest;
    if (2 > argc)
    {
        numtest = 100000000;
    }
    else
    {
        numtest = atoi(argv[1]);
    }
    volatile clock_t c1;
    volatile clock_t c2;


    volatile int value = 0;
    volatile double avg = 0;
    c1 = clock();
    for (volatile int i=0; i < numtest; i++)
    {
        if (func())
        {
            value++;
        }
    }
    c2 = clock();
    avg+=double(c2-c1)/CLOCKS_PER_SEC;
    printf("%f\n", avg);
    return 0;
}

bool func()
{
    return true;
}




Общая задача для двух программ - узнать об ошибке в функции и увеличить переменную. Т.е. пытаемся определить насколько исключения будут медленными, если одну и ту же функцию вызывать несколько миллионов раз. По умолчанию стоит 100 миллионов. Решил также сравнить как на циклы влияет оптимизация и компиляторы gcc и msvc между собой.

Код

                    -=[GCC]=-
g++ -o0 -o exception exception.cpp:
gccexception: 282 890 байт

(default 100000000 iterations)
>gccexception && gccexception && gccexception
102.001000
106.641000
109.376000

g++ -o3 -o exception exception.cpp:
gccexception: 282 890 байт

(default 100000000 iterations)
>gccexception && gccexception && gccexception
102.376000
105.501000
102.141000
-------------------------------------
g++ -o0 -o standard standard.cpp:
gccstandard: 279 306 байт

(default 100000000 iterations)
>gccstandard && gccstandard && gccstandard
0.968000
0.921000
0.937000

g++ -o3 -o standard standard.cpp:
gccstandard: 279 306 байт

(default 100000000 iterations)
>gccstandard && gccstandard && gccstandard
0.953000
0.953000
0.968000
-=-=-=-=-=-=-=-=-=-
                    -=[MSVC 2005]=-
cl /Od /EHsc exception.cpp /link /out:msvcexception.exe
msvcexception: 77 824 байт

(default 1000000 iterations) - 1 миллион против 100 миллионов на gcc.
>msvcexception && msvcexception && msvcexception
4.734000
5.062000
4.734000

cl /Ox /EHsc exception.cpp /link /out:msvcexception.exe

(default 1000000 iterations) - 1 миллион против 100 миллионов на gcc.
>msvcexception && msvcexception && msvcexception
gccexception: 77 824 байт
5.203000
4.812000
4.875000
-------------------------------------
cl /Od /EHsc standard.cpp /link /out:msvstandard.exe
msvcstandard: 69 632 байт

>msvcstandard && msvcstandard && msvcstandard
0.921000
0.906000
0.984000

cl /Ox /EHsc standard.cpp /link /out:msvstandard.exe
msvcstandard: 69 632 байт
>msvcstandard && msvcstandard && msvcstandard
0.562000
0.546000
0.562000
-=-=-=-=-=-=-=-=-=-


Из результатов видно, что оптимизация в gcc вообще никак не влияет на скорость. Зато в msvc оптимизация работает, но только для стандартных способов проверки. Т.е. оптимизации исключений не проводятся ни в gcc, ни в msvc.

При стандартном способе проверки (без exception'ов) оптимизация дает хороший прирост в скорости для msvc, по сравнению с gcc.

Однако с исключениями в msvc творится что-то странное, они ну очень тормозные по сравнению с gcc. Мне пришлось отказаться от 100 миллионов циклов в пользу 1 миллиона. Но если умножить лучший результат на 100, то мне бы пришлось ожидать 481 секунду. Терпения не хватило. Я не исключаю того, что возможно для msvc есть какие-то ключи для компилятора связаные с выбором реализации исключений. 

По результатам получается, что отказавшись от использовании исключений мы можем придать программе прирост скорости в ~100 раз, а то и более.

Вполне возможно, что я мог где-то накосячить в исходниках и все результаты можно пустить коту под хвост, поэтому буду рад конструктивной критике. Может быть я вообще не правильно использую исключения smile


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Lazin
Дата 25.9.2008, 14:07 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(SABROG @  25.9.2008,  13:55 Найти цитируемый пост)
Может быть я вообще не правильно использую исключения

ты их неправильно используешь smile 
Цитата(SABROG @  25.9.2008,  13:55 Найти цитируемый пост)

Код

bool func()
{
    throw true;
    return true;
}


дело в том, что обычно, программа редко занимается обработкой исключений, но во все функции способные бросить исключение (а в некоторых случаях во все функции), передается дополнительная информация, вот это и нужно измерять, а ты просто используешь исключения вместо return, а это не обычный способ их использования smile

Добавлено через 3 минуты и 44 секунды
то-есть когда используются исключения, в стек пихается дополнительная инфа, сам понимаешь что это дешевая операция, а вот обработка исключения это аварийная ситуация smile , здесь важно что-бы управление было передано куда надо и были вызваны деструкторы в правильном порядке, а не что-бы это произошло быстро
PM MAIL Skype GTalk   Вверх
vinter
Дата 25.9.2008, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Lazin @  25.9.2008,  15:07 Найти цитируемый пост)
а вот обработка исключения это аварийная ситуация

не всегда. И даже не в большинстве случаев.

Цитата(SABROG @  25.9.2008,  14:55 Найти цитируемый пост)
 volatile clock_t c1;    volatile clock_t c2;    volatile int value = 0;    volatile double avg = 0;

это как называется? "Какой плохой компилятор хватит оптимизировать?" smile


--------------------
Мой блог
PM MAIL WWW   Вверх
SABROG
Дата 25.9.2008, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Это понятно. Моей целью было замерить ту самую скорость из-за которой не советуют использовать исключения вместо кодов ошибок (напр. Bjarne Straustrup).

Добавлено через 3 минуты и 23 секунды
Цитата(vinter @ 25.9.2008,  14:17)
Цитата(Lazin @  25.9.2008,  15:07 Найти цитируемый пост)
а вот обработка исключения это аварийная ситуация

не всегда. И даже не в большинстве случаев.

Цитата(SABROG @  25.9.2008,  14:55 Найти цитируемый пост)
 volatile clock_t c1;    volatile clock_t c2;    volatile int value = 0;    volatile double avg = 0;

это как называется? "Какой плохой компилятор хватит оптимизировать?" smile

Я хотел оптимизации именно циклов (развертка циклов и т.п.).


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
vinter
Дата 25.9.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



SABROG, не занимайся ерундой, хочешь использовать - используй. А сидеть и пытаться вычислить наносекунду разницы это реально извращение.

Цитата(SABROG @  25.9.2008,  15:17 Найти цитируемый пост)
Я хотел оптимизации именно циклов 

volatile зачем юзаешь?


--------------------
Мой блог
PM MAIL WWW   Вверх
SABROG
Дата 25.9.2008, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(vinter @  25.9.2008,  14:41 Найти цитируемый пост)
SABROG, не занимайся ерундой, хочешь использовать - используй. А сидеть и пытаться вычислить наносекунду разницы это реально извращение.

Понимаешь в чем дело, мне нравятся исключения за то, что это хороший механизм не только для отладки, но и за более секьюрной идентификации ошибки вместо многоэтажных if'ов или case'ов. К тому же код выглядит более причесанным и легкочитаемым. И действительно хочется использовать исключения вместо кодов возвратов где только можно. Но везде пишут о том, какое это опасное оружие не в тех руках и при неправильном применении. Вот и хочется мне самому понять как все-таки стоит проектировать приложение с исключениями и в каких методых его стоит использовать. А если уж промахнусь, то кого винить за тормоза.

Цитата(vinter @  25.9.2008,  14:41 Найти цитируемый пост)

volatile зачем юзаешь? 


Занимаюсь копи-пастингом. Скопировал исходник из предыдущих тестов со строками ну и решил оставить, т.к. оптимизация или неоптимизация этих переменных ну никак не повлияет на скорость вызова функции и проверки последующего значения. Меня сейчас интересует не общая скорость выполнения функции, а дельта между использованием исключений и не использованием. А оптимизацию я включал и выключал, чтобы проверить оптимизирует ли как-нибудь компилятор сами исключения и циклы.

Может конечно и ерундой занимаюсь, но ведь придут и другие люди с тем же вопросом.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Lazin
Дата 25.9.2008, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



1-й вариант - функция не бросает исключения

Код

#include <iostream>
#include <time.h>
bool func();
using namespace std;
bool global = false;
int main(int argc, char *argv[])
{
    int numtest;
    //if (2 > argc)
    //{
        numtest = 100000000;
    //}
    //else
    //{
    //    numtest = atoi(argv[1]);
    //}
    volatile clock_t c1;
    volatile clock_t c2;
    volatile int value = 0;
    volatile double avg = 0;
    c1 = clock();
    for (volatile int i=0; i < numtest; i++)
    {
        global = (i % 1000) == 0;
        try
        {
            func();
        }
        catch(bool)
        {
            value++;
        }
    }
    c2 = clock();
    avg+=double(c2-c1)/CLOCKS_PER_SEC;
    printf("%f\n", avg);
    return 0;
}
bool func()
{
    if(global)
        return false;
        //throw true;
    return true;
}

работает примерно 1.5 сек

второй вариант - ф-я бросает исключение при каждом 100000-м вызове
Код

#include <iostream>
#include <time.h>
bool func();
using namespace std;
bool global = false;
int main(int argc, char *argv[])
{
    int numtest;
    //if (2 > argc)
    //{
        numtest = 100000000;
    //}
    //else
    //{
    //    numtest = atoi(argv[1]);
    //}
    volatile clock_t c1;
    volatile clock_t c2;
    volatile int value = 0;
    volatile double avg = 0;
    c1 = clock();
    for (volatile int i=0; i < numtest; i++)
    {
        global = (i % 100000) == 0;
        try
        {
            func();
        }
        catch(bool)
        {
            value++;
        }
    }
    c2 = clock();
    avg+=double(c2-c1)/CLOCKS_PER_SEC;
    printf("%f\n", avg);
    return 0;
}
bool func()
{
    if(global)
        throw true;
    return true;
}

работает за 1.6 сек.

Добавлено через 1 минуту и 46 секунд
то есть реально исключение обрабатывается только 100 раз, и на скорость сама его обработка не влияет, 5%-я разница это и есть стоимость использования исключений
PM MAIL Skype GTalk   Вверх
J0ker
Дата 25.9.2008, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



проясняю ситуацию
в современной программе практически НЕВОЗМОЖНО избавиться от оверхеда, накладываемого исключениями
почему?
потому, что вы вызываете функции сторонних библиотек и те в свою очередь делают то-же самое.
т.о. вы можете объявить throw() весьма ограниченное число собственных функций, которые либо не вызывают других функций вообще (включая неявные) либо вызывают заведомо функции не бросающие исключения. Иначе вы рискуете остаться без вызова деструкторов локальных объектов, т.к. данная функция не будет добавлена в таблицу размотки исключения. Смею напомнить, что стандартный new может выбросить исключение.
Т.о. даже если вы НЕ ловите исключения (или ловите их в саом конце - в main) вы НЕ МОЖЕТЕ промежуточные функции объявит throw().

точнее тут
http://forum.vingrad.ru/forum/topic-229145/kw-exception.html

Это сообщение отредактировал(а) J0ker - 25.9.2008, 20:15


--------------------
user posted image
PM MAIL   Вверх
SABROG
Дата 25.9.2008, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



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

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


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
UnrealMan
Дата 26.9.2008, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Механизм исключений по определению предназначен для обработки исключительных (т.е. редко возникающих) ситуаций. Если одна и та же ошибка то и дело возникает в каком-то цикле, то это уже не исключительная ситуация, и способы её обработки нужны соответствующие.
PM MAIL   Вверх
J0ker
Дата 26.9.2008, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



Цитата(SABROG @  25.9.2008,  23:02 Найти цитируемый пост)
Joker, вижу вроде написал что-то умное, но написал на каком-то, только тебе, понятном языке.

ну если выразиться по простому - любая функция объявляющая локальные объекты требующие разрушения и (функция-же) содержащая после этого вызов(ы) не throw() функций - (как минимум) всегда содержит в прологе регистрацию в таблице размотки. Т.о. этот оверхед по времени и по объему кода неизбежен. Оверхед catch-а и по времени и по объему ничтожный. Плюс, конечно-же, оверхед по объему от наличия самого стека размотки.
Сам-же процесс обработки исключения не во всех компиляторах оптимизирован, и поэтому тесты дают гигантский разброс. Отсуствие хорошей оптимизации связано с тем, что механизм исключений это НЕ РУТИННЫЙ механизм завершения блока, и должен использоваться для индикации действительно исключительных ситуаций.
Вобщем я дуаю что оценка в 5% - вполне достоверна...


--------------------
user posted image
PM MAIL   Вверх
Lazin
Дата 26.9.2008, 05:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(J0ker @  26.9.2008,  02:30 Найти цитируемый пост)
Вобщем я дуаю что оценка в 5% - вполне достоверна...

если бы функция func выполнялась достаточно долго, то там и 5-ти процентной разницы небыло-бы
PM MAIL Skype GTalk   Вверх
J0ker
Дата 26.9.2008, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14



Цитата(Lazin @ 26.9.2008,  05:32)
Цитата(J0ker @  26.9.2008,  02:30 Найти цитируемый пост)
Вобщем я дуаю что оценка в 5% - вполне достоверна...

если бы функция func выполнялась достаточно долго, то там и 5-ти процентной разницы небыло-бы

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


--------------------
user posted image
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0597 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.