LINUX.ORG.RU

Всё решает кэш, всё остальное - понты?

 , , , ,


1

1

Прочитав статьи ( http://rus-linux.net/lib.php?name=/MyLDP/hard/memory/memory.html http://www.es.ele.tue.nl/premadona/files/akesson01.pdf http://www.freescale.com/files/training_pdf/WBNR_FTF10_NET_F0686.pdf?lang_cd=en и http://www.freescale.com/files/training_pdf/WBNR_FTF11_NET_F0686.pdf?lang_cd=en ) у меня сложилось впечатление, что память - это основной botlneck после подгрузки данных с накопителя (PCI-e SSD). Получается, что если процесс часто не попадает в кэш (в нашем сегодняшнем мире браузеров, явы, огромных БД, компиляции и виртуализации сложно запихнуть в 8-16Мб памяти все данные приложения), то он будет сильно тормозить, при этом мы никак это не сможем увидеть (или, таки, есть средства?): он просто будет показывать 100% загрузки, тогда как реально процессор 90% времени ожидает память.

Получается, что для всех современных (т.е. «жирных») задач - всё решается кэш (и DDR4), а всё остальное - понты?

Также получается, что си и с++ быстрее явы только из-за того, что их структуры занимают меньше места в памяти, поэтому попадание в кэш происходит чаще, а использование мегатормозной памяти - реже?

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

facehoof.jpg

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

svr4
()
Ответ на: комментарий от svr4

major collection - это вообще говоря исключительаня ситуация и говорит о некомпетентности программиста. В правильно написанном приложении только minor должен быть.

anonymous
()

GC

Основные тормоза в Java бывают из-за сборщика мусора. Структуры там не больше чем в плюсах.

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

Подожди, у них еще netbeans грузится, им не до этого.

Deleted
()
Ответ на: комментарий от Artem_Korneev

C++ медленнее Java?!

не делать низкоуровневых оптимизаций

Что в словах «не делать низкоуровневых оптимизаций» неясно?

anonymous
()
Ответ на: комментарий от anonymous

Что в словах «не делать низкоуровневых оптимизаций» неясно?

Слово «низкоуровневых» не ясно. Не ясно, при каких это условиях С++ вдруг медленнее чем Java.

Один и тот же алгоритм, реализованный одинаково на С++ и Java будет быстрее работать на С++ по вполне очевидным причинам. Что и как нужно сделать с С++ чтобы оно стало медленнее Java?

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

Слово «низкоуровневых» не ясно.

Что именно неясно?

Один и тот же алгоритм, реализованный одинаково на С++ и Java будет быстрее работать на С++

Нет. Он будет работать одинаково. Быстрее на с++ он станет работать тогда, когда будут использованы низкоуровневые оптимизации, которые в джаве провести нельзя.

по вполне очевидным причинам

Это по каким? Хоть одну причину почему один и тот же машкод должен работать быстрее, если он скомпилирован из кода в плюсах, а не из кода в джаве, назвать можешь?

anonymous
()
Ответ на: комментарий от anonymous

Слово «низкоуровневых» не ясно.

Что именно неясно?

Я ж написал - слово «низкоуровневых». Какие именно оптимизации имеются в виду?

будет быстрее работать на С++

Он будет работать одинаково.

Я этого не наблюдаю. Я спросил у вас о пруфлинках, вы пока ничего не показали.

по вполне очевидным причинам

Это по каким?

В основном - GC.

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

В основном - GC.

Выше пример, где код благодаря gc будет работать _быстрее_

Я ж написал - слово «низкоуровневых». Какие именно оптимизации имеются в виду?

Те, которые невозможно произвести в джаве. Та же прямая работа с память например.

Я этого не наблюдаю.

Пруф обратного? Где одинаковый код на джаве работает медленнее, чем сишка?

anonymous
()

Я чего-то не знаю, или вы про существование кеш миссов спорите уже вторую страницу? В треде про кеш.

Midael ★★★★★
()
Последнее исправление: Midael (всего исправлений: 1)
Ответ на: комментарий от Midael

Я чего-то не знаю, или вы про существование кеш миссов спорите уже вторую страницу? В треде про кеш.

Подожди, рано ещё, мы ему пытаемся объяснить, что процессор читает данные блоками по 64 байта. Он же утверждает, что это не так, и процессор читает данные по размеру регистра.

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()

Посоны, а чо с царем стало? Чота вскукарекнул в начале и заглох. Али цари явы интеллектом задавили? тут как бы поле непаханое поставить этих ява-зазнаек на место, же!

anonymous
()
Ответ на: комментарий от Deleted

Жаба - интерпретируемый язык

Да откуда вы такие берётесь, каждый год новые?

Да, типа есть прекомпиляция в байт-код. Разницу в работе такого прекомпиленного байткода и чистого машинного кода, работающего без JVM объяснять надо?

Погугли сперва, когда в JVM появился JIT. И, да, JVM — это не «язык Жаба».

KRoN73 ★★★★★
()
Ответ на: комментарий от Deleted

Без JVM оно не будет работать в любом случае.

На Java-процессоре будет без JVM работать.

KRoN73 ★★★★★
()

Какой-то шайтан да покарает его всевышний... мэне тут будэт врать что всякий грязный нечистый жаба в своих ластах путаясь будет быстрей в свой грязный балота покочка прыгать чем белокрылый си стрелой летит? Тьфу ему в глаза его поганый!

anonymous
()

да именно так. я как раз обоснование пишу под свой проц и там вот такие ссылки: 1, 2

видно как графики загибаются вниз в последние годы.

а вот теоретическое обоснование и практическое подтверждение, что насасывают процы изза кэша. у них тупо очередь переупорядочивания меньше(напр. 40 в Pentium2 = 8*5 реально, причем эти 5-очень разные типы операций, 128 у i7 - это 16*8) в разы меньше значения где насасывание начинает спадать. Регистров в разы меньше, опять же по этой же причине - их много «всего» но сортами отличаются. +гирей висит просто малое колво регистров вообще, надо дрючить кэш на предмет локальных переменных(mov-mov-mov-mov-mov... - и так 40% команд)

Вот тебе пример - А15 может 3 команды за цикл но делает 1 за 2.2 цикла.Пень и7 может 4 за цикл а делает 1 за 0.7 цикла и это только потому что у него огромный L3. Убери L3 и будет насасывать как ARM

ckotinko ☆☆☆
()
Последнее исправление: ckotinko (всего исправлений: 1)
Ответ на: комментарий от anonymous

Выше пример, где код благодаря gc будет работать _быстрее_

Вы про это?

«Вполне может быть, что GC джавы расположит все данные рядом, а дефолтный C++-ный malloc раскидает по всем углам и в C++ будет хуже»

Да, мысль интересный. Теоретически - может быть. Бывает ли так на практике - не знаю.

Та же прямая работа с память например

Вы про собственные аллокаторы и размещающий «new» в плюсах? Тогда мысль понятна, спасибо.

Пруф обратного? Где одинаковый код на джаве работает медленнее, чем сишка?

Хотелось бы всё-таки исходить из хронологического порядка. Я попросил привести пруфлинки, подтверждающие, что java бывает быстрее. И сделал это на пару дней раньше. :)

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

Да, мысль интересный. Теоретически - может быть. Бывает ли так на практике - не знаю.

Это не может быть, это наверняка, потому что перемещающий сборщик после сборки выравняет данные гарантированно.

И не теоретически, а на практике, Я уже приводил тут пример, но его удалили, вот еще раз:

#lang racket
(require ffi/unsafe)
(collect-garbage)
(collect-garbage)

(define lib (ffi-lib "libracket3m_9yy8ml.dll"))
(define gc-enable! (get-ffi-obj "scheme_enable_garbage_collection" lib (_fun _int -> _void)))

(define lst1 '())
(define lst2 '())

;вырубаем gc:
(gc-enable! 0)

;создаем два списка вперемешку, память фрагментирована:
(for ([i 4000000])
  (set! lst1 (cons 0 lst1))
  (set! lst2 (cons (make-bytes 130) lst2)))

;обходим фрагментированный список:
(time
 (for ([i 10])
   (last lst1)))

->
cpu time: 1685 real time: 1685 gc time: 0

;включаем и запускаем gc, потребление памяти не падает, т.к. оба списка
;достижимы, собирать нечего, но сборщик перемещает конс-ячейки линейно, т.о.
;память перестает быть фрагментированной:
(gc-enable! 1)
(collect-garbage)

;обходим нефрагментированный список:
(time
 (for ([i 10])
   (last lst1)))

-> 
cpu time: 202 real time: 203 gc time: 0

Хотелось бы всё-таки исходить из хронологического порядка. Я попросил привести пруфлинки, подтверждающие, что java бывает быстрее. И сделал это на пару дней раньше. :)

Здесь важен не хронологический порядок, а логический. Бремя гипотезы (жаба медленнее сишки) лежит на высказавшем ее.

anonymous
()
Ответ на: комментарий от anonymous

Это не может быть, это наверняка, потому что перемещающий сборщик после сборки выравняет данные гарантированно.

Фраза «может быть» относилось к тому, что С++ на фрагментированной памяти будет работать медленнее, чем Java на нефрагментированной.

Вашу мысль я понял.

Я уже приводил тут пример, но его удалили, вот еще раз:

Пример интересный. Правда, с языком этим я не знаком и мне трудно оценить правильность замера производительности. Но спорить не буду, поверю вам - выглядит довольно правдоподобно.

Здесь важен не хронологический порядок, а логический. Бремя гипотезы (жаба медленнее сишки) лежит на высказавшем ее.

Конечно! Но мы ведь обсуждали совершенно другую гипотезу - что С++ медленнее Java. Вот эту гипотезу я и прошу чем-нибудь подкрепить.

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

Конечно! Но мы ведь обсуждали совершенно другую гипотезу - что С++ медленнее Java.

Я говорил, что в определенных случаях он будет медленнее (без низкоуровневых оптимизаций) Выше такой случай как раз и приведен - стандартный new будет тормозить (но, естественно, можно написать самописный аллокатор, который тормозить не будет - собственно, сам gc как раз и написан на той же сишке :)). В большинстве других же случаев сишка будет по скорости наравне с джавой. Выигрывать сишка начинает тогда, когда мы используем оптимизации, которые в джаве просто невозможны.

anonymous
()
Ответ на: комментарий от anonymous

Ну.. пока я ждал ответа, я сам немного порылся в бенчмарках. Первое, что пришло на ум - посмотреть бенчмарки на сайте Debian:

http://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=java&lang2=gpp

Там именно то, о чём я говорил - одна и та же задача реализована на разных языках. Как я и предполагал, почти во всех случаях Java медленнее. Причём, разница значительная, иногда в разы. Тем не менее, есть два бенчмарка, где Java уверенно обгоняет плюсы:

http://benchmarksgame.alioth.debian.org/u64q/fasta-description.html#fasta

http://benchmarksgame.alioth.debian.org/u64q/binarytrees-description.html#bin...

Мне, собственно, интересен не столько сам факт, сколько причины. Начал копать.

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

fasta secs KB Java 2.19 39,368 C++ g++ 4.18 1,700

Памяти съедено в ~20 раз больше, чем плюсовой версией. Может что-то удалось закэшировать или ещё как-то выиграть производительность за счёт памяти.. хотя и странно это - алгоритм должен быть одинаковым. Надо будет покурить детали.

Второй бенчмарк - обычное бинарное дерево. Я был изрядно удивлён. Впрочем, разница не столь велика чтоб сильно из-за этого переживать, но сам факт удивляет:

binary-trees secs KB Java 5.75 354,364 C++ g++ 7.72 362,628

Разница процентов в 20 в пользу джавы при приблизительно одинаковом потреблении памяти. При беглом просмотре исходников плюсовой версии:

http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&amp...

Обратил внимание на эту строку:

typedef boost::object_pool<Node> NodePool;

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

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

Ну блин.. форматирование в табличках с бенчмарками разъехалось. :(

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

Ну.. пока я ждал ответа, я сам немного порылся в бенчмарках. Первое, что пришло на ум - посмотреть бенчмарки на сайте Debian:

Они непоказательны, потому что там для кжадого языка свой алгоритм. Например в том же с++ используются арены для бинари_трис, вместо остандартного new.

anonymous
()
Ответ на: комментарий от anonymous

А что такое «арены»?

Там в требованиях написано:

«We ask that contributed programs not only give the correct result, but also use the same algorithm to calculate that result.»

Т.е. алгоритм должен быть таким же. Если вы считаете, что где-то алгоритм не соответствует требованиям - можно пнуть мейнтейнеров этого бенчмарка.

Artem_Korneev
()
Ответ на: комментарий от Artem_Korneev

А что такое «арены»?

Ну те же пулы. Когда выделяется кусок памяти, а потом объекты в нем. С-но, и удаляется потом этот кусок целиком.

Если вы считаете

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

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

И хули толку, если для двух разных деревьев все равно один пул будет использоваться.

Так это как раз хорошо - освобождаем пул и сразу освобождается память под _все_ деревья на данной итерации. Локальность не страдает т.к. деревья создаются целиком, а не вперемешку, причем порядок создания нод соответствует порядку обхода, то есть каждая последующая при обходе нода находится в памяти ровно после предыдущей. Собственно, вариант на сишке является практически оптимальным и соответствует варианту на джаве по производительности.

anonymous
()
Ответ на: комментарий от foror

Если в С++ не делать низкоуровневых оптимизаций, то он обычно на уровне Java или даже медленее

С++ без оптимизаций - это Java без JIT.

devl547 ★★★★★
()
Ответ на: комментарий от anonymous

Кстати честная реализация на gcc, которая соответствует алгоритмически варианту на джаве, там тоже есть:

http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&amp...

проигрывает варианту на джаве всего лишь в 7 раз. И это как раз характерный результат - при одинаковых затратах программы на си в несколько раз медленнее программ на джаве. Из-за gc.

anonymous
()
Ответ на: комментарий от devl547

С++ без оптимизаций - это Java без JIT.

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

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

тормозит она у криворуких длинноклювых ипланов. У здорового человека ява не тормозит.

anonymous
()
Ответ на: комментарий от anonymous

Ты напрочь деревянный. Она у всех тормозит потому что это язык для идиотов, кастрированный C++, созданный чтобы создать рабочие места для даунов. В 99% задач код написанный в лоб на C++ будет быстрее кода написанного на жабе. Даже изголяться особо не нужно, выбираешь оптимальный алгоритм и пишешь без особых оптимизаций - результат гарантирован жаба сольет (иногда на порядки)

anonymous
()
Ответ на: комментарий от anonymous

Утипути.

Это ява курильщика. Ява здорового человека, местами, сливает и кресты и криворуко написанный код на Си в унитаз. Ну а по скорости написания...да даже смешно вспомниать. Пока на С++ выйдет перальфа 0.01, ява будет уже в релизе 2 раза и нести бабло.

anonymous
()
Ответ на: комментарий от anonymous

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

В 99% задач код написанный в лоб на C++ будет быстрее кода написанного на жабе. Даже изголяться особо не нужно, выбираешь оптимальный алгоритм и пишешь без особых оптимизаций - результат гарантирован жаба сольет (иногда на порядки)

FIGHT!!

Обговаривайте условия. Публика требует крови!

anonymous
()
Ответ на: комментарий от anonymous

В реальной жизни жаба тормозит. В любой задаче жаба тормозит.

Конечно, тормозит, с этим никто не спорит. Проблема в том, что сишка в реальной жизни тормозит сильнее джавы.

anonymous
()
Ответ на: комментарий от anonymous

Так вон на шутауте примеры, сишка в 7 раз всосала.

anonymous
()
Ответ на: комментарий от anonymous

Даже изголяться особо не нужно, выбираешь оптимальный алгоритм и пишешь без особых оптимизаций - результат гарантирован жаба сольет (иногда на порядки)

Но почему на практике результат строго обратный? На том же шутауте практически во всех случаях «лобовой» код на плюсах сливает «лобовому» коду на жабке (иногда на порядки). А когда не сливает - идет наравне. Ни одной задачи, где жабка слила в «лобовом» коде сишке _вообще нет_.

anonymous
()
Ответ на: комментарий от anonymous

Чтобы можно было использовать из жабки сишные библиотеки. Ну и что, что медленно, зато самому велосипеды писать не надо. Но вот если надо ускорить - можно и переписать на джаву.

anonymous
()
Ответ на: комментарий от anonymous

Ты я смотрю не только деревянный но и смешной. Наверно с жабами в болоте живешь. Тебя не Пинок.IO звать?

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от devl547

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

anonymous
()
Ответ на: комментарий от anonymous

Да C# жабу как тузик грелку уж не один год как рвет! .Net это не тупой JVM с двумя с половиной недоязычками, а серьезная платформа для множества языков созданная в Microsoft Research.

anonymous
()
Ответ на: комментарий от anonymous

Особенно смешны попытки догонять .Net и пытаться на коленках лепить всяких мутантов типа Scala.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.