Re[7]: [Investigation] Exceptions vs. Return Values
От: gear nuke  
Дата: 04.04.07 09:23
Оценка:
Здравствуйте, Programador, Вы писали:

P>Равноправны 2 регистра FS и GS это совсем не все


Если говорить о сегментных регистрах, то FS и GS далеко не одно и тоже. Но для С++ это не имеет значения, поскольку в Виндовсе плоская модель памяти, компилятор использует только регистры общего назначения (eax, ecx, edx, ebx, ebp, esi, edi; esp традиционно используется как указатель стека).

P>Я про рунтайм условия. Мы загружаем адрес, а память возможно не читаем, засчет этого ссылка на инт может быть быстрее


Зачем загружать адрес, если в дальнейшем не будет чтения? Это лишние действия, т.е. код не оптимален.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[8]: [Investigation] Exceptions vs. Return Values
От: CreatorCray  
Дата: 04.04.07 09:32
Оценка: +1
Здравствуйте, gear nuke, Вы писали:

GN>Если говорить о сегментных регистрах, то FS и GS далеко не одно и тоже. Но для С++ это не имеет значения, поскольку в Виндовсе плоская модель памяти, компилятор использует только регистры общего назначения (eax, ecx, edx, ebx, ebp, esi, edi; esp традиционно используется как указатель стека).

Еще активно используется FS для thread-specific штук типа TLS и исключений
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: [Investigation] Exceptions vs. Return Values
От: Programador  
Дата: 04.04.07 12:50
Оценка:
Здравствуйте, gear nuke, Вы писали:

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


P>>Равноправны 2 регистра FS и GS это совсем не все


GN>Если говорить о сегментных регистрах, то FS и GS далеко не одно и тоже. Но для С++ это не имеет значения, поскольку в Виндовсе плоская модель памяти, компилятор использует только регистры общего назначения (eax, ecx, edx, ebx, ebp, esi, edi; esp традиционно используется как указатель стека).


И что нет каких либо названий для первых четырех?
Потом говорить esp указатель стека просто по традиции не совсем корректно. Кстати вопрос — заметил что возможна адресация [esp+ofset] , чего мне кажется в 486 не было. Вроде ebp уже не актуален, тоесть можно пользовать esp, учитывай только что он меняется по мере проталкивания параметров. Тогда дополнительный свободный регистр появляется?


P>>Я про рунтайм условия. Мы загружаем адрес, а память возможно не читаем, засчет этого ссылка на инт может быть быстрее


GN>Зачем загружать адрес, если в дальнейшем не будет чтения? Это лишние действия, т.е. код не оптимален.


Я про
int fun(int &a,int &b)
{  extern int c;
   return c?a:b;
}

и
int fun(int  a,int  b)
{  extern int c;
   return c?a:b;
}
Re[9]: [Investigation] Exceptions vs. Return Values
От: CreatorCray  
Дата: 04.04.07 14:27
Оценка:
Здравствуйте, Programador, Вы писали:

P>Я про

P>
P>int fun(int &a,int &b)
P>{  extern int c;
P>   return c?a:b;
P>}
P>

P>и
P>
P>int fun(int  a,int  b)
P>{  extern int c;
P>   return c?a:b;
P>}
P>


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

Вообще тут уже ИМХО экономия на спичках...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: [Investigation] Exceptions vs. Return Values
От: remark Россия http://www.1024cores.net/
Дата: 04.04.07 18:54
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ну ты, например, можешь выложить то, что есть, а руки могут дойти у кого-то ещё


Нет смысла выкладывать — если это делать, то проще с нуля.
Больше времени потратишь, если будешь адаптировать мой код.


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

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


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


GN>Тем более, эти результаты неверны, это уже с++/rv+ex какой-то.


Почему не верны?
Для "чистого" случая я мерял С-код там ничего такого не было — если тебе нужен такой случай, то бери эти результаты.
А тут я намеренно мерил "с++/rv+ex" — т.к. это есть реальный паттерн — некоторые библиотеки используют именно а таком виде, например, ACE.


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


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


R>>В С — там код более явный, поэтому у компилятора меньше свободы, а в С++ менее явный — и у компилятора больше свободы.


GN>Интересная теория, я всегда считал что С и С++ перед оптимизацией трансформируется в одно и тоже ADT.


Я просто верб своим глазам, а машинный код говорит именно это...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[9]: [Investigation] Exceptions vs. Return Values
От: gear nuke  
Дата: 04.04.07 23:06
Оценка:
Здравствуйте, Programador, Вы писали:

P>И что нет каких либо названий для первых четырех?


Были, и для других то же, в 16ти битных процессорах.

P>Потом говорить esp указатель стека просто по традиции не совсем корректно. Кстати вопрос — заметил что возможна адресация [esp+ofset] , чего мне кажется в 486 не было.


В 16ти битном режиме нельзя было адресовать стек через sp.

P>Вроде ebp уже не актуален, тоесть можно пользовать esp, учитывай только что он меняется по мере проталкивания параметров. Тогда дополнительный свободный регистр появляется?


Andrew S писал тут про это не один раз. В случае ипользования исключений ebp занят под указатель на стековый кадр, иначе свободен.

P>>>Я про рунтайм условия. Мы загружаем адрес, а память возможно не читаем, засчет этого ссылка на инт может быть быстрее


GN>>Зачем загружать адрес, если в дальнейшем не будет чтения? Это лишние действия, т.е. код не оптимален.


P>Я про

P>
P>int fun(int &a,int &b)
P>{  extern int c;
P>   return c?a:b;
P>}
P>

P>и
P>
P>int fun(int  a,int  b)
P>{  extern int c;
P>   return c?a:b;
P>}

Во-первых, пример надуман, в реальном мире такого не будет (без const)
Во-вторых, поскольку размер int не больше, чем const int*, компилятору незачем использовать указатели, в лучшем случае код будет одинаков, в худьшем будут лишние копирования новых переменных (int a,int b).
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[7]: [Investigation] Exceptions vs. Return Values
От: gear nuke  
Дата: 04.04.07 23:06
Оценка:
Здравствуйте, remark, Вы писали:

R>Почему не верны?


Потому что написано с++/rv, а там с++/rv+ex (кстати, было и "там инструкции и на проверки возвращаемых значений и на поддержку исключений", но таблица сбила с толку )

R>Для "чистого" случая я мерял С-код там ничего такого не было — если тебе нужен такой случай, то бери эти результаты.


А, ну тогда практика согласуется с теорией — размер кода с исключениями не меньше, плюс еще размер неучтённых дополнительных данных.

R>Я просто верб своим глазам, а машинный код говорит именно это...


Я конечно соглашусь, что по машинному коду можно сказать: "вот это написано на С++". Потому что RAII, ООП и т.п. дают отпечаток даже () на исходном коде (как правило машинный код в этом случае не лучший). Но нельзя сказать уверенно: "это написано на С". Может быть и на С++. Никто же не запретит писать на С++ (практически) как на С. Когда активно используют расширенные возмоности — это видно. Например, по лишнему коду можно отличить std::auto_ptr от голого указателя, автоматические вызовы *структоров в new и delete от "эмуляции" их на С. Хотя на С++ можно получить более компактный результат, поскольку проще оптимизировать на более высоком уровне. А вот лушчего машинного кода у С++ я не только никогда не видел, но даже не могу понять, как большая свобода компилятора этому может способствовать
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[9]: [Investigation] Exceptions vs. Return Values
От: gear nuke  
Дата: 05.04.07 04:07
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Еще активно используется FS для thread-specific штук типа TLS и исключений


Не только для этого, но в сгенерированном из чистого С++ коде сегментных регистров не будет.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: [Investigation] Exceptions vs. Return Values
От: c-smile Канада http://terrainformatica.com
Дата: 05.04.07 05:41
Оценка: :)
Здравствуйте, remark, Вы писали:

R>

smart_ptr vs. smart_ptr&

R>Попутно я исследовал следующий вопрос – имеет ли смысл передавать умные указатели по ссылке вместо передачи по значению. Мы зачастую (ну я по-крайней мере ) передаю просто boost::shared_ptr без ссылок – по значению.
R>Функции аналогичные функциям из предыдущего теста – просто много форвардинга вызовов функций, без выделения ресурсов, но при этом между функцими передавался один boost::intrusive_ptr, в одном случае по значению, в другом по ссылке.

А зачем вообще передавать boost::intrusive_ptr<T> через параметры?

Что дает применение:

void foo( const boost::intrusive_ptr<T>& ptr )

по сравнению с
void foo( const boost::intrusive_ptr<T>& ptr )


Может я чего не понимаю но
boost::intrusive_ptr<T> это средство memory management — т.е. при чем здесь параметры?
Re[2]: [Investigation] Exceptions vs. Return Values
От: c-smile Канада http://terrainformatica.com
Дата: 05.04.07 05:43
Оценка:
Здравствуйте, c-smile, Вы писали:

Поправка:

Что дает применение:

void foo( const boost::intrusive_ptr<T>& ptr )

по сравнению с
void foo( const T* ptr )


Может я чего не понимаю но
boost::intrusive_ptr<T> это средство memory management — т.е. при чем здесь параметры?
Re[10]: [Investigation] Exceptions vs. Return Values
От: CreatorCray  
Дата: 05.04.07 06:23
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>но в сгенерированном из чистого С++ коде сегментных регистров не будет.

можно ли считать это чистым С++ кодом?
void foo()
{
 try
 {
  bar();
 }
 catch (...)
 {
  bar2();
 }
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: [Investigation] Exceptions vs. Return Values
От: minorlogic Украина  
Дата: 05.04.07 06:47
Оценка:
Возможно имелся ввиду shared_ptr ?
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[11]: [Investigation] Exceptions vs. Return Values
От: gear nuke  
Дата: 05.04.07 11:00
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>можно ли считать это чистым С++ кодом?

CC>
CC>void foo()
CC>{
CC> try
CC> {
CC>  bar();
CC> }
CC> catch (...)
CC> {
CC>  bar2();
CC> }
CC>}

Так и знал Это можно скомпелирвать g++ Формально я конечно не прав и MSVC использует FS (раз уж есть в ОС готовый механизм SEH). В этих случаях необходимость использования FS явно следует из контекста, его не нужно передавать в параметрах функции (как часть указателя). Говоря о плоской модели я всего лишь имел ввиду, что нет разницы, что адресует указатель — стек, хип, секцию данных исполняемого файла, даже адрес TIB — он всегда может храниться в любом из регистров общего назначения. (я бы лучше вместо fs вспомнил про eip, вот что действительно постоянно используется и является строго указателем )
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[12]: [Investigation] Exceptions vs. Return Values
От: CreatorCray  
Дата: 05.04.07 11:34
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Так и знал

Любопытно, что именно знал?
GN> Формально я конечно не прав и MSVC использует FS
Я бы сказал "в общем случае не прав".
Да и фраза "но в сгенерированном из чистого С++ коде сегментных регистров не будет" звучит так, как будто любой С++ код будучи откомпилирован не будет содержать сегментных регистров.

А во всем остальном —
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: [Investigation] Exceptions vs. Return Values
От: gear nuke  
Дата: 05.04.07 12:16
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Любопытно, что именно знал?


Что увижу этот пример

GN>> Формально я конечно не прав и MSVC использует FS

CC>Я бы сказал "в общем случае не прав".
CC>Да и фраза "но в сгенерированном из чистого С++ коде сегментных регистров не будет" звучит так, как будто любой С++ код будучи откомпилирован не будет содержать сегментных регистров.

Дык там я до этого писал "поскольку в Виндовсе плоская модель памяти" и далее продолжал в этом контексте. Если правильно понимаю, кастить к интегральному типу указатель в DOS — то сегментный регистр будет "добавлен" в результат, и наоборот; я имел ввиду, что в Виндовсе такого никогда не будет.

CC>А во всем остальном —


People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: [Investigation] Exceptions vs. Return Values
От: remark Россия http://www.1024cores.net/
Дата: 06.04.07 18:27
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, c-smile, Вы писали:


CS>Поправка:


CS>Что дает применение:


CS>
CS>void foo( const boost::intrusive_ptr<T>& ptr ) 
CS>

CS>по сравнению с
CS>
CS>void foo( const T* ptr ) 
CS>


CS>Может я чего не понимаю но

CS>boost::intrusive_ptr<T> это средство memory management — т.е. при чем здесь параметры?

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

Во-вторых, я отталкивался от boost::shared_ptr, который надо передавать, что бы его потом можно было скопировать и сохранить на будущее (иногда это можно сделать имея указатель, но не всегда). Потом я заменил shared_ptr на intrusive_ptr, что бы сделать копирование полегче... в итоге пример получился не очень вразумительным т.к. действительно из голого указателя всегда можно восстановить intrusive_ptr.

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

Отсюда, в частности, следуют следующие выводы:
— объекты CString и подобные быстрее всё же передавать по сслыке (хоть они и используют COW), особенно если таким образом получится "разрузить" функцию от объектов с деструкторами. Т.к. исчезает установка/снятие фрейма исключений.
— код:
for (...) 
{
  f1();
}

void f1()
{
  std::string s;
  ...
}


можно попробовать переписать как-то так:

for (...) 
{
  std::string s;
  f1(s);
}

void f1(std::string& s)
{
  ...
}


таким образом тоже элиминируем установку/снятие фрейма исключений в f1().



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: 2 Andrew S: методика замера времени
От: remark Россия http://www.1024cores.net/
Дата: 06.04.07 18:47
Оценка:
Речь идёт о замере интервалов порядка десятков тактов.

Я предлагаю следующую методику:
Выполняем код много раз подряд.
Разы, в которые произошёл вызов планировщика, переключение контекста, страничное прерывание и т.д. отбрасываем, как выдающие заведомо оооочень большое неправильное время, никак не связанное с нашим измеряемым кодом.
Т.о. получаем "истинное" время выполнения целевого фрагмента кода.


Ты предлагаешь (поправь, где не прав):
Выполняем код много раз подряд.
Разы, в которые произошёл вызов планировщика, переключение контекста, страничное прерывание и т.д. учитываем.
Потом "размазываем" эти ооочень сильно большие времена, усредняя все значения.
Т.о. получаем "истинное" время выполнения целевого фрагмента кода.

Т.е. ты считаешь нормальным, если, например, при замере одного фрагмента кода переключения контекста произошли 1 раз, а во время замера второго фрагмента кода переключения контекста произошли 2 раза. Потом мы усредняем эти времена и сравниваем.

Т.е. ты считаешь нормальным, если произошёл вызов планировщика, потом одно переключение контекста, потом поработал другой поток, потом опять вызов планировщика, потом опять переключение контекста и потом продолжила работать наша функция. Это нормально, это время можно включить в замер функции в 20 тактов. А вот если ко всему этому прибавляется ещё и пенальти, вызванное переключением потока на другое ядро, то вот это ты считаешь не нормальным, и для борьбы с этим предлагаешь делать привязку потока к ядру.

Аналогичная ситуация с поднятием приоритета потока. Ты считаешь, что вызов планировщика совершенно нормально учитывать при замере куска кода.

Ну уж извините, с таким подходом я в корне не согласен. Хоть убейте.



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

GN>Я конечно соглашусь, что по машинному коду можно сказать: "вот это написано на С++". Потому что RAII, ООП и т.п. дают отпечаток даже () на исходном коде (как правило машинный код в этом случае не лучший). Но нельзя сказать уверенно: "это написано на С". Может быть и на С++. Никто же не запретит писать на С++ (практически) как на С. Когда активно используют расширенные возмоности — это видно. Например, по лишнему коду можно отличить std::auto_ptr от голого указателя, автоматические вызовы *структоров в new и delete от "эмуляции" их на С. Хотя на С++ можно получить более компактный результат, поскольку проще оптимизировать на более высоком уровне. А вот лушчего машинного кода у С++ я не только никогда не видел, но даже не могу понять, как большая свобода компилятора этому может способствовать


В общем случае, если код делает одно и тоже, то и машинный код быдет таким же. Не виже никаких причин для обратного.

Вот набил такой пример:

__declspec(noinline) void auto_ptr()
{
    std::auto_ptr<int> i (new int(5));
}

__declspec(noinline) void by_hand()
{
    int* i = new int(5);
    delete i;
}

int main()
{
    auto_ptr();
    by_hand();
}


Ты не поверишь, но компилятор сделал следующее:


int main()
{
    auto_ptr();
0040109A  call        auto_ptr (401060h) 
    by_hand();
0040109F  call        auto_ptr (401060h) 
}
004010A4  xor         eax,eax 
004010A6  ret


Он даже не стал генерировать разных функций


Или вот ещё:


struct CPP
{
    int i;
    CPP()
    {
        __asm nop;
    }

    ~CPP()
    {
        __asm nop;
    }
};

struct C
{
    int i;

    void init()
    {
        __asm nop;
    }

    void deinit()
    {
        __asm nop;
    }
};

__declspec(noinline) void cpp()
{
    __asm nop;
    CPP cpp;
}

__declspec(noinline) void c()
{
    __asm nop;
    C c;
    c.init();
    c.deinit();
}

int main()
{
    cpp();
    c();
}



Машинный код:

__declspec(noinline) void cpp()
{
00401020  push        ecx  
00401021  nop              
00401022  lea         ecx,[esp] 
00401025  call        CPP::CPP (401000h) 
0040102A  lea         ecx,[esp] 
0040102D  add         esp,4 
00401030  jmp         CPP::~CPP (401010h) 



__declspec(noinline) void c()
{
00401040  push        ecx  
00401041  nop              
00401042  lea         ecx,[esp] 
00401045  call        init (401010h) 
0040104A  lea         ecx,[esp] 
0040104D  add         esp,4 
00401050  jmp         deinit (401010h)




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: 2 Andrew S: что мерить
От: remark Россия http://www.1024cores.net/
Дата: 06.04.07 19:22
Оценка:
Приведу твой ответ из ветки "Конструктив":

AS>Давай. Навскидку я вижу следующие паттерны:

AS>1. Чисто вычислительная функция — когда вызовов апи не производится вообще. Это может быть быть парсер текста, вычисление с использованием матриц и т.п. Желательно распределить их по степени сложности — глубины вызовов и количеству вызовов с проверками в одной функции.

согласен

AS>2. Обертки1. Когда ровно один слой и все сводится к вызову апи функции (или метода) и проверке возвращаемого значения\трансляции в исключение.


согласен — такой тест я делал

AS>3. Обертки1. Тоже ровно один слой, но в этом случае апи использует исключение (пример — MFC). Мы транслируем в свое исключение либо в код ошибки\возвращаемое значение.


в принципе не очень согласен но сделать можно, а потом пусть каждый сам решает насколько ему этот случай интересен

AS>4. Работа с файлами и анализ текста. Микс тест из 1, 2 и 3.


вот тут не очень понятно — ты что предлагаешь делать реальные вызовы ос?
я думаю, что это загубит весь тест, т.к. во-первых, время большое, а во-вторых, оно может сильно колебаться
а если не делать вызовов ос, то не понятно чем это отличается от (1)

AS>5. Смешанные вычисления — когда необходимо в процессе вычислений обращаться к апи. Сложность вычислений,процент обращений и характер распределения мест обработки по уровням можно регулировать (либо определить статистически общие варианты и использовать только их).


не понятно, чем отличается от (4)



что хотелось добавить — имхо тут надо делать всё-таки не очень нагруженные "мясом" тесты, что бы более "чисто" выделить вклад именно стратегий сообщения об ошибках. вызовы ос имхо накорню всё погубят. с вычислениями тоже надо быть осторожно — если тест получится memory bandwidth bound — то пиши пропало. т.е. имхо можно осторожно поделать какие-нибудь вычисления в регистрах, и повызывать заглушки ос. а в остальном оставить только "скелеты" от паттернов и при этом использовать невстраиваемые функции.


какие бы паттерны я добавил:
6. не понятно, почему обёртки в один слой. современные проекты насчитывают как минимум десяток слоёв (если считать в функциях), а то и больше. соответственно предлагаю мерить толстые обёртки. при этом варьировать толшину и ширину обёртки до "функций ос".

7. имхо обязательно надо мерить функции, использующие "ресурсы" — память/файлы/хендлы/соединения и т.д. в принципе это можно включить в предыдущий пункт, только варьировать ещё и кол-во ресурсов.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.