Re[17]: [Investigation] Exceptions vs. Return Values
От: Andrew S Россия http://alchemy-lab.com
Дата: 02.04.07 20:07
Оценка:
M>>>Я не хочу ничего объяснять , если вас заинтересовал этот вопрос , почитайте Криса Касперски.

AS>>Так, давайте, что именно? Или просто "отвяжись" — дык тогда может лучше так и говорить?


M>начать можно тут

M>http://www.codenet.ru/progr/optimize/kk/

И что там я обнаружу нового?
Вот цитата:

Непосредственные результаты замеров времени исполнения программы в "сыром" виде, как было показано выше, ни на что ни годны. Очевидно, перед использованием их следует обработать. Как минимум откинуть пограничные значения, вызванные нерегулярными наведенными эффектами (ну, например, в самый ответственный для профилировки момент, операционная система принялась что-то сбрасывать на диск), а затем... Затем перед нами встает Буриданова проблема . Мы будем должны либо выбрать результат с минимальным временем исполнения — как наименее подвергнувшийся пагубному влиянию многозадачности, либо же вычислить наиболее типичное время выполнения — как время выполнения в реальных, а не идеализированных "лабораторных" условиях.

Мной опробован и успешно применяется компромиссный вариант, комбинирующий оба этих метода. Фактически, я предлагаю вам отталкиваться от среднеминимального времени исполнения. Сам алгоритм в общих чертах выглядит так: мы выполняем N повторов программы, а затем отбрасываем N/3 максимальных и N/3 минимальных результатов замеров. Для оставшихся N/3 замеров мы находим среднее арифметическое, которое и берем за основной результат. Величина N варьируется в зависимости от конкретной ситуации, но обычно с лихвой хватает 9-12 повторов, т. к. большее количество уже не увеличивает точности результатов.


Ничего не напоминает? А рассуждения о том, что минимальное время выполнения зависит только от программного окружения — очень и очень спорно. Особенно при наличии многопроцессорных и неюниформных юнитов.
Кстати, там же и про RDTSC есть и про то, что и как он меряет. И почему то, что автора топика, неправильно. И читать это полезно как раз не мне (хотя мне это и интересно, впрочем, статью эту я уже читал), а автору топика и тестов...
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[18]: [Investigation] Exceptions vs. Return Values
От: minorlogic Украина  
Дата: 03.04.07 04:38
Оценка:
Теперь по крайней мере вы знаете, чем обусловленно стремление брать минимальное время.

А то что вопрос неоднозначен я знаю. Автору топика возможно это будет интерессно, но я бы вам предложил поправить замеры времени в коде , который он сибирался выложить.
Заранее спасибо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Ассемблер для Andrew S
От: minorlogic Украина  
Дата: 03.04.07 04:38
Оценка:
Ждем вашу версию исправленную
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Ассемблер для Andrew S
От: CreatorCray  
Дата: 03.04.07 06:25
Оценка: +1
Здравствуйте, remark, Вы писали:

Бугага! Тест то некорректен... Ну как можно мешать в одном exeшнике два теста которые требуют разных опций компиляции. Ладно б оптимизации так ведь исключений...

Раздели на 2 отдельных Exe шника
один с /EHsc и кодом основанным на исключениях
другой без и с кодом на return value
надо это для того, чтоб в rv тесте не было ничего связанного с исключениями.

запускай их РАЗДЕЛЬНО.

мои результаты:
test_ex: 127
test_rv: 120

Чуть модифицировал тест с целью посмотреть не на минимум а на полное время выполнения — читай среднее время выполнения

int main()
{
    int const test_count = 1000000;

#if 1
    {
        int ec = 0;
        tick_t time = 0;
        tick_t start = 0;
        tick_t t = 0;
        for (int i = 0; i < test_count; ++i)
        {
            start = get_tc();
            try
            {
                test_ex();
            }
            catch (...)
            {
                ++ec;
            }
            t = get_tc() - start;
            time += t;
        }
        std::cout << "test_ex: " << time << "\n";
    }
#else
    {
        int ec = 0;
        tick_t time = 0;
        tick_t start = 0;
        tick_t t = 0;
        for (int i = 0; i < test_count; ++i)
        {
            start = get_tc();
            if (!test_rv())
                ++ec;
            t = get_tc() - start;
            time += t;
        }
        std::cout << "test_rv: " << time << "\n";
    }
#endif
}


test_ex: 137504231
test_rv: 125761239

в среднем получается:

test_ex: 137
test_rv: 125

Ну как ни крути — у rv время меньше...

Опции компиляции: Intel C++ 9.1
icl /c /O3 /Og /Ob2 /Oi /Ot /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /GF /FD /EHsc /MT /YX"StdAfx.h" /Fp".\Release/test.pch" /FAcs /Fa".\Release/" /Fo".\Release/" /W3 /nologo /Zi /Gd /QxP
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: [Investigation] Exceptions vs. Return Values
От: remark Россия http://www.1024cores.net/
Дата: 03.04.07 08:28
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, remark, Вы писали:


R>>Там проблема, в том, что есть деструкторы — значит устанавливается и снимается фрейм исключений — т.е. тут двойная работа.


GN>Я о "с++/rv"


Ну так исключение всё равно может полететь, и деструкторы есть, значит фрейм всё равно надо устанавливать.

R>>А код С++ компилятор даже лучше генерирует — поскольку деструкторы не вызываются явно у него есть некая свобода в оптимизации.


GN>Не верю Компилятор там один и тот же.


В С — там код более явный, поэтому у компилятора меньше свободы, а в С++ менее явный — и у компилятора больше свободы.
Я глядел сгенерированный код "с++/rv" — я там даже сразу не понял, что он там к чему нагенерил — там он как-то хитро пишет прям в стек, т.е. не push/pop, а mov [sp],x и всякого такого рода вещи.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: [Investigation] Exceptions vs. Return Values
От: remark Россия http://www.1024cores.net/
Дата: 03.04.07 08:33
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Однако при отключенной (дебаг) получается чушь:


Ну под дебагом-то что код смотреть? Ты приведи пример, где под релизом так.

В msvc помогает "добить" такие места, где не идельная оптимизация, включение link-time code generation — он как раз вот такие "форварды" должен элиминировать.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Ассемблер для Andrew S
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 08:45
Оценка:
M>Ждем вашу версию исправленную

Вы мне предлагаете написать набор паттернов? Вроде как не я затевал эту тему
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Ассемблер для Andrew S
От: remark Россия http://www.1024cores.net/
Дата: 03.04.07 08:50
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>[code skipped]


AS>Нда, сильно. Вот почему я и говорю о необходимости кода.

AS>1. Тест в общем случае некорректен. В случае использования возвращаемого значения использовать идиому RAI нет необходимости, поэтому первые 4 сравнения идут лесом. Про что я и говорил — различные варианты обработки ошибок влекут использование различных паттернов на различных уровнях вызова.

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

AS>2. Вариант с rv у тебя с ошибкой


Бывает...
действительно bool res = fasle

AS>3. Где случай, в котором тебе надо вызывать функцию вне зависимости от результата вызова предыдущей? Т.е. вызвали одну, затем другую, затем третью и т.д. — а потом обрабатываем результат в зависимости от вызова. Т.е. не &&, а ||.

AS>4. Где вложенная обработка исключений, тоже непонятно. Впрочем, это боком относится к (3), но все же? Например, некоторые искючения могут позволить продолжить цикл (info\warning), тогда как другие ведут к выходу.

А если бы я привёл тот случай, ты бы сказал, а где у тебя этот случай
Что значит, где другой случай? Вот есть этот случай, я его тестирую. У меня в коде, по крайней мере, такие паттерны есть. Мне этого достаточно. По крайней мере для начала.


AS>5. Обрати внимание, что в rv варианте используется esp стек фрейм, а в ex — может и ebp. О чем я тебе уже 100 раз говорил.


Ни там, ни там не вижу использования ebp.
Приведи код и листинг. А то сейчас такое ощущение, что ты код не смотрел.


AS>6. Обрати внимание на разницу в способе вызова — в случае ex для настоящих объектов у тебя используеся this_call. Попробуй сделать не эмуляцию контрукторов функциями, а сделать init\deinit в самом tobj. Это съэкономит прилично и места, и времени.


Не понял. Приведи код, а то ещё долго будем припираться...


AS>А вообще, проблема на мой взгляд вот в чем. Ты берешь за основу модель исключений, и пытаешься приспособить под нее модель возвращаемых значений. Об этом говорит и использование bool в качестве возвращаемого значения (тогда как используется обычно более информативные типы, возвращающие не только успешность, но и саму ошибку — т.е. информации в разы больше), и построение функции (очередность и кратность вызова), уровень обработки (исключение у тебя обрабатывается на самом высоком уровне, тогда как общая практика — обработка части исключений на различных уровнях вызова, добавление отработки даже на одном уровне — то, что ты называешь ресурсами, уже изменяет ситуацию) и т.д. Неудивительно, что в этих условиях rv почти всегда проигрывает. У тебя полностью сферический конь в полном отсутствии воздуха. Я уже неоднократно говорил, что придумать ситуации, когда ex или rv будет выигрывать проблем не составляет. Нас должно интересовать не это, а реально существующие паттерны кода.


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


AS>PS Эк тебя зацепило Критику надо воспринимать не в штыки, а пытаться хотя бы слушать оппонента.


Тебя приходится не слушать, а гадать и вытягивать. Код был в первом посте — приведи наконец свой код.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[19]: [Investigation] Exceptions vs. Return Values
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 08:50
Оценка:
M>Теперь по крайней мере вы знаете, чем обусловленно стремление брать минимальное время.

Теперь? Автор топика сразу сказал, почему он берет минимальное время. Впрочем, обе стратегии в обычных условиях показывают некую тенденцию, а то, что тесты не совсем корректны — думаю, уже убедились. Так что надо смотреть код, как я неоднократно говорил — почему, например, автор не заметил, что вариант с rv используется другую спецификацию вызовов для эмуляции конструкторов\деструкторов? А это по 4 команды на каждый вызов, причем 2 из них — работы с памятью. Нормально так, да?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Ассемблер для Andrew S
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 08:52
Оценка:
CC>Бугага! Тест то некорректен... Ну как можно мешать в одном exeшнике два теста которые требуют разных опций компиляции. Ладно б оптимизации так ведь исключений...

Это да. Но все-же имхо это не должно в данном случае... хотя, нет, должно, в смысле, может. Выравнивание.

CC>мои результаты:

CC>test_ex: 127
CC>test_rv: 120

А можете привести листинги для функций? Вдруг ic там что проинлайнил? Он может....
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Ассемблер для Andrew S
От: remark Россия http://www.1024cores.net/
Дата: 03.04.07 08:59
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, remark, Вы писали:


CC>Бугага! Тест то некорректен... Ну как можно мешать в одном exeшнике два теста которые требуют разных опций компиляции. Ладно б оптимизации так ведь исключений...


CC>Раздели на 2 отдельных Exe шника

CC>один с /EHsc и кодом основанным на исключениях
CC>другой без и с кодом на return value
CC>надо это для того, чтоб в rv тесте не было ничего связанного с исключениями.

CC>запускай их РАЗДЕЛЬНО.


CC>мои результаты:

CC>test_ex: 127
CC>test_rv: 120

CC>Чуть модифицировал тест с целью посмотреть не на минимум а на полное время выполнения — читай среднее время выполнения


CC>test_ex: 137504231

CC>test_rv: 125761239

CC>в среднем получается:


CC>test_ex: 137

CC>test_rv: 125

CC>Ну как ни крути — у rv время меньше...


CC>Опции компиляции: Intel C++ 9.1

CC>icl /c /O3 /Og /Ob2 /Oi /Ot /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /GF /FD /EHsc /MT /YX"StdAfx.h" /Fp".\Release/test.pch" /FAcs /Fa".\Release/" /Fo".\Release/" /W3 /nologo /Zi /Gd /QxP


Скомпилировал код с возвращаемыми значениями как С-код:
test_ex: 172
test_rv: 184

Если суммировать:
test_ex: 1793656
test_rv: 1853848

Вот поэтому и было бы хорошо сделать "коробочный" тест, который можно было бы легко скачать, скомпилировать, запустить и выложить результаты для своей платформы.


з.ы. а мерить среднее время всё-таки некорректно, если ты запустишь тест несколько раз, то увидишь, что время "плавает", т.е. сказываются третьи факторы, с минимальным временем такого нет.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Ассемблер для Andrew S
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 09:14
Оценка:
AS>>3. Где случай, в котором тебе надо вызывать функцию вне зависимости от результата вызова предыдущей? Т.е. вызвали одну, затем другую, затем третью и т.д. — а потом обрабатываем результат в зависимости от вызова. Т.е. не &&, а ||.
AS>>4. Где вложенная обработка исключений, тоже непонятно. Впрочем, это боком относится к (3), но все же? Например, некоторые искючения могут позволить продолжить цикл (info\warning), тогда как другие ведут к выходу.

R>А если бы я привёл тот случай, ты бы сказал, а где у тебя этот случай


Так можно сделать оба? Или это будет слишком плохо для исключений, да?

R>Что значит, где другой случай? Вот есть этот случай, я его тестирую. У меня в коде, по крайней мере, такие паттерны есть. Мне этого достаточно. По крайней мере для начала.


Понятно.

AS>>5. Обрати внимание, что в rv варианте используется esp стек фрейм, а в ex — может и ebp. О чем я тебе уже 100 раз говорил.


R>Ни там, ни там не вижу использования ebp.

R>Приведи код и листинг. А то сейчас такое ощущение, что ты код не смотрел.

Код я тебе привел. Держи листинг...

?test_ex@@YAXXZ PROC NEAR                ; test_ex, COMDAT

; 467  : {

    push    ebp
    mov    ebp, esp
    push    -1
    push    $L107950
    mov    eax, DWORD PTR fs:__except_list
    push    eax
    mov    DWORD PTR fs:__except_list, esp
    sub    esp, 20                    ; 00000014H
    push    ebx
    push    esi
    push    edi

; 468  :     tobj o1, o2, o3, o4;

    lea    ecx, DWORD PTR _o1$[ebp]
    mov    DWORD PTR __$EHRec$[ebp], esp
    call    ??0tobj@@QAE@XZ                ; tobj::tobj
    lea    ecx, DWORD PTR _o2$[ebp]
    mov    DWORD PTR __$EHRec$[ebp+12], 0
    call    ??0tobj@@QAE@XZ                ; tobj::tobj
    lea    ecx, DWORD PTR _o3$[ebp]
    mov    BYTE PTR __$EHRec$[ebp+12], 1
    call    ??0tobj@@QAE@XZ                ; tobj::tobj
    lea    ecx, DWORD PTR _o4$[ebp]
    mov    BYTE PTR __$EHRec$[ebp+12], 2
    call    ??0tobj@@QAE@XZ                ; tobj::tobj

; 469  :     try
; 470  :     {

    mov    BYTE PTR __$EHRec$[ebp+12], 4

; 471  :         test_ex2();

    call    ?test_ex2@@YAXXZ            ; test_ex2

; 472  :         test_ex2();

    call    ?test_ex2@@YAXXZ            ; test_ex2

; 473  :         test_ex2();

    call    ?test_ex2@@YAXXZ            ; test_ex2

; 474  :         test_ex2();

    call    ?test_ex2@@YAXXZ            ; test_ex2
$L105166:

; 479  : }

    lea    ecx, DWORD PTR _o4$[ebp]
    mov    DWORD PTR __$EHRec$[ebp+12], 2
    call    ??1tobj@@QAE@XZ                ; tobj::~tobj
    lea    ecx, DWORD PTR _o3$[ebp]
    mov    BYTE PTR __$EHRec$[ebp+12], 1
    call    ??1tobj@@QAE@XZ                ; tobj::~tobj
    lea    ecx, DWORD PTR _o2$[ebp]
    mov    BYTE PTR __$EHRec$[ebp+12], 0
    call    ??1tobj@@QAE@XZ                ; tobj::~tobj
    lea    ecx, DWORD PTR _o1$[ebp]
    mov    DWORD PTR __$EHRec$[ebp+12], -1
    call    ??1tobj@@QAE@XZ                ; tobj::~tobj
    mov    ecx, DWORD PTR __$EHRec$[ebp+4]
    pop    edi
    pop    esi
    mov    DWORD PTR fs:__except_list, ecx
    pop    ebx
    mov    esp, ebp
    pop    ebp
    ret    0


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

AS>>6. Обрати внимание на разницу в способе вызова — в случае ex для настоящих объектов у тебя используеся this_call. Попробуй сделать не эмуляцию контрукторов функциями, а сделать init\deinit в самом tobj. Это съэкономит прилично и места, и времени.


R>Не понял. Приведи код, а то ещё долго будем припираться...


А что тут понимать? Если бы ты смотрел сгенеренный код:
ex:
    lea    ecx, DWORD PTR _o3$[ebp]
    mov    BYTE PTR __$EHRec$[ebp+12], 1
    call    ??0tobj@@QAE@XZ                ; tobj::tobj

rv:

    lea    ecx, DWORD PTR _o2$[esp+20]
    push    ecx
    call    ?ctor@@YA_NPAH@Z            ; ctor
    add    esp, 4
    test    al, al
    je    SHORT $L105177


Видишь, в одном случае параметр (this) передается в eсx, а во втором — через стек?

Вот как правильно (в смысле, соответствует твоему варианту теста):

struct tobj1
{
    bool init();
    void release();
    int fake;
};

bool tobj1::init() {return true;}
void tobj1::release() {}

static bool test_rv()
{
    tobj1 o1, o2, o3, o4;
    bool res = false;
    if (o1.init())
    {
        if (o2.init())
        {
            if (o3.init())
            {
                if (o4.init())
                {
                    res = test_rv2() && test_rv2() && test_rv2() && test_rv2();
                    o4.release();
                }
                o3.release();
            }
            o2.release();
        }
        o1.release();
    }
    return res;
}


    lea    ecx, DWORD PTR _o3$[esp+20]
    call    ?init@tobj1@@QAE_NXZ            ; tobj1::init
    test    al, al
    je    SHORT $L105190


Кроме того, если ты не будешь использовать bool, а нормальный int-based тип, то сравниваться будет eax, что обычно быстрее (т.к. команда другая).

Да, кстати, там у тебя еще одна ошибка — определение tobj использует int fake, а декларация — нет.

R>Это вполне реальный паттерн. Нет преобразования исключений. Исключений говорит о неудачности транзакции. Нет никаких частичных восстановлений и фаиловер. У меня лично такого кода очень много и я знаю, что и у других тоже. Я хочу мерить это.


Т.е. ты всегда выпускаешь все исключения наверх? Вообще, сколько я видел — обычно обрабатывают часть исключений на месте, дабы обеспечить реакцию (например, почему не завершена транзакция, не прочитан файл и т.п.), а затем в зависимости от действий пользователя продолжают выполнение.
В любом случае, то что у тебя — это лишь один из паттернов, и делать на только его основе какие-то выводы — по меньшей мере странно.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Ассемблер для Andrew S
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 09:20
Оценка:
R>з.ы. а мерить среднее время всё-таки некорректно, если ты запустишь тест несколько раз, то увидишь, что время "плавает", т.е. сказываются третьи факторы, с минимальным временем такого нет.

Поэтому и надо ставить приоритет реалтайм и привязывать к одном процессору, как тут уже говорили. Еще и рабочую область неплохо бы закоммитить.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[7]: [Investigation] Exceptions vs. Return Values
От: rm822 Россия  
Дата: 03.04.07 09:28
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, rm822, Вы писали:


R>>Здравствуйте, remark, Вы писали:


R>>>Здравствуйте, rm822, Вы писали:


R>>>>>>Двойка вам за научный подход.


R>>>Тут основная проблема, что бы сделать тесты справедливые для обоих стратегий.

R>>>Т.е. что я делаю — беру некую предельно простую абстракцию — ресурс — приписываю ему семантику — его надо выделить, причём выделение может провалится, и его обязательно надо освободить при выходе из функции. Далее я моделирую эту абстракцию на С++ и на С предельно "честно" по отношению к обоим языкам и их возможностям — на С++ — объект с деструктором, на С — функции construct/destroy. И сравниваю именно эти реализации одной и той же задачи разными средствами. Какая реализация быстрее?
R>>>Сравнивать тёплое с мягким нет смысла.
R>>>Т.е. нет смысла мерить типа "а что если мы в с++ вставим дополнительный new/delete" — ты тогда и в С вставь тоже что-то, что будет решать ту задачу, для решения которой ты в С++ вставил дополнительный new/delete.
R>>>Т.е. ты придумай некую абстрактную задачу, которая бы на С++ требовала применения иерархий ошибок/динамического полиморфизма и т.д., потом максимально "честно" вырази её решение на С, причём там, что бы тебе потом не говорили — а я бы это сделал подругому и быстрее. И вот тогда будем мерить, где решение задачи "мега динамической полиморфной обработки ошибок" работает быстрее.

R>>Реальность такова что для обработки исключений используется иерахия классов а не int.(Обычно) Для обработки ошибок error-кодами используется int а не классы. (Обычно) И сравнивать нужно именно теплое с мягким, потому что такова реальность.


R>Обычно и не думают о наносекундах, и что?

Короче, мне этот пустой пи.... надоел — сам все проверю когда время будет

R>>>
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[18]: [Investigation] Exceptions vs. Return Values
От: remark Россия http://www.1024cores.net/
Дата: 03.04.07 09:44
Оценка: +1
Здравствуйте, Andrew S, Вы писали:

M>>>>Я не хочу ничего объяснять , если вас заинтересовал этот вопрос , почитайте Криса Касперски.


AS>>>Так, давайте, что именно? Или просто "отвяжись" — дык тогда может лучше так и говорить?


M>>начать можно тут

M>>http://www.codenet.ru/progr/optimize/kk/

AS>Ничего не напоминает? А рассуждения о том, что минимальное время выполнения зависит только от программного окружения — очень и очень спорно. Особенно при наличии многопроцессорных и неюниформных юнитов.

AS>Кстати, там же и про RDTSC есть и про то, что и как он меряет. И почему то, что автора топика, неправильно. И читать это полезно как раз не мне (хотя мне это и интересно, впрочем, статью эту я уже читал), а автору топика и тестов...


Вот и он говорит, что можно брать и минимальное время тоже.
Тут зависит от того что мерить. Если мерить обращения к БД по сети, то возможно лечше брать некое среднее время. А если я хочу замерить время выполнения функции порядка десятков тактов, которая никак не связана ни со свопом, ни с памятью, ни с диском, ни с сетью и т.д., то самая оптимальная, т.к. "чистая", стратегия — это минимальное время. А уже все третьи задержки, будут одинаково добавляться что к одному времени, что к другому. Если будем мерить среднее в данном случае, то всё что получим — ненужную дисперсию.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Ассемблер для Andrew S
От: remark Россия http://www.1024cores.net/
Дата: 03.04.07 10:14
Оценка:
Здравствуйте, Andrew S, Вы писали:

R>>з.ы. а мерить среднее время всё-таки некорректно, если ты запустишь тест несколько раз, то увидишь, что время "плавает", т.е. сказываются третьи факторы, с минимальным временем такого нет.


AS>Поэтому и надо ставить приоритет реалтайм и привязывать к одном процессору, как тут уже говорили. Еще и рабочую область неплохо бы закоммитить.


Если мерить длинный интервал и запускать функцию _один_ раз, то да. В моём случае всё это учтено, поэтому ничего этого не надо — это никак не повлияет на результат.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Ассемблер для Andrew S
От: CreatorCray  
Дата: 03.04.07 10:17
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>А можете привести листинги для функций? Вдруг ic там что проинлайнил? Он может....

если указывать __declspec(noinline) — то не будет гарантировано.
Впрочем вот:

test_ex
    PUBLIC ?test_ex@@YAXXZ
?test_ex@@YAXXZ    PROC NEAR
$B3$1:                          ; Preds $B3$0
;;; {
$LN118:
        push      ebp                                           ;29.1
        mov       ebp, esp                                      ;29.1
        push      -1                                            ;29.1
        push      OFFSET FLAT: B3$EH                            ;29.1
        mov       eax, DWORD PTR fs:__except_list               ;29.1
        push      eax                                           ;29.1
        mov       DWORD PTR fs:__except_list, esp               ;29.1
        sub       esp, 16                                       ;29.1
        mov       DWORD PTR [ebp-16], esp                       ;29.1
        mov       DWORD PTR [ebp-28], edi                       ;29.1
        mov       DWORD PTR [ebp-24], esi                       ;29.1
        mov       DWORD PTR [ebp-20], ebx                       ;29.1
                                ; LOE ebx esi edi bl bh
$B3$2:                          ; Preds $B3$1
$LN119:
;;;     tobj o1, o2, o3, o4;
        mov       DWORD PTR [ebp-4], 0                          ;30.7
                                ; LOE ebx esi edi bl bh
$B3$3:                          ; Preds $B3$2
$B3$4:                          ; Preds $B3$3
$LN120:
        mov       DWORD PTR [ebp-4], 1                          ;30.11
                                ; LOE ebx esi edi bl bh
$B3$5:                          ; Preds $B3$4
$B3$6:                          ; Preds $B3$5
$LN121:
        mov       DWORD PTR [ebp-4], 2                          ;30.15
                                ; LOE ebx esi edi bl bh
$B3$7:                          ; Preds $B3$6
$B3$8:                          ; Preds $B3$7
$LN122:
        mov       DWORD PTR [ebp-4], 3                          ;30.19
                                ; LOE ebx esi edi bl bh
$B3$9:                          ; Preds $B3$8
$LN123:
;;;     test_ex2();
        call      ?test_ex2@@YAXXZ                              ;31.2
                                ; LOE ebx esi edi bl bh
$B3$10:                         ; Preds $B3$9
$LN124:
;;;     test_ex2();
        call      ?test_ex2@@YAXXZ                              ;32.2
                                ; LOE ebx esi edi bl bh
$B3$11:                         ; Preds $B3$10
$LN125:
;;;     test_ex2();
        call      ?test_ex2@@YAXXZ                              ;33.2
                                ; LOE ebx esi edi bl bh
$B3$12:                         ; Preds $B3$11
$LN126:
;;;     test_ex2();
        call      ?test_ex2@@YAXXZ                              ;34.2
                                ; LOE ebx esi edi bl bh
$B3$13:                         ; Preds $B3$12
;;; }
$LN127:
        mov       ecx, DWORD PTR [ebp-12]                       ;35.1
        mov       DWORD PTR fs:__except_list, ecx               ;35.1
        mov       esp, ebp                                      ;35.1
        pop       ebp                                           ;35.1
        ret                                                     ;35.1
                                ; LOE
;?test_ex@@YAXXZ    ENDS
destr_detour28$0$130::
destr_detour29$0$130::
destr_detour30$0$130::
$B3$15:                         ; Preds $B3$7 $B3$5 $B3$3       ; Very Infreq
$LN128:
        ret                                                     ;30.11
                                ; LOE
destr_detour27$0$130::
$B3$21:                         ; Preds $B3$1                   ; Very Infreq
$LN129:
        ret                                                     ;30.7
        ALIGN     2
B3$EH::                                                         ;
        mov       eax, OFFSET FLAT: FI_?test_ex@@YAXXZ          ;30.7
        jmp       ___CxxFrameHandler                            ;30.7


test_ex2
    PUBLIC ?test_ex2@@YAXXZ
?test_ex2@@YAXXZ    PROC NEAR
$B5$1:                          ; Preds $B5$0
;;; {
$LN132:
        push      esi                                           ;24.1
$LN133:
;;;     if (!++counter) throw 0;
        mov       eax, DWORD PTR ?counter@@3HC                  ;25.9
        add       eax, 1                                        ;25.9
        mov       DWORD PTR ?counter@@3HC, eax                  ;25.9
$LN134:
        jne       $B5$3         ; Prob 78%                      ;25.2
                                ; LOE ebx ebp esi edi
$B5$2:                          ; Preds $B5$1
$LN135:
        mov       DWORD PTR [esp], 0                            ;25.18
        lea       eax, DWORD PTR [esp]                          ;25.18
$LN136:
        push      OFFSET FLAT: __TI1H                           ;25.24
        push      eax                                           ;25.24
        call      __CxxThrowException@8                         ;25.24
                                ; LOE ebx ebp esi edi
$B5$3:                          ; Preds $B5$2 $B5$1
;;; }
$LN137:
        pop       ecx                                           ;26.1
        ret                                                     ;26.1
        ALIGN     2
                                ; LOE
; mark_end;
?test_ex2@@YAXXZ ENDP


test_rv
    PUBLIC ?test_rv@@YA_NXZ
?test_rv@@YA_NXZ    PROC NEAR
$B3$1:                          ; Preds $B3$0
;;; {
$LN114:
$LN115:
;;;     int o1, o2, o3, o4;
;;;     bool res = true;
;;;     if (!ctor(&o1)) goto end;
;;;     if (!ctor(&o2)) goto do1;
;;;     if (!ctor(&o3)) goto do2;
;;;     if (!ctor(&o4)) goto do3;
;;;     if (!test_rv2()) goto do4;
        call      ?test_rv2@@YA_NXZ                             ;50.7
                                ; LOE eax ebx ebp esi edi
$B3$2:                          ; Preds $B3$1
        movzx     eax, al                                       ;50.7
$LN116:
        test      eax, eax                                      ;50.2
        je        $B3$8         ; Prob 78%                      ;50.2
                                ; LOE ebx ebp esi edi
$B3$3:                          ; Preds $B3$2
$LN117:
;;;     if (!test_rv2()) goto do4;
        call      ?test_rv2@@YA_NXZ                             ;51.7
                                ; LOE eax ebx ebp esi edi
$B3$4:                          ; Preds $B3$3
        movzx     eax, al                                       ;51.7
$LN118:
        test      eax, eax                                      ;51.2
        je        $B3$8         ; Prob 78%                      ;51.2
                                ; LOE ebx ebp esi edi
$B3$5:                          ; Preds $B3$4
$LN119:
;;;     if (!test_rv2()) goto do4;
        call      ?test_rv2@@YA_NXZ                             ;52.7
                                ; LOE eax ebx ebp esi edi
$B3$6:                          ; Preds $B3$5
        movzx     eax, al                                       ;52.7
$LN120:
        test      eax, eax                                      ;52.2
        je        $B3$8         ; Prob 78%                      ;52.2
                                ; LOE ebx ebp esi edi
$B3$7:                          ; Preds $B3$6
$LN121:
;;;     if (!test_rv2()) goto do4;
        call      ?test_rv2@@YA_NXZ                             ;53.7
                                ; LOE ebx ebp esi edi
$B3$8:                          ; Preds $B3$7 $B3$6 $B3$4 $B3$2
$LN122:
;;;     res = true;
;;; do4:    dtor(&o4);
;;; do3:    dtor(&o3);
;;; do2:    dtor(&o2);
;;; do1:    dtor(&o1);
;;; end:    return res;
        mov       eax, 1                                        ;59.16
        ret                                                     ;59.16
        ALIGN     2


test_rv2
    PUBLIC ?test_rv2@@YA_NXZ
?test_rv2@@YA_NXZ    PROC NEAR
$B5$1:                          ; Preds $B5$0
;;; {
$LN125:
$LN126:
;;;     return !!++counter;
        mov       edx, DWORD PTR ?counter@@3HC                  ;39.13
        add       edx, 1                                        ;39.13
        mov       DWORD PTR ?counter@@3HC, edx                  ;39.13
        mov       eax, 0                                        ;39.13
        mov       ecx, 1                                        ;39.13
        cmovne    eax, ecx                                      ;39.13
        ret                                                     ;39.13
        ALIGN     2
                                ; LOE
; mark_end;
?test_rv2@@YA_NXZ ENDP
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Ассемблер для Andrew S
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 10:28
Оценка:
AS>>А можете привести листинги для функций? Вдруг ic там что проинлайнил? Он может....
CC>если указывать __declspec(noinline) — то не будет гарантировано.
CC>Впрочем вот:

Cудя по коду для rv, icc убрал вызовы ctor и dtor. Мы договорились этого не делать
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[6]: Ассемблер для Andrew S
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 10:29
Оценка:
R>>>з.ы. а мерить среднее время всё-таки некорректно, если ты запустишь тест несколько раз, то увидишь, что время "плавает", т.е. сказываются третьи факторы, с минимальным временем такого нет.

AS>>Поэтому и надо ставить приоритет реалтайм и привязывать к одном процессору, как тут уже говорили. Еще и рабочую область неплохо бы закоммитить.


R>Если мерить длинный интервал и запускать функцию _один_ раз, то да. В моём случае всё это учтено, поэтому ничего этого не надо — это никак не повлияет на результат.


Ладно, ладно, мы все тупые, а ты один умный. Делай как знаешь
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[19]: [Investigation] Exceptions vs. Return Values
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.04.07 10:35
Оценка: +1
M>>>>>Я не хочу ничего объяснять , если вас заинтересовал этот вопрос , почитайте Криса Касперски.

AS>>>>Так, давайте, что именно? Или просто "отвяжись" — дык тогда может лучше так и говорить?


M>>>начать можно тут

M>>>http://www.codenet.ru/progr/optimize/kk/

AS>>Ничего не напоминает? А рассуждения о том, что минимальное время выполнения зависит только от программного окружения — очень и очень спорно. Особенно при наличии многопроцессорных и неюниформных юнитов.

AS>>Кстати, там же и про RDTSC есть и про то, что и как он меряет. И почему то, что автора топика, неправильно. И читать это полезно как раз не мне (хотя мне это и интересно, впрочем, статью эту я уже читал), а автору топика и тестов...

R>Вот и он говорит, что можно брать и минимальное время тоже.


Когда он это говорил, про мультиядерность, доступную обычному юзеру, еще не было и речи. Соответственно, не было речи и про NUMA, про синхронизации кешей и прочие вещи, характерные для многопроцессорных систем. Минимальное время выполнения там зависит от аппаратных компонент, на которых по прихоти шедуллера будет выполняться код. Правда, там есть упоминания о беспричинных выпадениях для K7 и KT133. Поэтому выпадения минимума могут быть _НАСТОЛЬКО_ редки и нехарактерны, что ты можешь с приличной вероятностью получить fake (даже программно — например, для одного варианта шедулер может всегда выбирать один юнит, а для другого — например, всегда другой). Гарантировать ты это в твоей реализации не сможешь. Поэтому и надо:
1. Привязывать к юниту.
2. Поднимать приоритеты.
3. Брать средне-минимальное время.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.