- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
template<unsigned AxesQount, class Conten>
const Vector<AxesQount, Conten> Vector<AxesQount, Conten>::operator-(void) const
{
return *this*-1.0;
};
template<unsigned AxesQount, class Conten>
const Vector<AxesQount, Conten> Vector<AxesQount, Conten>::operator+(void) const
{
return *this;
};
я с векторами мало работал. знакомый у меня есть специалист. он говорил что стандартный val_array так обложен оптимизациями (что есть его raison d'etre) что ему около полугода надо было что бы все освоить и в нормальном темпе портировать старый векторный код с фортрана.
Вот уж обрадовал! Да за полгода с нуля на асме написать можно. Говно ваш С++, тормозное, непродуктивное говно.
с HPC (high performance computing) совместимых языков кот наплакал. Java/C# - гарбадж коллекшн отъедает 5-10% производительности с легкостью. 5-10% производительности от кластера стоящего $$$$$$$$$$ это все равно $$$$$$$$$ - или по-русски говоря - охуеть сколько денег. математические языки тоже есть, но не у всех есть нужные библиотеки и не все настолько портируемы как простые С/С++. ну фортран тоже есть, но хороший, правильно параллелизирующий компилятор стоит $$$$$.
и профит от порта на С++ тоже как бы почти очевиден: при переходе на другой кластер, нужно только перекомпилировать. С/С++ компиляторы либо бесплатные, либо стоят копейки (или комбинация: девелоперы сидят на GCC, релиз компилится коммерческим компилятором). Фортран нужно другую версию компилятора для другого железа лицензировать по новой.
пруф или не было.
в яве и дотнете выделение объекта - ничтожная операция, в то время как в с++ - целое событие.
также в с++ фрагментируется куча. если долго крутиться, то будет тормозить сильнее языка со сборкой мусора.
пруфы давай, что гц съъедает 5-10%, или пиздабол.
если ты обрабатываешь запросы с сети и никогда до полной CPU загрузки не доходишь, эффекта GC ты никогда и не увидишь: он работает в отдельном потоке и время его испольнения на времени обработки запроса не отражается.
а вот если до 100% доходишь ... ну мои коллеги уже поимели этот опыт. да как бы это батч джобы. никто там на время сильно не смотрит. наши тест делали только что бы знать насколько долго будет работать и будет ли вообще работать.
ну а так как я в контексте HPC постил, то понятно что там системы стараются на все 100% грузить. и на весь оверхед смотрят под лупой. кастом кернелы, кастом libc там нормальная практика. 1-2% выиграной производительность иногда значит что расчеты будут делаться несколько часов/дней быстрее - и за каждым процентом они гоняются.
> также в с++ фрагментируется куча. если долго крутиться, то будет тормозить сильнее языка со сборкой мусора.
старая проблема которая уже давно не проблема. почти на всех системах которых я работал есть выбор мемори аллокаторов. либо дежурный из либц, либо чего понавороченей для многопоточности/с защитой от дефрагментации/с поддержкой миллиардов мелких блоков. (E.g. Solaris' libumem, HP-UX's mallocng).
Нету пруфов - Идешь нахуй.
ЗЫ начинаю верить что гестов надо давить.
а что насчёт памяти? много ли выделялось? сборщик мусора какбэ просто так не работает, для этого условия нужны. когда памяти нормальное количество он засуспенжен же.
> с защитой от дефрагментации
какие алгоритмы? мне кроме прямого компактирования в голову ничо не приходит. а для него нужно иметь полноценный рантайм
с настройкой гц не баловались? с разными опциями (включить серверный режим, там)?
меня на те тесты звали как юниксода звали, что бы трейсы системы интерпретировать. тест делали ночью, работал где-то 5 часов - но на серваках памяти 64ГБ. тип задачи: маппинг полей входных сообщений по длииииному списку правил.
> какие алгоритмы?
сложно их даже алгоритмами называть. http://en.wikipedia.org/wiki/Memory_pool - это в принципе стандартная практика для телекоммуникационного софта.
хотя у нас и куча тупых С++ модулей которые и libc пользуются - и работают месяцами без проблем.
> с настройкой гц не баловались?
я строчку как они стартуют Яву наковырять могу. основная проблема в нашем случае что это должно работать не только с Сановской JRE, но так же и IBM'овской на AIX'ах. поэтому сильно на уровне JRE не оптимизуруют - больше сосредотачиваются что бы оно работало с обеими JRE (по граблям портабельности параметров Явы ходят постоянно).
Это немецкий?
У меня слёзы по лапкам потекли...
Это немецкий?
Что это значит вообще? this-1?
С++ говнО.
Кто ещё сомневается?
Как вообще пользоваться этой херью? Это куча какой-то каши, а внутри кот наплакал:
return *this*-1.0;
Это вот что-бы описать один ничего не делающий оператор - нужно написать столько говна?
Каково здесь соотношение полезного и бесполезного кода? Бесполезного примеро раз в 10ть больше. С таким кодированием проект и к новому году не закончить.
И вообще все эти операторы в С++ - не оптимальное быстродействие.
Ыыы. operator+ возвращает результат по значению. Афтар долбоёп. Он тем более потеряет быстродействие, особенно если вектор состоит, например, из пары тысяч значений.
единственная говнокодность это то что возвращаемое значение не константа и операция типа
-vec = other;
возможна хоть и бессмысленна...
вот листинг подобной функции для флоата
_TEXT SEGMENT
??$?GM$02@pmath@@YA?BV?$Vector@M$02@0@AB V10@@Z PROC ; pmath::operator-<float,3>, COMDAT
; ___$ReturnUdt$ = eax
; _v$ = ecx
; Line 201
fld DWORD PTR [ecx]
fstp DWORD PTR [eax]
fld DWORD PTR [ecx+4]
fstp DWORD PTR [eax+4]
fld DWORD PTR [ecx+8]
fstp DWORD PTR [eax+8]
fld DWORD PTR [eax]
fld DWORD PTR __real@bf800000
fmul ST(1), ST(0)
fxch ST(1)
fstp DWORD PTR [eax]
fld DWORD PTR [eax+4]
fmul ST(0), ST(1)
fstp DWORD PTR [eax+4]
fmul DWORD PTR [eax+8]
fstp DWORD PTR [eax+8]
; Line 202
ret 0
??$?GM$02@pmath@@YA?BV?$Vector@M$02@0@AB V10@@Z ENDP ; pmath::operator-<float,3>
; Function compile flags: /Ogtp
_TEXT ENDS
и для инта
_TEXT SEGMENT
??$?GH$02@pmath@@YA?BV?$Vector@H$02@0@AB V10@@Z PROC ; pmath::operator-<int,3>, COMDAT
; ___$ReturnUdt$ = eax
; _v$ = ecx
; Line 201
mov edx, DWORD PTR [ecx]
mov DWORD PTR [eax], edx
mov edx, DWORD PTR [ecx+4]
mov DWORD PTR [eax+4], edx
mov ecx, DWORD PTR [ecx+8]
mov DWORD PTR [eax+8], ecx
mov edx, DWORD PTR [eax]
neg edx
mov DWORD PTR [eax], edx
mov ecx, DWORD PTR [eax+4]
neg ecx
mov DWORD PTR [eax+4], ecx
mov edx, DWORD PTR [eax+8]
neg edx
mov DWORD PTR [eax+8], edx
; Line 202
ret 0
??$?GH$02@pmath@@YA?BV?$Vector@H$02@0@AB V10@@Z ENDP ; pmath::operator-<int,3>
; Function compile flags: /Ogtp
_TEXT ENDS
template<unsigned AxesQount, class Conten>
const Vector<AxesQount, Conten>& Vector<AxesQount, Conten>::operator+(void) const
В чём проблема?
так как при
vec1 = -vec2;
получим что оба вектора равны... а это неправильно....
Я бы так не стал утверждать. Всякие извращенцы всёж есть.
У вас плохая связанность предложений. Потренируйтесь на днях. Может среди программистов есть такие, что не умеют выражать мысли, тк для них разговор происходит слишком быстро, но на форуме есть время подумать и сформулировать свою мысль.
Этот человек, определённо, сильный. Не у каждого хватит смелости согласиться:
>ок...
Большинство ответит грубым хамством.
Вот бывает программисты работают с языками, а общаться с людьми не умеют. Странно... :(
Запись
Matrix c = a + b;
эффективнее, чем
Matrix c;
c = a + b;
Это описано в
http://valera.asf.ru/cpp/book/c14.shtml
после строк "14.8. Соображения эффективности A".
Кто-нибудь это проверял? Много, ли компиляторов, поддерживает эту оптимизацию?
Matrix c = a + b; // Вызывается оператор сложения и копирующий конструктор
Matrix c; // Конструктор по умолчанию
c = a + b; // Оператор сложения и оператор присваивания
Что-бы понять - легче прочитать. Там пару обзацев всего лишь. Всё читать не нужно.
Это в разделе: "14.8. Соображения эффективности A".
Ссылки на временные объекты/Семантика переноса (Rvalue Reference/Move semantics).
Это позволяет делать дополнительную более оптимальную перегрузку операторов c передачей параметра по &&. В том числе это позволяет возращать объекты по ссылке, вместо того, что-бы возвращать их по значению. Притом иногда нет необходимости выделять дополнительную память под объект, тк результат может храниться в этом самом временном объекте, который возвращаем по ссылке.
Остаётся дождаться стандарта, когда можно будет совсем избавиться от передачи результата по значению.
На основание статьи, о том, что для некоторых операций языки с динамическими типами работают быстрее языков со статическими типами (в том числе С++/C#/им подобные):
http://www.smalltalk.ru/articles/cpp-is-faster.html
Появилась статья, о применении опыта динамических языков для оптимизации в С++:
http://www.smalltalk.ru/articles/cpp-pic.html
http://www.smalltalk.ru/articles/cpp-pic.html
, что лучше делать так:
и использовать это:
взамен:
Это позволит убрать лишний вызов функции (закешировать) typeid(CA), хотя в хороших компиляторах это должна быть константа.
это не может быть константа. ходил недавно по граблям "почему RTTI (typeid(), dynamic_cast) под локом глобальным работает" (есть у нас там пара пидапрограммеров которые этим весь код свой обкладывают).
так вот расковырял относительно быстро: загрузка/выгрузка динамических библиотек меняет RTTI структуры приложения.
Почему не может?
typeid(CA) - получение идентификатора по типу, а идентификатор типа (не переменной) известен на этапе компиляции. Вполне может быть константой.
Приведённый выше код выполняет работу компилятора на всякий случай, если тот туп, но думаю в новых компиляторах это не понадобится.
:-)