Один парень работает в серьезной конторе. пишут что-то супер сложное для отслеживания и обработки информации в реальном времени на с++. время обработки пришедшей инфы должно быть гарантированно меньше миллисекунды.
сегодня он обратился с вопросом
у меня есть функция которая должна дико быстро отрабатывать, есть переменная в ней char x[250].
вот где этот массив будет создаваться и где память очищается?
Я объяснил где, как и что это элементарная и очень быстрая операция.
Это как-то его не слишком убедило
но в этой функции на счету каждая микросекунда
мне нужен буффер просто
...
для sprintf нужно
Здравствуйте, WiseAlex, Вы писали:
WA>Я объяснил где, как и что это элементарная и очень быстрая операция.
Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
WA>Это как-то его не слишком убедило WA>[q] WA>но в этой функции на счету каждая микросекунда
Если и впрямь именно микросекунда, то речь безусловно не идет о Windows, а в таком случае лучше вообще рекомендаций не давать.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
Под машинами без аппаратного стека подразумеваются процессоры, в которых нет специальных инструкций для добавления/удаления слов в стек с автоматическим инкрементом/декрементом указателя вершины? Так это никак не влияет. В любом случае для резервирования места просто отнимаем (или прибавляем, в зависимости от направления роста) к указателю вершины нужную величину. Инструкции типа enter/leave — те же яйца, только в профиль, и производительности особо не добавят.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, WiseAlex, Вы писали:
WA>для sprintf нужно
Помню, в бытность мою работы в геймдеве (слава богу, всего полгода этого дурдома), один коллега засунул в какой-то цикл где обрабатываются полигоны локальный std::vector с push_back'ом для каждой вершины, скомпилил в дебаге с дебаговой же STL и потом рассказывал мне: "я так и знал шо этот STL такой тормозной".
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
ДД>Под машинами без аппаратного стека подразумеваются процессоры, в которых нет специальных инструкций для добавления/удаления слов в стек с автоматическим инкрементом/декрементом указателя вершины? Так это никак не влияет. В любом случае для резервирования места просто отнимаем (или прибавляем, в зависимости от направления роста) к указателю вершины нужную величину. Инструкции типа enter/leave — те же яйца, только в профиль, и производительности особо не добавят.
См. архитектуру IBM/360-370. В ней аппаратного стека вообще.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>См. архитектуру IBM/360-370. В ней аппаратного стека вообще.
Чем в данном случае "аппаратный" стек отличается от "программного"? Только тем, что в первом случае на вершину указывает отдельный регистр, во втором — обычная переменная.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>См. архитектуру IBM/360-370. В ней аппаратного стека вообще.
ДД>Чем в данном случае "аппаратный" стек отличается от "программного"? Только тем, что в первом случае на вершину указывает отдельный регистр, во втором — обычная переменная.
Я не помню, как там выделялась память (а скорее даже не знаю, так как работал на Фортране, а в нем тогда не было динамического выделения памяти в каком бы то ни было виде). Что я помню — что для выделения памяти использовалась специальная макрокоманда GETMAIN, но вот применялась ли она для выделения только динамической в нынешнем понимании или также и автоматической в нынешнем понимании памяти — сказать не берусь, и тем более утверждать, что для этого использовалась именно фиксированная переменная.
А отличия, конечно, есть. При занесении в стек ESP меняется автоматически, а насчет переменной на это надеяться не приходится. Хотя, конечно, эмулировать аппаратный стек программно можно.
WA>у меня есть функция которая должна дико быстро отрабатывать, есть переменная в ней char x[250].
WA>вот где этот массив будет создаваться и где память очищается?
WA>Я объяснил где, как и что это элементарная и очень быстрая операция. WA>Это как-то его не слишком убедило
может, потому что объяснили не слишком убедительно. а память точно будет очищаться?
WA>
WA>но в этой функции на счету каждая микросекунда
WA>мне нужен буффер просто
WA>...
WA>для sprintf нужно
смотря, что этот sprintf делает. если это "%s\n" то это одно, а если там идет очень сложное форматирование, то не факт, что самопальная реализация будет работать быстрее.
ЗЫ. довелось участвовать в собеседовании одного человека, претендующего на сеньера на руби. я руби не знаю, но что-то умное был спросить просто обязан (иначе на фига я присутствую?!). спросил первое что пришло в голову -- какой порядок оверхида (по расходу памяти) у разряженных массивов? чел сначала не понял вопроса (почему-то он думал, что сколько мы кладем в массив, ровно столько памяти и потребляем), а потом признался, что такое ему вообще не приходило в голову.
ЗЫ.ЗЫ. а если память все-таки очищается, то почему вы думаете, что иницилизация 250 (плюс выравнение) байт займет значительно меньше времени, чем sprintf?
P>ЗЫ.ЗЫ. а если память все-таки очищается, то почему вы думаете, что иницилизация 250 (плюс выравнение) байт займет значительно меньше времени, чем sprintf?
какие нафиг очистки, какие нафиг выравнивания???
sub esp, XXX — одна машинная команда на ВСЕ локальные переменные на входе, это разве новость?
Здравствуйте, vitasR, Вы писали:
R>Здравствуйте, poldhiir, Вы писали:
P>>ЗЫ.ЗЫ. а если память все-таки очищается, то почему вы думаете, что иницилизация 250 (плюс выравнение) байт займет значительно меньше времени, чем sprintf?
R>какие нафиг очистки, какие нафиг выравнивания???
ну напишите char buf[250] = {1,2,3}; сразу увидите какие очистки.
под x86 компилятор выделит 252 байт. потому как 250 не кратно 4м.
Здравствуйте, poldhiir, Вы писали:
P>>>ЗЫ.ЗЫ. а если память все-таки очищается, то почему вы думаете, что иницилизация 250 (плюс выравнение) байт займет значительно меньше времени, чем sprintf?
R>>какие нафиг очистки, какие нафиг выравнивания??? P>ну напишите char buf[250] = {1,2,3}; сразу увидите какие очистки. P>под x86 компилятор выделит 252 байт. потому как 250 не кратно 4м.
в оригинале было char buf[250], без инициализации. инициализировать буфер куда пойдет sprintf — гхм...
Здравствуйте, poldhiir, Вы писали:
p> R>какие нафиг очистки, какие нафиг выравнивания???
p> ну напишите char buf[250] = {1,2,3}; сразу увидите какие очистки. p> под x86 компилятор выделит 252 байт. потому как 250 не кратно 4м.
Ты в курсе, что есть стек? Регистр SP(ESP)и так далее? Если нет, то понятно.
Здравствуйте, ocaml, Вы писали:
O>Здравствуйте, poldhiir, Вы писали:
p>> R>какие нафиг очистки, какие нафиг выравнивания???
p>> ну напишите char buf[250] = {1,2,3}; сразу увидите какие очистки. p>> под x86 компилятор выделит 252 байт. потому как 250 не кратно 4м.
O>Ты в курсе, что есть стек? Регистр SP(ESP)и так далее? Если нет, то понятно.
Здравствуйте, poldhiir, Вы писали:
P>Здравствуйте, ocaml, Вы писали:
O>>Здравствуйте, poldhiir, Вы писали:
p>>> R>какие нафиг очистки, какие нафиг выравнивания???
P>0xFC это 252 байта. почему там объяснять, надеюсь, не надо?
252 байт обяснять не надо. надо обьяснить почему это время займет.
Здравствуйте, ДимДимыч, Вы писали:
ДД>Под машинами без аппаратного стека подразумеваются процессоры, в которых нет специальных инструкций для добавления/удаления слов в стек с автоматическим инкрементом/декрементом указателя вершины? Так это никак не влияет. В любом случае для резервирования места просто отнимаем (или прибавляем, в зависимости от направления роста) к указателю вершины нужную величину. Инструкции типа enter/leave — те же яйца, только в профиль, и производительности особо не добавят.
Все гораздо хуже. Бывают архитектуры, например популярный PIC16, где вообще нет относительной адресации памяти данных. А стек есть только для адресов возврата, фиксированного размера. Компилятор С в такой архитектуре строит т.н. компилированный стек еще в дизайн-тайме. Соответственно, все ф-ии становятся нереентерабельны. Писать трудно, но можно.
Здравствуйте, dudkin, Вы писали:
D>Здравствуйте, poldhiir, Вы писали:
P>>Здравствуйте, ocaml, Вы писали:
O>>>Здравствуйте, poldhiir, Вы писали:
p>>>> R>какие нафиг очистки, какие нафиг выравнивания???
P>>0xFC это 252 байта. почему там объяснять, надеюсь, не надо?
D>252 байт обяснять не надо. надо обьяснить почему это время займет.
где я говорил про время?! а надо бы сказать... если функция критична к времени выполнения, то создавая массив в стеке мы не можем быть уверенными, что он не вылетит на границы текущей страницы и ось не начнет аллоцировать память при первом к ней обращении. и это займет уж точно больше времени, что sprintf
Здравствуйте, sz36, Вы писали:
S>Все гораздо хуже. Бывают архитектуры, например популярный PIC16, где вообще нет относительной адресации памяти данных. А стек есть только для адресов возврата, фиксированного размера. Компилятор С в такой архитектуре строит т.н. компилированный стек еще в дизайн-тайме. Соответственно, все ф-ии становятся нереентерабельны. Писать трудно, но можно.
Да, я немного знаком с PIC'ами, писал несколько проектов под них. И распределение памяти в т.н. компилированном стеке (aka "программном") сводится к изменению значения указателя вершины стека, точно так же, как в случае с "аппаратным" стеком x86. И в данном случае неважно, распределяется ли память для локальных переменных в том же массиве, где хранятся адреса возврата (как в x86) или для адресов возврата есть отдельный стек ("аппаратный"), а для параметров и переменных — своя область памяти со стековой организацией доступа ("программный" стек). Распределение памяти сводится к изменению указателя вершины, будь то регистр процессора или просто переменная в памяти.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, sz36, Вы писали:
S>>Все гораздо хуже. Бывают архитектуры, например популярный PIC16, где вообще нет относительной адресации памяти данных. А стек есть только для адресов возврата, фиксированного размера. Компилятор С в такой архитектуре строит т.н. компилированный стек еще в дизайн-тайме. Соответственно, все ф-ии становятся нереентерабельны. Писать трудно, но можно.
ДД> Распределение памяти сводится к изменению указателя вершины, ДД> будь то регистр процессора или просто переменная в памяти.
поддерживаю. и вообще автоматическую память можно "эмулировать" и на си, размещая данные в куче, что упрощает борьбу с утечками. правда тут главное не забыть при выходе из функции перемесить указатель назад, но даже если забыть, то в отличии от malloc/free тут ничего трагичного не случится. допустим, фунция А зовет функцию Б, а функция Б зовет функцию B. допустим, что Б или В (или обе сразу) забывают освободить автоматическую память и в этом случае она освобождается по завершению А.
Здравствуйте, 4UBAKA, Вы писали:
UBA>Здравствуйте, poldhiir, Вы писали:
P>>0xFC это 252 байта. почему там объяснять, надеюсь, не надо?
UBA>Наверное такие опции компилятора выставлены?
у компилятора нет таких опций. кстати, если написать char a,b,c; то компилятор выделит три двойных слова даже если оптимизация отключена. и если выравниванием структур можно хоть как-то управлять, то отключить выравнивание стековых переменных нельзя никак. но это уже тонкости, которые, впрочем, иногда существенны при выборе типов переменных. скажем, если нам нужна переменная для хранения чисел от одного до пяти, то использование char не только не приведет к экономии памяти, а даже увеличит накладные расходы (компилятор выделит двойное слово как для int и расширит char до int, путем манируляций в ран-тайме -- увеличивается размер кода, увеличивается и время его выполнения).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
извините забыл написать — windows со всеми вытекающими
WA>>Это как-то его не слишком убедило WA>>[q] WA>>но в этой функции на счету каждая микросекунда
PD>Если и впрямь именно микросекунда, то речь безусловно не идет о Windows, а в таком случае лучше вообще рекомендаций не давать.
если бы речь шла о встроенной системе и/или аппаратных сложностях я не постал бы это в юмор.
зы. многие на рсдн со встроенными системами работали (и я не исключение) и про их особенности в курсе
Здравствуйте, WiseAlex, Вы писали:
WA>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
WA>извините забыл написать — windows со всеми вытекающими
И при этом идет борьба за микросекунды ??? Вот это действительно улыбку вызывает, но довольно-таки саркастическую. Выскочит какое-нибудь прерывание в ядре и плакали все микросекунды.
PD>Здравствуйте, WiseAlex, Вы писали:
WA>>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
WA>>извините забыл написать — windows со всеми вытекающими
PD>И при этом идет борьба за микросекунды ??? Вот это действительно улыбку вызывает, но довольно-таки саркастическую. Выскочит какое-нибудь прерывание в ядре и плакали все микросекунды.
И это сразу после
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
извините забыл написать — windows со всеми вытекающими
WA>>Это как-то его не слишком убедило
WA>>[q]
WA>>но в этой функции на счету каждая микросекунда
PD>Если и впрямь именно микросекунда, то речь безусловно не идет о Windows, а в таком случае лучше вообще рекомендаций не давать. если бы речь шла о встроенной системе и/или аппаратных сложностях я не постал бы это в юмор.
зы. многие на рсдн со встроенными системами работали (и я не исключение) и про их особенности в курсе
Спасибо, PD, за еще одну шикарную демонстрацию своего фирменного метода скорочтения: читать не вникая
D>>252 байт обяснять не надо. надо обьяснить почему это время займет. P>где я говорил про время?! а надо бы сказать... если функция критична к времени выполнения, то создавая массив в стеке мы не можем быть уверенными, что он не вылетит на границы текущей страницы и ось не начнет аллоцировать память при первом к ней обращении.
Такая аллокация для каждой конкретной страницы стека произойдет один раз за время жизни данного потока — слив не засчитан.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, kero, Вы писали:
K>А уж ты-то мне...
Так отстань, я же тебе говорил. Не смотри мои сообщения. Я твои давно не смотрю и не отвечаю. А у тебя какое-то извращенное желание их искать и комментировать.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, kero, Вы писали:
K>>А уж ты-то мне...
PD>Так отстань, я же тебе говорил. Не смотри мои сообщения. Я твои давно не смотрю и не отвечаю. А у тебя какое-то извращенное желание их искать и комментировать.
Неужель сам никаких нестыковок не заметил в этом сообщении?
Здравствуйте, Nik_1, Вы писали:
PD>>Так отстань, я же тебе говорил. Не смотри мои сообщения. Я твои давно не смотрю и не отвечаю. А у тебя какое-то извращенное желание их искать и комментировать. N_>Неужель сам никаких нестыковок не заметил в этом сообщении?
Ох, извини. Я-то думал, ты про опус kero
Нестыковки здесь нет. Я действительно сообщения kero не смотрю и на них не отвечаю. Разумеется, за исключением тех его сообщений, которые являются ответом на мои — эти сообщения и просматриваю все и на большую часть отвечаю.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>если выделить ровно 250 байт, то es[ станет невыравненным и все функции вызываемые оттуда замедлятся. знаешь про overhead of unaligned memory access?
Здравствуйте, 4UBAKA, Вы писали:
BZ>>если выделить ровно 250 байт, то es[ станет невыравненным и все функции вызываемые оттуда замедлятся. знаешь про overhead of unaligned memory access?
UBA>На выравнивание для байтов?
UBA>Будут нужны двойные слова и более — подравняемся.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>адрес возврата нужно пихать в стёк. если стёк будет невыравнен, то запись/извлечение этого адреса будет межленней
До или после локальных переменных? Что-то я забыл как это в Си...
Здравствуйте, 4UBAKA, Вы писали:
BZ>>адрес возврата нужно пихать в стёк. если стёк будет невыравнен, то запись/извлечение этого адреса будет межленней
UBA>До или после локальных переменных? Что-то я забыл как это в Си...
да без разницы, если есть вызовы внутри этой функции
Здравствуйте, BulatZiganshin, Вы писали:
BZ>а смысл? если вызовов нет, то ты сэкономишь 3 байта от силы. если есть — не сэкономишь ничего. да ещё потратишь время на выравнивание
А на ста отдельных чарах сколько?
Если есть или хотя бы может быть, то это можно определить в compile time.
Зы. А почему не надо выравнивать переменные на границу, например, параграфа?
Здравствуйте, WiseAlex, Вы писали:
WA>Один парень работает в серьезной конторе. пишут что-то супер сложное для отслеживания и обработки информации в реальном времени на с++. время обработки пришедшей инфы должно быть гарантированно меньше миллисекунды. WA>... WA>для sprintf нужно
Пока "менеджеры" и кадровики считают, что хороший программист должен получать меньше плохого менеждера, будет так. Будут платить 50тыр в течение полугода такому товарищу за "супермегаоптимизацию" вокруг sprintf() вместо того, чтобы заплатить 150тыр за 2 недели спецу, который проблему решит сходу и еще и гарантию даст. Увы и ах.
Здравствуйте, 4UBAKA, Вы писали:
UBA>Здравствуйте, BulatZiganshin, Вы писали:
BZ>>да без разницы, если есть вызовы внутри этой функции
UBA>См. выше: "Будут нужны двойные слова и более — подравняемся."
UBA>А 3 двойных слова на 3 char'а — хрень.
так работают все современные компиляторы. покажите компилятор, который так не делает -- будет очень интересно на него посмотреть. а раз так делают все -- значит, в этом есть определенный смысл, который становится понятым при анализе сгенерированного компилятором кода.
вы, конечно, можете написать свой компилер, который делает эту "хрень" не делает, но сомнительно, что это будет киллер фича, а логика кодогенерации усложнится изрядно. более того, работа с char на x86 более медленная чем с int, поскольку возможности процессора по работе с 8ми битными данными очень ограничены и компилер предпочитает не заморачится, а загонять char в двойное слово, по ходу маскируя три старших байта. с беззнаковым char'ом это еще ничего. а вот как только у нас появляется знак, так кол-во "вспомогателных" команд сразу возрастает.
вывод: char следует использовать или в больших массивах (там действительно экономия будет), либо же когда нам действительно нужен char, например, при написании парсера бинарного файла, но даже тут считанный char имеет смысл присвоить переменной типа int, как, собственно, и происходит в стандартных си библиотеках. функция читает char из файла, а возвращает... int!!!
Здравствуйте, poldhiir, Вы писали:
P>вы, конечно, можете написать свой компилер, который делает эту "хрень" не делает,
Уже ответил RedUser "GCC-4.3.2 так не выравнивает, по крайней мере, по умолчанию".
P>но сомнительно, что это будет киллер фича, а логика кодогенерации усложнится изрядно.
Самую малость.
P>более того, работа с char на x86 более медленная чем с int
Здравствуйте, WiseAlex, Вы писали:
WA>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека.
WA>извините забыл написать — windows со всеми вытекающими
Извини, но написать под Windows функцию, которая гарантированно выполняется менее миллисекунды, невозможно. Даже если функция выполняет одну операцию сложения. Потому как это не реалтайм система по определнию.
Кстати, тут в КСВ народ жаловался, что Виндовс иногда зависает в ядре на ~10мс в случайные промежутки времени. Это просто как реальный пример.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Eugeny__, Вы писали:
E__>Здравствуйте, WiseAlex, Вы писали: WA>>Здравствуйте, Pavel Dvorkin, Вы писали: PD>>>Ну-ну. Я бы для начала поинтересовался , для каких машин он пишет, что там за процессор и как выделяется память. А то мне в свое время доводилось иметь дело с машиной без аппаратного стека. WA>>извините забыл написать — windows со всеми вытекающими E__>Извини, но написать под Windows функцию, которая гарантированно выполняется менее миллисекунды, невозможно. Даже если функция выполняет одну операцию сложения. Потому как это не реалтайм система по определнию. E__>Кстати, тут в КСВ народ жаловался, что Виндовс иногда зависает в ядре на ~10мс в случайные промежутки времени. Это просто как реальный пример.
Ну, вы прям как 2-ой PD, право. Взгляните, в каком вы форуме.
Здравствуйте, WiseAlex, Вы писали:
WA>Один парень работает в серьезной конторе. пишут что-то супер сложное для отслеживания и обработки информации в реальном времени на с++. время обработки пришедшей инфы должно быть гарантированно меньше миллисекунды. WA>сегодня он обратился с вопросом WA>
WA>у меня есть функция которая должна дико быстро отрабатывать, есть переменная в ней char x[250].
WA>вот где этот массив будет создаваться и где память очищается?
WA>Я объяснил где, как и что это элементарная и очень быстрая операция. WA>Это как-то его не слишком убедило WA>
WA>но в этой функции на счету каждая микросекунда
WA>мне нужен буффер просто
WA>...
WA>для sprintf нужно
WA>
A где смеяться то? Ну лоханулся парень, который "работает в серьезной конторе". Все с чего-то начинали...
З.Ы.: Поражает то, как "коллеги по-цеху" готовы сожрать друг друга...