Разработка на PC и производительность — Memory Latency

    Herb Sutter (автор Exceptional C++, бывший глава ISO C++ standards committee, мистер Free Lunch Is Over и прочая, и прочая) работает в Microsoft и иногда по средам читает атомные лекции.

    Я наконец-то на одну такую попал, и очень радовался. На умных мужиков всегда радостно поглядеть и послушать.
    Для отчета — кроме Херба, видел живого Олександреску и живого Walter Bright (который "D").

    Лекция называлась «Machine Architecture: Things Your Programming Language Never Told You» (здесь можно скачать презентацию и видео) и была про конкретную часть abstraction penalty — Memory Latency.

    Я попытаюсь коротко рассказать о ключевой мысли лекции. Она простая, очевидная и тысячу раз сказанная. Думаю, еще раз повторить азбуку — никогда не повредит.


    Для самых маленьких, о том что такое Latency и Bandwidth


    Bandwidth — это ширина канала. Сколько можно прокачать данных за секунду, сколько можно пустить инструкций чтобы полностью загрузить ALU и так далее.
    Latency — это длина канала, то есть через какое время к тебе придут данные, которые ты попросил. Через сколько тактов к тебе придет запрошенный бит из памяти, через сколько тактов будет готов результат инструкции, когда команда пройдет до конца пайплайна и так далее.
    И они, разумеется, друг на друга влияют. Как только нужен результат, а делать больше нечего — весь bandwidth простаивает из-за latency. Запросили память, которой нет в кеше — сидим, ждем память. Захотели выполнить инструкцию, которой необходим результат предыдущей — ждем ее выполнения. Это создает «пузыри» в канале и соответственно уменьшает загрузку.

    Херб в презентации использует пример нефтепровода, он вполне наглядный. Можно прокачивать дикое количество баррелей в минуту, но каждый баррель идет до места назначения несколько дней. В чистом виде bandwidth и latency.

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

    И вот последние 20 с лишним лет показывают, что latency растет гораздо медленней. Особенно — latency памяти.


    Ща, у Херба там табличко была…

                                     
                        1980 VAX-11/750    Modern Desktop      Improvement since 1980 
    
    Clockspeed (MHz)            6           3000                +500x 
    
    Memory size (RAM, MB)       2           2000                +1000x 
    
    Memory bandwidth (MB/s)     13          7000(read)          +540x 
    
                                            2000(write)         +150x 
    
    Memory latency (ns)         225         ~70                 +3x 
    
    Memory latency (cycles)     1.4         210                 -150x (!!!!!!)
    


    Из таблички хорошо видно, что процессор хорошо растет, размер памяти хорошо растет, bandwidth памяти опять же зашибато, а вот latency со времен VAX — стало всего в три раза лучше. В расчете на такты (последняя строка) — ухудшилось в 150 раз.
    Что означает, что промах кеша стоит на порядки больше даже самых тяжелых инструкций процессора.

    В 80-х годах было просто и здорово — стоимость доступа к памяти была вполне сравнима, а то и меньше, вычислительных инструкций (а на floating point так и вообще),
    Есть процессор, диск и память, программист ими непосредственно и оперирует. Код выполняется прозрачно и предсказуем до такта.

    Сейчас же в железе на самом деле все по-другому. Доступ к памяти — сотни тактов. Да, за раз можно взять целый cache line (32 или 64 байта), но ждать все равно сотни тактов. В миллисекунду, например, получается обратиться в разные места памяти примерно 10000 раз. 100 объектов разных классов, вызов 10 виртуальных функций в каждом — уже 20+% от миллисекунды. В геймдеве — очень реальные цифры. А трафик памяти, вообще говоря, самое важное что у нас есть.

    И это все про память. Если полезли к диску — это уже совсем за пределами добра и зла, там latency в десятки миллионов тактов.

    Как это лечить — разумеется кешем и иерархией. L1 — 2 такта, L2 — 14 тактов, L3 — lets say about 40. Отдельно для данных, отдельно для инструкций.
    Сложная логика кеша, ноу-хау различных производителей процессоров и прочее.
    Кроме этого — обязательно out of order, чтобы пытаться выполнять то, что не зависит от ждущих.
    Out of order execution, register renaming, обязательно мощный branch prediction, обязательно стартовать доступы и записи в память как можно раньше. Если бранч пойдет не в ту сторону, это сразу рушит out of order и является катастрофой.
    Опять же, там внутри длинный конвейер. На P4 был даже патологически длинный — до 25 инструкций за раз и out of order заглядывал вперед на сотню. На последних процессорах конвеер меньше, но все равно непрозрачный.

    Саттер пишет, что на Itanium2 кеш занимает 85% площади процессора.
    На Core Duo — я не смог нагуглить, думаю примерно также.
    Еще 10 с лишним процентов — логика out of order, branch prediction и прочего добра.
    Остаются считанные проценты на собственно ALU, которые реально что-то считают.

    Современный процессор — это не вычислитель, а гигантский хардверный эмулятор x86-инструкций.
    Вся это нужно для того, чтобы спрятать от программиста latency. Чтобы можно было продолжать программировать в 80-х годах — когда есть только процессо и память, причем к памяти доступаться можно сколько угодно недорого. Чтобы продолжать запускать старый код все лучше, чтобы новый можно было писать также.

    И все же — мы пытаемся скрыть падение скорости в 150 раз! Незаметно для программиста! Не изменяя его структур данных! Так, чтобы он не заметил изменения порядка выполнения инструкций!

    Разумеется, это занятие никогда не будет оптимальным.

    Из того что программист в некотором смысле живет в стране эльфов, Саттер делает два практических следствия.

    Первое — это влияет на корректность программ


    Везде, где делаются предположения о последовательности чтений-записей в память, в любимой Саттером многопоточности.
    Если, предполагая, что запись int в память атомарна, начать делать lock free взаимодействие тредов — ушибешься.

    Например:

    Thread1:
    flag1 = 1;
    if (flag2 != 0) { …}
    // enter critical section

    Thread2:
    flag2 = 1;
    if (flag1 != 0) { …}
    // enter critical section



    Тред1 сначала выставляет flag1 — флаг того, что он хочет shared resource, и проверяет не занят ли второй ресурс другим тредом. Делается предположение, что flag2 проверится только после установки flag1 (чтобы не войти в critical section если она занята другим тредом).
    И будет тотальный превед — memory read на flag1 произойдет очень рано из-за out of order (формально, этот read ни от чего не зависит, поэтому его можно делать рано), и никакой синхронизации не будет.
    Поэтому нужно честно локать. Полагаться на память как на что-то, что отражает значения переменных — нельзя.

    Второе и самое веселое — конечно, производительность.


    Уже давно в основном тормозит память. В основном из-за latency, а не bandwidth. Случайное чтение памяти — много дороже целой тучи вычислений. Locality matters, на всех масштабах.

    Кстати, что такое «случайное» в реальной программе страшно размазывается из-за непрозрачной иерархии кешей.
    Вроде бы если используется много — то и так будет в кеше. С другой стороны, сколько реальный working set в разные моменты — толком и не прикинуть.
    А еще оно на каждом процессоре разное. А еще оно крайне зависит от данных. И самое классное — его еще и хрен померять!
    Свел пример к синтетическому — он стал помещаться в кеш. Превед.

    К счастью (к сожалению?), цена кеш-мисса столь велика, что серьезные проблемы можно померять и сквозь толстую прослойку.
    Скорость random access (меряем latency) против sequential access (меряем bandwith) отличается на порядок. Это разница между std::vector vs std::list.
    Хуже, это может быть разница между std::vector<T> vs std::vector<T*> (это, как все знают, и массив объектов в Java или .net ).

    В итоге — надо всегда думать о памяти. Как о локальности, так и о затратах.
    Мерять, не в память ли уперся. Когда в random access — можно продуктивно думать и решать. И когда в footprint — бывает тоже.

    На gamedeff вот тут описывался хороший пример такой борьбы за локальность.

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

    И я не знаю, что с этим делать в PC-мире


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

    С одной стороны, хочется больше контроля. Иметь четкое место в кеше, где я могу иметь гарантированное время доступа. Иметь некие гарантии того, что мне не попортят кеш при первом же context switch.
    Вот например, легко рассуждать о том, как хорошо все в консольном мире, где совсем другое железо. SPU, 256 kb полностью управляемой очень быстрой локальной памяти, четкие запросы в основную память широкими (чтобы прятать latency) DMA-пакетами. Или Xbox360, где можно локнуть на время часть кеша, да еще и попросить GPU из него рендерять.
    Ни одна из этих моделей не заживет на PC в чистом виде.
    На одном процессоре живет множество тредов одновременно, если каждый будет управлять 256 килобайтами памяти, то при context switch ее всю надо выгрузить и загрузить. Будет тяжелый и долгий context switch, а типично в OS ну просто дофига даже полу-активных тредов.
    Локать кеш нельзя позволять по тем же причинам — это означает либо буфферить его в память при context switch, либо забирать его навсегда от других приложений. Если забирать будут даже только активные — остальное станет тормозить.

    Хуже, основные аппликейшены — без всяких верхних границ. Могут загрузить документ и в 10 килобайт, и в 100 мегабайт. Размер Excel-таблицы может отличаться в тысячи раз, никаких верхних границ по памяти, как на консоли — не поставишь.

    Причем и набор железа, и количество памяти всегда разное, таргет вязкий — «кушать памяти поменьше и работать побыстрее». И железо больше эмулирует, чем работает.

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

    И это малая часть проблем. Я бы сказал, фундаментальные — backward compatibility и совсем другой чем на консолях баланс «performance против стоимости разработки». Но об этом можно как-нибудь потом писать бесконечно много.

    Напоследок, краткие медитативные цифирки (я брал у себя на домашней машине):

    floating point mul: 0.5-4 cycles (на одном ядре)
    L1 access (~16-32 kb): ~2-3 cycles
    L2 access (~2-4 mb): ~15 cycles
    Random Memory Access: ~200 cycles
    Sequential Access with Prefetch: ~2 bytes/cycle

    Остается бороться, мужики. Понимать цену абстракции и на этом уровне, не давать мозгам расслабляться и жить в восьмидесятых годах.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 70
    • 0
      Огромное спасибо за интересную статью!
      Для меня сейчас, вы — самый интересный автор на хабре )
        • 0
          а где бы про это можно подробней почитать??
          желательно с простыми примерами и с самого начала…

          пишу ресурсоемкие приложения на c++ (имидж процессинг), знаю что можно ускорить, но не знаю как ö(
          • +1
            Линк из предыдущего коммента очень хороший, начинать читать надо там ( lwn.net/Articles/250967/ )

            Если Image Processing — еще обязательно мануалы по SSE.
            Классические от Интела (http://www.intel.com/products/processor/manuals/), документацию из MSDN, и пару любых туториалов из гугла.
            Ну там, вот
            • 0
              спасибо за SSE, буду изучать.
              А есть ли здесь знатоки/любители CUDA ??
              • 0
                Ну, я знаю что-то о CUDA, мне по должности положено. На простые вопросы отвечу, за сложными лучше идти на специализированные форумы.
            • 0
              Использовать IPP, там уже все ускорено за вас.
              • 0
                К сожалению, в случаях хоть чуть отличающихся от мейнстрима, IPP может стать использовать тяжело.
                Но когда можно использовать — конечно нужно.

                Еще IPP хорошая проверка, насколько ты хорошо или плохо пишешь такие функции :)
                Можно проигрывать проценты, но не разы.
            • –4
              Очень познавательно. Я еще в университете забросил C++ из-за постоянной борьбы с компиляторами и проблемами выполнения кода на разных компьютерах. Ваша статья, отчасти, помогла понять чать проблем и то, почему многие программисты ругают современный подход Intel к проектированию процессоров.
              • +2
                Какой такой подход? x86 в отличие от любых других современных процессоров может выполнять неоптимизированное мясо, коим являются 90% программ, с хорошей скоростью.
                • +1
                  Процессор, ориентированный на мясо… (надо будет запомнить...) — как все универсальное: все делает, но хуже, чем узко-специализированные решения.
              • +14
                Впечатлило. Так вот оказывается почему консоли могут выдавать прекрасную графику на сравнительно средней аппаратной начинке.
                • 0
                  А вот вопрос к специалисту — а как с этим обстоят дела на больших компьютерах? Ну всяких спарках сановских, креях и прочих мегадолларовых устройствах?
                  • 0
                    А я не специалист ни разу по серверному железу. В Спарках вроде бы тот же DDR, так что проблемы все на месте. На сервере попроще, реалтайм-перформанс не так критичен.
                    За Креи совсем не знаю.
                    • 0
                      реалтайм-перфомансе важен в oltp, так-что там все тоже самое, только помноженное на промышленную эксплуатацию. :(
                      • 0
                        Я скорее в том смысле, что мне казалось, там важен bandwidth — сколько удается обработать запросов в секунду, а не latency — сколько занимает один запрос. В таком случае, проблемы в крайнем случае можно решать деньгами — увеличивать количество серверов и т.д., временем программиста, соответственно, только если оно оказывается дешевле серверов. Чем дальше ужимаешь — тем больше нужно усилий, в пределе — design for performance, войны за такты и прочее.
                        В реалтайме же такого размена вообще нет — критично время работы одной задачи на одной машине прямо здесь и сейчас. Становится веселее.
                        Впрочем, это я патриот низкоуровнего перформанса.

                        Оффтоп: интересно, как бы железную загрузку процессора показательно померять, чтобы сравнить…
                        • 0
                          В программе top в линухе есть такое поле — wa. Оно вроде как означает «waiting for IO» — процент времени, который проц проводит в ожидании ответа, не выполняя полезной работы. Ощутимо подскакивает во время плотного взаимодействия с диском — своппинг, например…

                          Ваш оффтоп — не из этой серии?
                          • 0
                            Мне скорее хочется процент утилизации железа. Насколько нагружены ALU, например.
                            • 0
                              В спарке есть счетчики циклов на каждом блоке, так что можно померить как кого грузили.
                  • +8
                    Чуствую себя лохом :(
                    Засиделся в пхп, пожалуй надо опуститься на low-level, хотя бы ненадолго.
                    • НЛО прилетело и опубликовало эту надпись здесь
                    • –2
                      Random Memory Access: ~200 cycles — это хорошо или плохо? А сколько у вас цикл? Чтобы не было таких глупых вопросов Latency измеряется не в циклах чего-то там, а в секундах — наносекундах. Поэтому у автора и такие бредовые результаты с ухудшением латентности в 150 раз по сравнению с 1980.
                      • +3
                        Только всё равно процессор простаивает 200 циклов, а мог бы делать полезную работу. Конечно, иногда out of order исполнение спасает, но не так часто, как хотелось бы.
                        • 0
                          Кто вам сказал что он простаивает эти 200 тактов? 200 таковый LLC miss+DTLB miss — это надо постараться так писать программы, чтобы у вас при каждом обращении в память такие простои были. А если промах один-два, то эти промахи скрадываются Out-Of-Order выполнением других инструкций.
                          • +1
                            С трудом себе представляю внеочередное выполнение сотни независимых, например, двухтактовых комманд. Если повезёт, выполнится две-три командны, остальные 190 тактов процессор будет крутится вхолостую.

                            Что же до промахов, любой список указателей на данные в куче потенциальный источник таких катаклизмов с высокой вероятностью.
                            • 0
                              точнее говоря, тут не только в программе дело

                              компилятор (статический оптимизатор) + железо (динамический out-of-order) делают свои дела. Причем на ILP (instruction level parallelism), то бишь железо, приходится основная доля распараллеливания в самом (самих) пайплаине (пайплаинах).

                              Кроме того не стоит забывать о MOB, L2 и victim cache.
                              • НЛО прилетело и опубликовало эту надпись здесь
                                • 0
                                  FFT кстати отлично переписывается на регулярные доступы. Матричное умножение отдельными локальными блоками порядка размера кеша.
                                  Вот тут показательный пример — lwn.net/Articles/255364/
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                • 0
                                  Два кеш-мисса — это значит out of order должен предоставить инструкций на 400 тактов, то есть сотни. Это очень немало, их вполне может не найтись.
                                  На самом деле, Hyper-Threading не в последнюю очередь был придуман затем, чтобы сглаживать такие простои. Пока один тред ждет на доступе к памяти, другой может выполняться. Но даже двух тредов мало, когда оба начинают генерировать стабильные кеш-миссы.
                              • +2
                                Вычислительная операция как была такт, так и осталась тактом (с учетом SIMD-операций и multicore, еще меньше). В 150 раз ухудшилось соотношение скорости памяти к скорости процессора. Это принципиально меняет факторы, влияющие на производительность приложения.
                                • 0
                                  Вычислительная операция — это абстрактное понятие. SSE делает 2 дабловых умножения за такт. 1 дабловое умножение при этом занимает 0.5 такта. Сингловое умножение, соответственно 0.25 тактов. А сейчас в Блумфилдах будет плавающий множитель и режим турбо, и такт у вас будет такой, чтобы влезать в TDP.
                                  >>В 150 раз ухудшилось соотношение скорости памяти к скорости процессора. Это принципиально меняет факторы, влияющие на производительность приложения.
                                  Это как раз не меняет. Как раньше хреново было, так и сейчас. Ничего нового. А вот ООО, кэш, префетч, предсказание переходов — это да, это — меняет.
                                  • 0
                                    Дык нет же. Раньше было совсем не так, вычисления были сравнимы с доступом в память. Ну комон, если раньше люди для того чтобы программа работала быстрее чаще пытались делать на сложение меньше, то теперь надо смотреть и думать о локальности памяти. Когда скорость доступа к памяти сравнима с обычной инструкций — вообще проблемы локальности не стоит.

                                    А вот когда она есть — тогда надо делать и out of order, и кешировать, и префетчить, и выбирать структуры данных.

                                    Мне кажется, если честно, у нас какое-то номиналистическое непонимание. Вы утверждаете «скорость доступа к памяти не увеличилась, ничего не поменялось». Я утверждаю «но на все остальное действовал закон Мура, и поэтому вес этого фактора принципиально возрос».
                              • 0
                                «Поставить поставить два процессора» — исправьте пожалуйста.
                              • +7
                                Отличная статья.

                                По поводу latency vs bandwidth говорят: «Bandwidth problems can be cured with money. Latency problems are harder because the speed of light is fixed – you can’t bribe God.»
                                • 0
                                  Практический вопрос: для скриптовых языков типа php или perl, c огромным расходом памяти, лучше использовать два медленных процессора вместо одного быстрого, получается? Есть ли конкретные рекомендации на эту тему — например, несколько бакэндов + фронтэнд vs один бакэнд+фронтэнд? И какое влияние многоядерности на доступ к памяти — будут ли двухядерные процессоры в сумме иметь меньшие потери производительности из-за латентности, чем одноядерный большей частоты в два раза?
                                  • +1
                                    Многоядерность она разная бывает. В исполнении с общей FSB многоядерность ухудшает доступ к памяти, поскольку вводятся дополнительные затраты на синхронизацию кэшей (снупинг). В исполнении NUMA все хорошо, когда каждое ядро вделяет память симметрично. Но как только одно ядро залезло в память другого — все, опять тормозим.
                                    Я честно скажу — не занимался профилированием скриптов, но на первый взгляд — высокая частота+оч большой кэш — вот что для них нужно. А какие-то вычислительные задачи лучше писать на С-подобных языках с жесткой оптимизацией под платформу — компилятором и/или руками.
                                    • 0
                                      Очень большой кеш — прямое следствие latency памяти. Уверенно пребывать в иллюзии быстрого доступа к памяти можно только если есть уверенность, что твой working set полностью в кеш влезает. Это вряд ли. Но большой кеш сглаживает степень падения, конечно :)
                                    • +2
                                      Извините, но Александреску… Как-то странно видеть написание его фамилии через «О».
                                      А статья правда интересная! Спасибо!
                                      • +1
                                        Дык эта, падонак-стайл. Я еще Оволон пишу, вместо WPF.
                                      • 0
                                        Можно ли считать процессоры без MMU/TLB более простыми, но и прогрессивными в архитектурном плане? (типа ARM'ов, как в сотовых телефонах и микроконтроллёрах)
                                        Будущее за простотой! Долой многоуровневую эмуляцию?
                                        • 0
                                          с 64-битовой адресацией без MMU можно без проблем жить, наверное. Но ведь виртуальная память — это не только эмуляция, но и изоляция.
                                          Хотя было бы здорово иметь одну абстракцию на дисковую память и физическую :) Соответственно, и механизмы защиты позаимствовать.
                                          • 0
                                            Все, как всегда, сложно. Процессорам на открытах платформах с обратной совместимостью — боюсь, придется играть в эти игры. Потому что а) людям не хочется шибко много думать, когда они пишут код и б) есть очень много уже написанного кода, который хочется запускать быстрее.
                                            Действительно «прогрессивные» в этом плане скорее Cell и Larrabee.
                                          • –2
                                            Вот, наконец-то поднимают эту тему! Сегодня проблемой десктопных приложений еще и становится то, что лентяи-программисты используют либо языки вроде явы/дотнета, либо библиотеки вроде Qt, которые, кроме всего прочего, отличаются непомерным большим потреблением памяти, в результате чего (я подозреваю) происходит намоного больше обращений к RAM так как эти монстры просто физически не могут поместиться в кеш.

                                            Кроме, того в ООП-библиотеках использутся многократное наследование, на каждом этапе в класс добавляются новые поля, в результате чего экземпляр класса занимает достаточно много места в памяти, и если многие поля не используются, то они все равно вытягиваются в кеш и отнимают там местло, так как все хранятся рядом.
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                              • –2
                                                Java и NET (пока что) место на сервере, а не на десктопе.

                                                Множество программ, начаная с классических winRAR/winAMP/foobar2000 и так далее написаны без всего этого и замечательно работали/работают.

                                                А тенденция использовать упомянутые технологии меня, как пользователя, не радует (а линусоидам еще хуже, там вообще пытаются к скриптовым языкам прикручивать Gtk, надеюсь вы и сами понимаете, какой ужас в результате полуается).
                                                • 0
                                                  А представьте как быстро .NET идет на КПК…
                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                • –1
                                                  Лентяи говоришь?
                                                  А головой подумать?
                                                  Вы же, наверное, не лентяйничаете и не ездите в транспорте, а идёте пешком?
                                                  Всегда есть 2 стороны медали.
                                                  Скорость и минимальность нужна не везде и не всегда. Да, к тому же, за неё приходится платить.
                                                  • –2
                                                    Ну хорошо, лентяи, я немного перегнул, тут скорее рыночные обстоятельства, то есть разработчику/программистам нужно реализовать выполнение программой каких-то задач к какому-то сроку, а уж насколько качественно это будет сделано — дело десятое, наверно писать исключительно хорошие программы невыгодно, где-то я читал… не помню, может у Споэльски.
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                      • 0
                                                        Боюсь, вы неправильно меня поняли. Я говорю о производительности языков для десктопных приложений, а не серверных. Согласен, на сервере можно хоть на Руби писать, так как всегда можно обеспечить нужную производительность покупкой хорошего железа, настройкой ОС, кешированием, масштабированием и прочим.

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

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

                                                        Другой вопрос, что с экономической точки зрения это не очень выгодно, выгоднее делать как придется. Но это извечный вопрос — сделать кое-как или качественно.

                                                        А в веб-технологии соотверственно внимание стоит уделять производительности client-side технологий, например js (многие приложения Гугла, например, на мой взгляд в этом плане сделаны так себе, авторы увлеклись созданием сложных интерфейсов на языке, который для этого не очень подходит).

                                                        Что касается вопроса про язык для десктопа — очевидно, нужно что-то вроде С++, только было бы замечательно, если б его кто-то подпилил, решив проблемы, начиная с классической проблемы исключений в конструкторе, и придумав нативные и производительные масивы и строки. Ну и мне. как человеку ленивому хотелось бы писать поменьше, то есть сделать автогенерацию заголовочных файлов, убрать необходимость описывать всякие структуры (автогенерация описания структуры, почему бы нет) и типы данных там, где они очевидны. ах, да, и include_once сделайте пожалуйста (или вообще уберите нафик заголовочные файлы) (не понимаю. почему никто до этого не додумался).

                                                        Ну и касательно библиотек (Gtk, Qt), они действительно неэффективны, соравните производительность наитивных Win приложений вроде notepad с такими же, написанными на этих библиотеках. Как говорится, разница видна невооруженным глазом. Ну и то, что имитировать ООП на Си — явное извращение, не стоит забывать (я читал про причины, побудившие это сделать, тем не менее это слабое и неэффективное решение).
                                                        • 0
                                                          Качество тут не при чём. Хотя что именно Вы имеете в виду говоря «качество»?
                                                          Для меня качество — это точность в решении поставленной задачи. Насколько хорошо решена задача? Вот что главное.
                                                          На шарпе пишут и хорошие, качественные программы, хотя жуют они больше чем жевал бы аналог но на С/С++
                                                          А ведь часто скорость в решении — не главное. Программа не обязательно должна быть «ультра» быстрой она должна быть достаточно быстрой для своей задачи. Тут важно соблюдать баланс. Разработчики часто перестают проверять perfomence вообще, а вот это уже плохо. Хотя крайности — обычно всегда плохо…
                                                          • 0
                                                            Если кратко: компьютер не должен реагировать медленнее мысли, человеческого мозга. Иначе пользователю приходится ждать, а это некомфортно.

                                                            > Для меня качество — это точность в решении
                                                            > поставленной задачи. Насколько хорошо
                                                            > решена задача? Вот что главное.

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

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

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

                                                            Сравните для примера Chrome и Firefox. Первый ест больше памяти (издержки технологии, надеюсь исправят), но запускается почти мгновенно. Что хорошего в браузере, который запускается с такой же скоростью, как последний 3Д Макс?(да и работает не быстрее). Ну и естественно, идею реализациии интерфейса на XUL/JS нельзя назвать грамотной, как и идею выполнять обработку событий интерфейса и JS-скрипты в одном потоке, тут просто сказать нечего. Хотя это и можно объяснить ограниченностью ресурсов у разработчиков (не так богаты, как Гугл все же) и «больной» историей (большое число команд учавствовало в разработке, в таких случаях архитектура страдает).

                                                            Какой смысл тогда подключаться к многомегабитному интернету, если страницы прорисовываются дольше, чем приходит очередная порция данных из сети?
                                                            • –1
                                                              >компьютер не должен реагировать медленнее мысли
                                                              Это в идеале. А в жизни всё сложнее.
                                                              >Не путайте, повторю еще раз, десктопные приложения и серверные или командно-строчные скрипты
                                                              Я не путаю. Когда я говорил про достаточную скорость я имел в виду все программы, вне зависимости от применения.
                                                              >но запускается почти мгновенно
                                                              Вот когда к нему прикрутят весь тот плагинный функционал что есть у фф тогда и будем сравнивать.

                                                              Вы приписываете мне свои мысли.
                                                              Скорость должна быть достаточной. Для любой программы.
                                                              • 0
                                                                > Вот когда к нему прикрутят весь тот
                                                                > плагинный функционал что есть у фф
                                                                > тогда и будем сравнивать.

                                                                Тормознутость браузера перечеркивает все преимущества плагинов. И эту тормознутость ничем не исправить, надо только подождать пару лет, когда железо станет помощнее. Если конечно программеры FireFox не придумают еще какуб-нибудь ресурсоемкую хрень.

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

                                                                >компьютер не должен реагировать медленнее мысли
                                                                > Это в идеале. А в жизни всё сложнее.
                                                                Не вижу ни одной убедительной причины, по которой программа может притормаживать на процессоре, выполняющем больше миллиарда (!) операций в секунду. Если программа делает что-то мега слодное — выведите градусник, но томрозов тем не менее быть не должно. Пользователь мог бы ввести поисковый запрос и сидеть смотреть результаты, делать выводы, а вместо этого он должен ждать пока загрузится браузер, тратя свое время. Какой смысл в быстром интернете с медленным браузером, объясните?
                                                                • –1
                                                                  >Какой смысл в быстром интернете с медленным браузером, объясните?
                                                                  Видео смотреть удобнее.
                                                                  >Не вижу ни одной убедительной причины, по которой программа может притормаживать на процессоре, выполняющем больше миллиарда (!) операций в секунду.
                                                                  Вы никогда не задумывались почему производители браузеров — огромные компании с миллионными оборотами? С большим штатом программистов? Даже целые войны были.
                                                                  Неужели Вы действительно умаете что всё так просто?
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                            • 0
                                                              Если кратко — в общем, вы правы. Я абсолютно не против использования библиотек, конечно, не писать же свою функцию printf() ))) Более того, нет наверно никакого смысла писать все самому, то, что уже написано и отлажено до тебя тысячей человек. Но почему люди просто тупо статически линкуют библиотеку целиком, даже если используют меньшую часть функций? (подозреваю, в опенсорсе это связано с тем, что gcc не умеет function-level linking)

                                                              Другой вопрос, что библиотеки бывают разные. Упомянутые мной Gtk и Qt (мое имхо) потебляют неадекватное количество ресурсов, посмотрите, сколько времени будет выполняться HelloWorld. Другой вопрос, что они дают чот-то вроде кроссплатформенности, но не дорогая ли выходит плата за кроссплатформенность? Особенно учитывая крошечный процент пользователей не-Win систем. Получается, что 97% человек платят за то, чтобы у оставшихся 3% эта программа тоже работала.

                                                              Другой пример. Есть такая замечательная программа DropBox. У нее очень классная задумка, а вот реализация — подкачала (именно десктопного клиента, к веб-инетрфейсу претензий нет). Эта программа, даже ничего не делая, сидя в трее потребляет под 50Мб памяти, как вы думаете, почему? А загляните-ка в папку программы и увидите там во-первых, Python25.dll, значит минимум часть программы написана на питоне, уже понятно, куда девается память и возможно скорость работы. Теперь заглянем в 24 мегабайтный екзешник, который представляет собой мало того, что debug-версию (руки бы поотрывать), так еще и является архивом. да-да, не ослышались, это архив, видимо во время запуска он куда-то распаковывается, на диск или в память. В архиве — тонна файлов и папок, ощущение, что это пакет с исходниками ядра Линукса)) Но нет, там куча (слава богу, откомпилированных) Питоновских файлов и библиотек. Ах да, еще несколько внушительного размера библиотек вроде wxmsw28uh_core_vc.dll (3 мб, нехилый размер для core). Вот и обяъяснение памятежоркости — Питон + WxWidgets. Нафига им сдался питон и WxWidgets — не пойму. неужели нет на С++ хороших библиотек. что творится-то? Или они денег все стоят? И почему, блин, Питон, если уж его использовать, не компилируется в машинный код.а превращается в какую-то хрень, помесь архива и exe-файла? По моему, так просто Питон под windows никому особо не нужен, вот все на его оптимизацию и забивают.

                                                              Вот такие вот печальные дела(
                                                              • –1
                                                                >Особенно учитывая крошечный процент пользователей не-Win систем. Получается, что 97% человек платят за то, чтобы у оставшихся 3% эта программа тоже работала.
                                                                Ага.
                                                                >debug-версию
                                                                А как Вы это узнали, если это архив?
                                                                >на С++ хороших библиотек. что творится-то?
                                                                Это называется прогресс. Кроме С++ в мире есть ещё много хороших языков программирования.
                                                                >И почему, блин, Питон, если уж его использовать, не компилируется в машинный код
                                                                >По моему, так просто Питон под windows никому особо не нужен, вот все на его оптимизацию и забивают.
                                                                Потому что он — интерпретатор. Вы бы для начала почитали что это такое, а потом уже критиковали.
                                                                Если он вам не нужен — это ещё не значит что не нужен никому.
                                                                Я уже не говорю о том что без этих «медленных и не нужных» (Python, C#, Java, Tcl ...) языков не появилось бы куча программ. Просто потому что их сложнее было бы делать.
                                                                • 0
                                                                  > А как Вы это узнали, если это архив?

                                                                  PEiD пишет MS VC 7.0 [ZIP SFX][Debug], а Тотал коммандер открывает содержимое (да-да, он и такое умеет)).

                                                                  > Потому что он — интерпретатор. Вы бы
                                                                  > для начала почитали что это такое, а
                                                                  > потом уже критиковали.

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

                                                                  > Я уже не говорю о том что без этих
                                                                  > «медленных и не нужных» (Python, C#,
                                                                  > Java, Tcl ...) языков не появилось бы куча
                                                                  > программ. Просто потому что их сложнее > было бы делать.

                                                                  На сервере — пожалуйста. Там за железо платит разработчик, а не пользователь)
                                                                  • –1
                                                                    >путь наименьшего сопротивления
                                                                    ну я понимаю, нужно всегда использовать трудный путь.
                                                  • –1
                                                    Разве не об этом Кнут не так давно говорил?
                                                    • 0
                                                      PC, конечно, изрядно нагружен обратной совместимостью, его тормозит эта самая latency, но процесс геймдева на консолях тормозят гораздо больше высокоуровневых вещей: закрытость и коммерческий характер платформы, отсутствие «любительского» движения разработчиков (моддеров и т. п.), не успевающие за законом Мура маркетинговые циклы… поэтому я спокоен за ПК и даже не собираюсь покупать какую-либо консоль. (Давно что-то у нас не было холиваров на эту тему...:))
                                                      • +1
                                                        Я готов и всегда рад разговаривать о вкусе устриц с кем-то, кто их давно и долго кушает. Где-то высказывались мнения людьми, лет 5 разрабатывающими под консоли?..
                                                      • –1
                                                        Вводная статья (обзорная) в архитектуру железок и проблему производительности приложений. Если автор хотел раскрыть тему производительности, то, думаю, этого не получилось. Только масса вопросов и домыслов родилась у всех… надо либо раскрыть до конца, либо не соваться в эту тему.

                                                        Статья породила в комментариях (мне кажется) холи вар среди сторонников managed и unmanaged языков программирования. Одни ругают их за «обжорство» и говорят «ай да низкоуровневое программирование», другие — отстаивают, хвалят их за скорость разработки приложений. По мне так надо всегда выбирать между оптимизированным, вылизанным, быстрым приложением и скоростью его разработки. В первую очередь заказчику (в конечном счёте мы все пишем для какого-то заказчика) надо работающее (корректно, без багов) приложение и в срок. А уж во вторую очередь приложение оптимизированное. Сразу поймать двух зайцев не удастся, уж поверьте. И лучше получит сначала первое, потом второе.

                                                        Кому действительно интересна тема низкоуровневой оптимизации тем рекомендую почитать вот эти вещи:
                                                        The Software Optimization Cookbook
                                                        The Software Optimization Cookbook, Second Edition
                                                        The Software Vectorization Handbook

                                                        Для оптимизации на многоядерных железках:
                                                        Multi-Core Programming
                                                        Optimizing Applications for Multi-Core Processors

                                                        Это, так сказать, отправная точка для тех, кому интересно. А вот «клубничка» — Code Optimization: Effective Memory Usage от Криса Касперского.
                                                        • 0
                                                          Холивора не видел. Что все зависит от требований и не всегда производительность приоритет — ну, в десятитысячный повторять не хочется, понимание читателя подразумевается.

                                                          Тема низкоуровневой оптимизации как таковой — слишком широка, чтобы ее объять одним постом. Или даже книгой, или даже жизнью одного человека. Саттер вот про Memory Latency выступил, Ульрих написал монументальный труд про память как таковую.

                                                          Поэтому я не очень понимаю, как можно целиком тему производительности раскрыть.
                                                        • 0
                                                          Очень интересная статья, с другой стороны жить как-то расхотелось сразу )
                                                          • 0
                                                            На самом деле out-of-order весьма фигово борется с memory wall, особенно в многозадачных и многопроцессорных системах. Предсказатели ветвлений не идеальны, если код не тупо потоковый (считаем сумму элементов массива), а логический (типа анализа того, куда юнит наступил), то они ошибаются очень часто, генерируют ложные обращения к памяти, к TLB, синхронизация кэшей. И вообще прочий ужас.

                                                            Кроме того, никуда нам не уйти от зависимостей. Код, в котором нет зависимостей — это тривиальные примеры, в чём-то более или менее сложных не бывает цепочек независимого кода длиной больше 100 инструкций. И P4 оказался провалом именно поэтому, потому что нет такого когда, который хорошо бы ложился на эти длинные конвейеры… Ну… Или этот код просто бы моделировал сферического коня в вакууме. В реальных программах не так уж и много микропараллелизма (независимостей, скажем, в анализе поведения персонажа в игрушке), зато много параллелизма уровня среднего (несколько моделей можно обсчитывать независимости), который out-of-order cpu просто не видит.

                                                            Поэтому, гораздо более мощное средство борьбы за сокрытие задержек — это SMT. Собственно, отчасти именно поэтому GPU такую звериную пиковую производительность имеют.

                                                            Ну. А борьба за локальность, конечно, актуальна при любой архитектуре.

                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.