Pull to refresh

Comments 468

А ещё можно было ба написать версию для тензор ядер… Было бы вообще огонь по скорости.

Если так уж нужна скорость, можно сделать специализированный вычислитель (систолический массив?) на каком-нибудь ASIC.

UFO just landed and posted this here
UFO just landed and posted this here
Если сейчас (да и раньше) программисты писали на медленных яваскрипт и python, то почему через несколько лет, когда производительность еще вырастет, и только потом остановится, все сразу убегут на C++?
UFO just landed and posted this here
Хм, почему сейчас ПО по-вашему «развивается», а вскоре вдруг перестанет? Нет, ну может быть лет через 50 такое и наступит, но мне к тому моменту будет уже глубоко на это пофиг
Процессоры стали работать в 2 раза быстрее -> появляется новый фреймворк, который работает в 2 раза медленнее, но ускоряет разработку на 30%. Оптимизировать некогда, нужно осваивать новый фреймворк. А внутри этого фреймворка всё примерно также — некогда было оптимизировать, срочно осваивали новую библиотеку/стандарт/подход. И вот так оно растёт, аки снежный ком — вот такое сейчас «развитие».
Когда процессоры будут удваивать скорость лет за 10~15, варианты «работает в 2 раза медленнее, зато разрабатывать на этом в 1.2 раза быстрее» больше не проканают, будет спрос на более быструю реализацию устоявшихся парадигм — и вот тут начнут оптимизировать.
За последние 10 лет производительность одного ядра и выросла примерно в 2 раза. Дальше производительность растёт только если программист осилил многопоточность.
Это на PC и конкретно у Интел.
В то время как на мобилках более чем на порядок.
А до предела однопоточной производительности ещё далеко.
UFO just landed and posted this here
Казалось бы, причём тут нулевые, когда речь шла про
За последние 10 лет

Кривая роста производительности у мобильных чипов сильно другая. Можно объяснить это эффектом «низкой базы», но A4 @ 800MHz десятого года это всё же процессор, который исправно выполнял все «смартфонные» функции.
Прогресс быстро шёл из-за того, что на мобильном рынке новая микроархитектура и новый техпроцесс стабильно появляются каждый год, в отличие от :)
UFO just landed and posted this here
Ну с многопоточностью сейчас гораздо легче, чем 10 лет назад. Даже в древней Дельфе появилось TParallel.For(, вместо ручного создания потоков.
Как будто проблема параллельных вычислений в самостоятельном создании потоков… Попробуйка распараллелить bsearch или aes-cbc. А если эти потоки ещё и приходится синхронизировать, то вообще начинается ад с дидлоками и рандом-багами.

Для bsearch если у Вас и 1е8 элементов, то это лишь ~26 операций будет в худшем случае, такое не надо параллелить. Если вы часто ищете — надо параллелить чтение(bsearch) и блокировать запись (вставка нового элемента). Если блокировки частые и мешают работе, можно как-то пул вставок делать и время от вермени сливать массивы.
С aes-cbc таже песня, алгоритм использует данные на предыдущем шаге, если у вас данные огромной длинны — то тут я не знаю как можно распараллелить, если у вас много поменьше — то это норм распределить на потоки.

Потому что парадигма «быстрый старт, потом оптимизация» — работает. Пока оно молодое, важны только возможности, если не совсем тормозное — делать упор на возможности это занять/отжать часть рынка. Выстрелило — есть популярность, начинаем оптимизировать. Тот же php постоянно заявлял «теперь мы быстрее от 10 до 100%» почти в каждой версии, и мельком видел тесты — 7 прилично быстрее чем 5. Ещё плюс — просто обновили версию, оттестировали и «на шару» получили экономию ресурсов.
Не выстрелило — не потратили много времени на работу, которая никуда не нужна. Плюс есть даже такой термин «преждевременная оптимизация». «преждевременная оптимизация — корень всех зол» — Дональд Кнут»
Другое дело спец вычисления, но их обычно и пишут сразу правильно и на всяких фортранах, лиспах… А если надо ещё быстрее — есть ASIC, например сети — те же циско часто раньше роутинг на асиках делали, получая очень быструю работу.
есть популярность, начинаем оптимизировать
Чего по факту не происходит. Исходят из того, что раз оно популярно то и оптимизировать незачем, лучше потратить деньги на новые фичи из за которых будет лагать ещё больше.
Эта цитата выдрана из контекста.
Полная цитата
Another important aspect of program quality is the efficiency with which the computer's resources are actually being used. I am sorry to say that many people nowadays are condemning program efficiency, telling us that it is in bad taste. The reason for this is that we are now experiencing a reaction from the time when efficiency was the only reputable criterion of goodness, and programmers in the past have tended to be so preoccupied with efficiency that they have produced needlessly complicated code; the result of this unnecessary complexity has been that net efficiency has gone down, due to difficulties of debugging and maintenance.

The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.

We shouldn't be penny wise and pound foolish, nor should we always think of efficiency in terms of so many percent gained or lost in total running time or space. When we buy a car, many of us are almost oblivious to a difference of $50 or $100 in its price, while we might make a special trip to a particular store in order to buy a 50 cent item for only 25 cents. My point is that there is a time and place for efficiency; I have discussed its proper role in my paper on structured programming, which appears in the current issue of Computing Surveys
Не стоит оптимизировать код вообще, если это в конечно счёте даст процент разницы. Но когда речь про изменение производительности в разы, то не оптимизировать крайне глупо!

Конечно нет, зачем это делать, если труд разрабов дороже железа до определенного момента. Как только это иначе и заметили — сразу начинают оптимизировать. Не знаю что у Вас по факту не происходит. Да, было бы приятно, если бы пользователи какой-то ОС прямо сейчас получили прирост скорости в 200%. Но если в случае майрософт это будет стоить пару сотен жизней человеко работы — то нет, спасибо. Все это люди которые чет вперед двигают, и фичи, и безопасность и тд. Если бизнес у которого полно денег будет и на эти задачи забирать людей которые чет умеет, то на остальные задачи ресурсов не хватит, и энтузиазма отказаться от денег. А ведь там есть область к медицине близкая, строительство и тд.
И что Вам даст это ускорение, вот один продукт взять — Винда ускорила, все классно, но через время опять фреймворки и пайтоны всякие/js уперлись в потолок по железу, и все. Если все будут оптимизацию в главный угол ставить — то это опять же куча человеко-часов непонятно на что.

По закону Мура каждые 18-24 месяцев количество транзисторов удваивается. До сих пор это происходило за счёт уменьшения их размеров.
Сейчас вводится техпроцесс на 5 нм для производства процессоров. В 2022 году будет 2 или 3 нм. В 2024 — 1. В 2026 — .5, в 2028 — .25 — и это предел, это размер атома кремния. Не получится сделать транзистор меньше атома.
Ну через многоядерность и параллелизацию что-то получится. Ну ещё площадь кристалла можно увеличить… но всё. В обозримое время мы упрёмся в ограничение производительности железа.
Будут ли к тому времени распространены квантовые компьютеры и как они будут программироваться — вопрос.
Давно уже упёрлись и сейчас все эти нанометры — банальный маркетинг.

Как видите, тут маркетологи, привязавшись к размерам ячейки памяти, обманули сами себя, и теперь вынуждены озвучивать цифру больше, чем могли бы. На самом деле, конечно, в условиях принципиального изменения структуры транзистора и ожидания пользователей услышать какую-то метрику, использование метрики, отражающей плотность упаковки, было, наверное, единственно верным решением, и маркетологи в конечном счете оказались правы, хоть это и приводит иногда к забавным ситуациям, когда одни и те же проектные нормы в разных компаниях называют по-разному. Например, читая новости о том, что TSMC уже запустила 7 нм, а Intel опять задерживает начало производства 10 нм, стоит помнить о том, что 7 нм TSMC и 10 нм Intel — это на самом деле одни и те же проектные нормы с точки зрения и плотности упаковки, и размеров отдельных транзисторов.

Проектные нормы в микроэлектронике: где на самом деле 7 нанометров в технологии 7 нм?
Понятно, что статически типизированные языки имеют фундаментальный бонус в скорости.
Но тот же python с развитием jit-компиляции (pypy, numbaJIT) и добавлением опциональной типизации — возможно, ещё долгое время можно будет выжимать из ускорения интерпритатора и JIT-компиляции. ( даже если не появится террагерцевых процессоров, квантовых компьютеров оптических вычислений и классический закон Мура встанет )
Понятно, что статически типизированные языки имеют фундаментальный бонус в скорости.


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

Как я себе вижу: компилятор может оптимизировать некоторые вещи, зная тип данных (
т.е. если функции на вход всегда приходит массив int'ов — оптимизировать проще, чем если это может быть int, float, строка, или вообще разные кастомные классы, для которых определено сложение друг с другом и деление на int. ( понятно, что такое можно написать и для статически типизированного языка, но если мы ищем среднее арифметическое массива интов [например, средняя зарплата], то у компилятора/интерпретатоора вообще не будет шансов из логики понять, что, например, строк там не будет. ( и и я не знаю динамически типизированных языков, где программист сможет это явно указать [python type hints — не влияют на оптимизацию, numba — статически типизирована, pypy — будет оптимизировать только при многократном вызове с интами])
)
Динамическая типизация всего лишь означает, что тип аргумента функции становится известен во время выполнения (например, прямо перед её запуском), а не заранее при обработке программы целиком. Соответственно, в этот момент можно компилировать функцию под конкретные типы. В случае, если типы аргументов действительно не меняются, оверхед по сравнению с компиляцией «заранее» будет нулевой.
Из языков ровно так работает, например, julia — причём явным образом типы указывать не требуется (но можно).
Numba в питоне тоже, конечно, никак не статически типизирована — до выполнения программы типы аргументов могут быть неизвестны.
def div(a,b):
    return a/b

В каком месте интерпретатор питона поймет что я передал ему строки, я так понимаю прям перед делением он выполнит эту проверку. В то время как статически типизированный язык просто интерпретирует куски памяти как int float или как мы их объявляли, ничего не будет проверять и поделит. Разве это не выигрышь времени выполения?
Нигде не поймёт — ну так я и не писал, что питон так делает (но см. в конце комментария про нумбу).
Julia, например, компилирует в такое:
> f(a, b) = a / b
> @code_native f(1.0, 2.0)  # float
# выдаёт ассемблерный код:
# vdivsd	%xmm1, %xmm0, %xmm0
# retq
> @code_native f(1, 2)  # int
# vcvtsi2sd	%rdi, %xmm0, %xmm0
# vcvtsi2sd	%rsi, %xmm1, %xmm1
# vdivsd	%xmm1, %xmm0, %xmm0
# retq
> @code_native f(big"1.0", 2.0)  # bigfloat - вызов соответствующего метода
# pushq	%rax
# movabsq	$"/", %rax
# callq	*%rax
# popq	%rcx
# retq
> f("abc", 1)  # строки делить нельзя
# MethodError: no method matching /(::String, ::Int64)

Эту функцию, конечно, можно использовать и внутри других функций
Заголовок спойлера
function g(x, b)
    res = 0.0
    for a in x
        res += f(a, b)
    end
    return res
end
> a = rand(100)
> @code_native g(a, 2.0)
#     movq    8(%rdi), %rax
#     testq   %rax, %rax
#     jle L74
#     movq    (%rdi), %rcx
#     vmovsd  (%rcx), %xmm1           # xmm1 = mem[0],zero
#     vdivsd  %xmm0, %xmm1, %xmm1
#     vxorpd  %xmm2, %xmm2, %xmm2
#     vaddsd  %xmm2, %xmm1, %xmm1
#     cmpq    $1, %rax
#     je  L69
#     movl    $1, %edx
#     nopw    (%rax,%rax)
# L48:
#     vmovsd  (%rcx,%rdx,8), %xmm2    # xmm2 = mem[0],zero
#     vdivsd  %xmm0, %xmm2, %xmm2
#     vaddsd  %xmm2, %xmm1, %xmm1
#     incq    %rdx
#     cmpq    %rax, %rdx
#     jb  L48
# L69:
#     vmovapd %xmm1, %xmm0
#     retq
# L74:
#     vxorps  %xmm1, %xmm1, %xmm1
#     vmovaps %xmm1, %xmm0
#     retq


Как видно, единственный оверхед здесь после запуска — один раз скомпилировать функцию для каждого требуемого типа аргументов. Затем выполнение идёт без замедлений относительно нативного кода.
При этом типизация динамическая, и можно составить такую функцию:
h(a) = f(rand(Bool) ? big"1.0" : 1.0, a)

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

В питоне нумба, как я писал, тоже по сути динамически типизированная — ведь статических типов в нём в принципе нет.
@numba.njit
def g(x, b):
    res = 0.
    for a in x:
        res += a / b
    return res
a1 = np.random.rand(100)
a2 = np.random.rand(100).astype(int)
g(a1 if np.random.rand() > 0.5 else a2, 2.0)

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

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

Затем выполнение идёт без замедлений относительно нативного кода.

Доказательства?
@code_native f(1, 2) # int
vcvtsi2sd %rdi, %xmm0, %xmm0
# vcvtsi2sd %rsi, %xmm1, %xmm1
# vdivsd %xmm1, %xmm0, %xmm0
# retq

Ага, «инт». (╯°□°)╯︵ ┻━┻
По вашим примерам ничего не видно, т.к. не показан код, который вызывает эти функции

Весь код показан — просто открываете REPL джулии и вводите ровно то, что в моём комментарии, те строки которые не с # начинаются. То, что с # в начале — это будет вывод. Можно и в скрипт запихать конечно, только явным образом print'ы проставить.
Больше кода никакого и нет, если конечно вы не имеете в виду реализацию самого компилятора или что-то подобное.
не показан код, который вызывает эти функции

Итак, вызывающий код — это просто f(1, 2), g(a, 2.0) и т.п.

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

А какой требуемый тип?

Может я не очень вас понял, но требуемый тип — это просто тип, с которым нужно скомпилировать функцию. Есть вызов f(1, 1) — компилируем f(::Int, ::Int); есть f(1.0, 1.0) — это f(::Float, ::Float), и т.д. Если с такими типами уже компилировали — ничего не делаем, просто вызываем (или инлайним) имеющуюся.

Ага, «инт»

Да, возможно я не уточнил, т.к. считал очевидным — какой тип имеют литералы. 1 и 2 — типа Int64, поэтому f(1, 2) вызывает f(::Int, ::Int). 1.0, 2.0 — это Float64.

Затем выполнение идёт без замедлений относительно нативного кода.

Доказательства?

Если брать приведённый мой пример функции f и её вызова в g — то там же приведён ассемблерный код, который будет выполняться при дальнейших вызовах с теми типами. При выполнении этого кода уже не важно, когда он появился — заранее или во время выполнения — скорость будет такая же. С чего вообще по-другому может быть?

Например, предложенный в моём предыдущем комментарии вызов g(a, 2.0) у меня на лаптопе выполняется за ~70 ns. Сравнивать с C/C++ лениво, но для последовательных делений и сложений по 100 раз время вполне соответствует ожидаемому от нативного кода.
При выполнении этого кода уже не важно, когда он появился — заранее или во время выполнения — скорость будет такая же. С чего вообще по-другому может быть?
Даже ели допустить, что Julia в runtime'е выполняет настолько качественную оптимизацию насколько возможно (что вряд ли, так как это занимает время) — инлайнинг, к примеру, в такой модели совершенно неприменим. Да и само переключение компиляция/выполнение бесплатно не проходит.
инлайнинг, к примеру, в такой модели совершенно неприменим

Не знаю, откуда такое мнение. Ведь прямо в комментарии выше, где я привожу пример выдаваемого ассемблерного кода, показан инлайнинг! А именно, функция f вставлена в g — никакого дополнительного вызова не происходит.

Даже ели допустить, что Julia в runtime'е выполняет настолько качественную оптимизацию насколько возможно (что вряд ли, так как это занимает время)

Да и само переключение компиляция/выполнение бесплатно не проходит.

Не вижу никакой проблемы проводить качественную оптимизацию во время выполнения программы, перед первым запуском каждой функции с новыми типами аргументов. Как я и писал, эта компиляция — единственный оверхед во время работы, но он случается только один раз на каждую комбинацию <функция, типы аргументов>.
Не знаю, откуда такое мнение.
Ну допустим Вы наткнулись на вызов функции и захотели его заинлайнить — как Вы это сделаете, если код функции, в которую нужно инлайнить, уже готов (это ведь он выполняется сейчас)? Единственный способ — вставить код с помощью memcpy, но уж лучше тогда не-inline вызов использовать.
Ага, нашел Ваш пример. ОК, есть инлайнинг, но видимо тогда все дерево вызовов скомпилировано за раз, а не по одной функции, как Вы говорите. Ассемблер, кстати, странновато выглядит.
Не вижу никакой проблемы проводить качественную оптимизацию во время выполнения программы
Дело в том, что качественная оптимизация использует данные обо всей программе, а не об одной конкретной функции. Например, если бы в Вашем примере было целочисленное деление — хороший оптимизатор бы заметил, что второй параметр всегда константный, и заменил бы его на умножение на константу. А компиляция по одной функции такого не сделает, откуда ей об этом знать?
Как я и писал, эта компиляция — единственный оверхед во время работы
Ага, а как на счет кэша скомпилированных функций? Перед каждым вызовом будьте добры сделать лукап, ну и апдейт кэша после компиляции, если вхождение не было найдено.
Ну допустим Вы наткнулись на вызов функции и захотели его заинлайнить — как Вы это сделаете, если код функции, в которую нужно инлайнить, уже готов

Как именно это технически реализовано — не разбирался и не знаю, могу только предполагать. Видимо, когда вызывается функция с конкретными типами аргументов, проводится некий анализ и вызываемых из неё функций — если они «простые», то инлайнятся.

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

второй параметр всегда константный, и заменил бы его на умножение на константу

Опять же, детали реализации я не знаю, но constant propagation в джулии давно завезли. Весьма вероятно, что он менее полный по сравнению с условным Си, просто из-за возраста языка. Но фундаментальных ограничений нет, во многих случаях он уже работает.

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

Не понял, зачем лукап перед каждым вызовом? Когда типы выводятся компилятором, этого точно не происходит; если типы невозможно вывести — ставится «лукап», либо из нескольких вариантов, либо если вообще ничего неизвестно — полноценный динамический.
Например, когда есть два варианта:
> f(a, b) = a * b
> h(a) = f(rand(Bool) ? 1 : 1.0, a)
> h(1)  # возвращает либо 1::Int, либо 1.0::Float
> @benchmark h(1)  # показывает, что h(1) занимает 5-8 ns
> @code_native debuginfo=:none h(1)
# под спойлером

Заголовок спойлера
Видно и целочисленное imulq, и дробное vmulsd. Более детально я в ассемблере не шарю :)

pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movabsq $rand, %rax
callq *%rax
movabsq $4607182418800017408, %rdx # imm = 0x3FF0000000000000
movl $1, %ecx
testb $1, %al
cmoveq %rdx, %rcx
jne L70
vcvtsi2sd %rbx, %xmm0, %xmm0
vmovq %rcx, %xmm1
vmulsd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, (%r14)
movb $1, %dl
xorl %eax, %eax
jmp L81
L70:
imulq %rbx, %rcx
movq %rcx, (%r14)
movb $2, %dl
xorl %eax, %eax
L81:
addq $8, %rsp
popq %rbx
popq %r14



Более полезный пример:
# если дали nothing - вернуть ноль, иначе умножить на 2
> f(x) = 2*x
> f(::Nothing) = 0

# хотим суммировать f(x[1]) + f(x[2]) + ...
> g(x) = sum(f, x)

# массив int'ов:
> a = rand(Int, 1000)
> @benchmark g(a)
# 80-90 ns

# массив int'ов и nothing'ов вперемешку:
> a = [rand(Bool) ? rand(Int) : nothing for _ in 1:1000]
> @benchmark g(a)
# 200-220 ns

В общем, даже в этой ситуации, где типы принципиально нельзя вывести статически (и есть лукап во время выполнения), получился весьма эффективный код. Даже simd используется, судя по времени.
Ладно, кажется я понял в чем проблема — в терминологии. Правильно ли я понял, Вы под вызовом функции подразумеваете команду вроде "> @benchmark g(a)"? Ну вот я это воспринимаю как запуск программы. А вот внутри себя она уже вызывает функции — это инструкции call или заинлайненный код других функций. Так вот я утверждаю, что каждая такая программа перед запуском полностью компилируется (включая все то, что она вызывает). Согласны с таким образом сформулированной позицией?
Этот подход эффективен — если Вам нужно запустить одну такую команду-программу. Но, опять же, есть аналогичная проблема — компилятор вынужден анализировать команды по одной, не видя общей картины. Например:
> f(x) = x
> g(x) = sum(f, x)
> a = [1 for _ in 1:1000]
> @benchmark g(a)
Если этот код компилируется по одной команде — будет цикл с суммированием. А если весь сразу — будет просто «return 1000».
Так вот я утверждаю, что каждая такая программа перед запуском полностью компилируется (включая все то, что она вызывает). Согласны с таким образом сформулированной позицией?

По-моему это принципиально невозможно сделать. Например:
> g() = eval(Meta.parse(readline()))
# вызываем g(), набираем в консоли код - он исполняется

# или

> g(x) = some_function(deserialize(x))
# вызываем g("file_name"), из этого файла десериализуется объект, на нём вызывается some_function

# или даже так

> g() = eval(Meta.parse(randstring(Char.(30:128), 123)))
# вызывать g()
# обычно будет ошибка,
# но возможно иногда случайно получится валидный код

Во всех трёх случаях при вызове функции g() нельзя определить, какие ещё функции будут вызваны. Это можно сделать только потом, когда часть кода g() будет выполнена.
Если этот код компилируется по одной команде — будет цикл с суммированием. А если весь сразу — будет просто «return 1000».

А для какого языка компилятор сможет сделать "return 1000", если a имеет ссылочный тип?


Если a будет иммутабельного типа и помечена как константа, то всё свернётся (но это не точно). Например, с пакетом StaticArray, добавляющим иммутабельные массивы фиксированного размера:


julia> f(x) = x
julia> g(x) = sum(f, x)
julia> const a = @SVector [1 for _ in 1:1000]
julia> @code_native (function () g(a) end)()
    .text
; ┌ @ REPL[8]:1 within `#10'
    movl    $1000, %eax             # imm = 0x3E8
    retq
    nopw    %cs:(%rax,%rax)
; └

(если смотреть код для g(a), то покажет код для g только в предположении, что аргумент — статический массив, не подставляя конкретное содержимое, поэтому в последней команде вызов обёрнут в функцию).

Весь код показан — просто открываете REPL и вводите ровно то, что в моём комментарии
Ещё раз. У вас не показан код который вызывает оверхед. И так понятно, что leaf-функции будут откомпилированы в нативный код. Смотреть на них не интересно.

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

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

Т.е. рантайм затраты на лукап и компиляцию функции вы не считаете оверхедом?
*facepalm*

Вызвать функцию в 5 строк из REPL и выполнять некий софт со 100 мегабайт кода это несколько разные вещи.

Да, возможно я не уточнил, т.к. считал очевидным — какой тип имеют литералы. 1 и 2 — типа Int64, поэтому f(1, 2) вызывает f(::Int, ::Int).


Языки такого плана обычно не умеют нормально работать с int.
Ваша функция с int не выполняет целочисленное деление.
Она переводит int в double, а потом делит даблы.

Например, предложенный в моём предыдущем комментарии вызов g(a, 2.0) у меня на лаптопе выполняется за ~70 ns.


Так же из repl дёрнули? Так он компильнулся / проинлайнился, оверхед вызова скрыт. Это не показывает ничего, кроме наличия jit — компилятора.
К тому же про 70нс я очень сильно сомневаюсь.
70 нс это латентность одного обращения к памяти.

Давайте посмотрим на инструкцию VDIVSD (на 4GHz Skylake)
:VDIVSD xmm, xmm, xmm L: 3.49ns= 14.0c T: 1.00ns= 4.00c
В цикле 100 итераций, но div не в цепочке зависимости, поэтому имеем время их исполнения не 14*100, а 4*100 тактов == 100 нс, если компилятор не векторизировал цикл (буду приятно удивлён, если векторизировал).
Ваша функция с int не выполняет целочисленное деление.
Она переводит int в double, а потом делит даблы.
Вроде бы у Julia такая семантика деления, целочисленное там другим значком.
docs.julialang.org/en/v1/manual/mathematical-operations
Оверхед будет в программе, которая вызывает вашу функцию, если функция не проинлайнена.

Да никакого оверхеда не будет, откуда у вас это мнение? Не заинлайнена функция — будет её вызов, такой же как в условном Си. Попробуйте сами, если не верите — надо что-нибудь поверх моих функций из примера накрутить чтобы компилятор не вставлял их по месту.
Конечно, если типы нельзя вывести, будет их проверка во время выполнения и после компиляции (см. функцию h из примера) — но от этого никуда не деться, независимо от языка и «статичности» компиляции. И в большинстве случаев оверхед этой проверки в жулии весьма небольшой.

Т.е. рантайм затраты на лукап и компиляцию функции вы не считаете оверхедом?

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

Языки такого плана обычно не умеют нормально работать с int.

Какого «такого» плана? Как «нормально»? Делить нацело можно, делить по-обычному тоже можно — просто это разные операторы.
Ваша функция с int не выполняет целочисленное деление.
Она переводит int в double, а потом делит даблы.

Конечно, если я в функции пишу "/" то я и ожидаю деление — без округления нацело, если вдруг в эту функцию передали инты. Нужно округлённое деление — так и пишите в коде, будет вам (стандартное хардверное) деление нацело.

Так же из repl дёрнули? Так он компильнулся / проинлайнился, оверхед вызова скрыт. Это не показывает ничего, кроме наличия jit — компилятора.

Поведение в repl и в коде из файлов в аспекте скорости и подхода к компиляции абсолютно никак не отличается.

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

При бенчмаркинге функция запускается много раз, так что всё в кэше находится. Разумеется, никак нельзя достичь 70 нс если отсчитывать время от запуска программы до вывода результата на экран.

В цикле 100 итераций, но div не в цепочке зависимости, поэтому имеем время их исполнения не 14*100, а 4*100 тактов == 100 нс,

Вполне возможно, что я действительно куда-то не туда посмотрел в прошлый раз. Сейчас перепроверил — выходит 100-110 ns.

если компилятор не векторизировал цикл (буду приятно удивлён, если векторизировал).

Вроде бы, судя по командам, цикл не векторизирован. Для векторизации нужно перед словом for добавить simd — тогда время работы сокращается раза в 2 у меня.
На питоне это всё тоже можно было-бы написать довольно быстро (хотя-бы попробовать), с помощью пакетов Numpy + Numba
Это скользкая дорожка
В таком случае можно говорить что и print это не питон
UFO just landed and posted this here
Так весь Питон — не Питон. В стандартной реализации — это Си.
Чтобы писать на Python «правильно», надо на нём писать общую логику, а всё, что хоть как-то требовательно к производительности, засовывать в модули. Которые на Си, который уже совсем не Python. И да, NumPy именно так и сделан.
Думаю что в будущем, когда остановится развитие ПО backend и desktop приложения будут писать на языках типа c++ и rust.

Не уверен. Оптимизации из статьи начиная с четвертой не очень то и зависят от языка программирования. Сборщик мусора тут тоже мимо — на весь тест три объекта.
Я бы поставил на языки с нормальный типизацией, которые будут давать возможность нормально задавать на уровне типов подобные оптимизации. Ну или для начала удобные библиотеки для работы со стандартными оптимизациями.
UFO just landed and posted this here

И по прежнему 80% будет уходить на ожидание, диска ли, сети ли… Но можно ждать быстрее!

UFO just landed and posted this here
Собственно, оптимизация энергопотребления в этом цикле и позволила процессорам прийти в мобильный сегмент.
Диски понемногу ускоряются, канал тоже в целом становится шире, так что самым узким горлышком для веба останется неторопливый сетевой протокол. И видимо, это следующее место в очереди на оптимизацию)

Не уверен. Все приложения всё ещё используют БД и там как упирались в диск, та и упираемся. С latency пока не сильно хорошо.

PCI-E хранилище в помощь. Может даже рейды
на серверах. а у пользователей? код вэбом не ограничивается.
m.2 хранилища относительно дешёвые тоже есть, и при этом шустрые

Попытка использовать samsung 970 под бд привела к его смерти за 2 месяца. Сначала тоже казалось, что отличное решение и под ноут подходит. Сейчас у меня хорошего решения нет. Да и по цене я не назвал бы это массовым.

2 месяца это что-то странное, похоже на брак.
У меня 2 штуки SSD Samsung работают почти непрерывно 6 лет — один система, другой рабочие файлы. Так вот смарт показывает оставшийся ресурс 91 и 99% соответственно.

Я был немилосерден. У меня циклы разработки такие, что записываются по 300-700gb и стирается и по-новой раз в пару-тройку дней.

Ну грубо можно принять 200 ГБ/день. За два месяца без выходных получится 12 ТБ — это на порядок меньше даже заявленного ресурса. А реальный, согласно тестам, должен быть больше ещё примерно на порядок. То есть ваш диск отработал ~1% того, что должен был.

Странно, потому-что у меня с хардами прямо противоположная ситуация. Если использовать под систему и на нём-же проводить всякие сборочки: начинал дохнуть где-то через полгода-год. С ssd ситуация противоположная: 2 года, 500 гб обьём (CT500P1SSD8), используется в качестве системного диска и под проекты тоже (брался из-за хорошего показателя 4k random write). 24.6 терабайт записаных за этот период, полёт нормальный (drive remaining life рапортует 90%), нареканий ноль.

Странно, потому-что у меня с хардами прямо противоположная ситуация. Если использовать под систему и на нём-же проводить всякие сборочки: начинал дохнуть где-то через полгода-год. С ssd ситуация противоположная: 2 года, 500 гб обьём (CT500P1SSD8), используется в качестве системного диска и под проекты тоже (брался из-за хорошего показателя 4k random write). 24.6 терабайт записаных за этот период, полёт нормальный (drive remaining life рапортует 90%), нареканий ноль.


Ну а у меня за последние 10 лет сдохло 20% SSD и 5% HDD.
Что за ssd-хи хоть?

Они померли и кто их уже помнит.
Хорошие модели. Не дешёвые. Я хреновых не покупаю.
Там где важна скорость — все базы данных давно крутятся на SSD, in_memory для кеширования тоже в помощь. Понятно, что это дороже — но варианты есть. У меня сейчас на проекте в стате по нгинксу — 99-ый квантиль укладывается в 40ms на апи(а на части эндпойнтов и в 20ms) — при том что там идёт работа с тремя разными базами данных, две in_memory, одна обычная. А главная страница — ~2.4 секунды до полной загрузки(меньше секунды до отображения интерфейса), 2mb данных, под сотню http запросов — стили, скрипты, картинки, и основное время в таймингах — ttfb.

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

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

Все приложения всё ещё используют БД и там как упирались в диск, та и упираемся

Что, прямо все-все приложения на свете? :)
В кровавом энтепрайзе работают не только лишь все.(с)
У меня вот ни одна задача не упирается в диск.
Когда проект в десятки мегабайт кода собирается на 16 ядрах, SSD загружен на 0-1%.
А вообщем то решают эту задачу.
Просто обычно в варианте «у нас спутниковый канал а значит пинг в полсекунды и полоса узкая а нам надо работать».
Как в тупом варианте для обычных пользователей (которым http нужен(тогда еще https был редкий) — Globax/TelliNet (спецпрокся сразу запрашивает кроме страницы еще и картинки) так и серьезные оптимизации протоколов вроде SMB чтобы снизить количество запросов + кэшировать информацию локально и передавать дельты. Это например продукты от Riverbed делают.

В HTTP/2 есть попытки оптимизировать по минимуму (например — то что не надо каждый раз соединение устанавливать и гонять TCP и TLS рукопожатия)

В HTTP/2 есть попытки оптимизировать по минимуму (например — то что не надо каждый раз соединение устанавливать и гонять TCP и TLS рукопожатия)

Как ни странно, этого не приходится делать даже в HTTP/1.1, если использовать заголовок «Connection: keep-alive». Причём, это используется везде, даже в библиотеках вроде requests для Python и cURL для PHP.
UFO just landed and posted this here
Как в тупом варианте для обычных пользователей (которым http нужен(тогда еще https был редкий) — Globax/TelliNet (спецпрокся сразу запрашивает кроме страницы еще и картинки)


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

Ох… Прямо в сердце… Трудно сделать базу шустрой на стороне клиента. А надо.

Полно задач, где на производительность вообще наплевать. Отчёт посчитается сегодня — отлично, послезавтра — тоже сойдёт.

только в бенчмарках там такая разница что вместо того чтобы ждать отчёт пару минут, придётся ждать десятилетие )))

Робин Мартин предполагает, что хороший способ приступить к решению проблемы — разделить библиотеки. Вместо того, чтобы создавать одну большую библиотеку, которая делает всё возможное, просто создать много библиотек.

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

Это как? Если вместо одной большой библиотеки будет много маленьких, каким образом я уменьшу количество зависимостей?


Разве это не тот путь, которым пошли с npm.js, и который в итоге приводит к 13000 зависимостей?

Это как? Если вместо одной большой библиотеки будет много маленьких, каким образом я уменьшу количество зависимостей?

Большая библиотека А может иметь компоненты b, c, d с зависимостями E,F,G соответственно. То есть библиотека A зависит от библиотек E, F, G. Разделяя библиотеку на библиотеки Ab, Ac, Ad (с зависимостями E,F,G соответственно), мы даём возможность пользователю подключить только библиотеку Ab c зависимостью E (если ему не нужны компоненты c, d), и не тянуть зависимости F, G ненужных компонентов.


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

Это именно то, к чему пришел npm. В котором «меньшими порциями» подключить себе 13000 зависимостей — сейчас довольно просто.

Это связано со сложностью ПО. Если есть 13000 различных функций (или связанных групп функций), число библиотек будет такого же порядка.

число библиотек будет такого же порядка

Как по мне, это проблема. В общем случае, я бы предпочел одну большую библиотеку + tree shaking, чем 10 маленьких:


  • больше вероятность, что она написана в одном стиле;
  • не возникнет конфликтов между версиями, когда библиотека A требует библиотеку C v1, а библиотека B требует библиотеку C v2;
  • меньше вероятность дублирования кода, поскольку компоненты одной библиотеки знают о существовании друг друга;
  • проще обновить одну библиотеку на новую версию, чем 10;
  • компоненты одной библиотеки будут совместимы между собой;
  • и т.д.

Согласен, но, на мой взгляд, проблема библиотек не только и не столько в том, что в них содержится "лишний" код (кстати, tree shaking всё-равно не сможет удалить абсолютно весь лишний код), сколько в том, что несколько последних поколений разработчиков обучены иначе думать — они ищут и подключают библиотеки на каждый чих, даже там, где можно было решить проблему написав десяток строк кода ручками.

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

Это распространённое заблуждение:


  • Этот десяток строк нужно протестировать ровно так же, как и любой другой десяток строк нашего кода — никакой особой разницы тут нет.
  • Насколько протестирован аналог этих строк в библиотеке — обычно никто не знает, и при выборе библиотеки на это не смотрит.
  • Поиск подходящих библиотек и выбор из нескольких альтернатив занимает время, нередко превышающее время на написание и тестирование этих 10 строк.
  • Добавление дополнительной зависимости в проект создаёт дополнительные риски и увеличивает стоимость поддержки проекта само по себе (которые принято игнорировать, но если прятаться под одеялом то монстр всё-равно никуда не исчезнет) — лицензии, зависимость от стороннего вендора, куча лишнего кода с потенциальными уязвимостями и т.д. (подробнее в https://habr.com/ru/post/443620/). Но если их не игнорировать, то стоимость поддержки и тестирования своих 10 строк почти всегда окажется значительно ниже стоимости поддержки дополнительной зависимости.

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

Я с вами в этом и не спорю, на мой взгляд всегда нужно находить золотую середину. Глупо подтягивать библиотеку для проверки числа на чётность, но ещё более дурацкая идея — писать свой ORM, например. И да, у меня в проекте самописный фрэймворк с самописным ORM, в котором я периодически отлавливаю новые ошибки и переписываю часть функционала) Для увеличения опыта — полезно, но будь у меня воля выбирать — я бы лучше подтянул готовую библиотеку)
Вы мой товарищ по несчастью, сейчас тоже мучаюсь на проекте с кучей велосипедов, в том числе с самописным ORM, к сожалению выпилить этот кошмар из проекта не представляется возможным, по трудозатратам это будет сложнее чем просто переписать все заново.

Не, то что вы описали, это про "в используемых библиотеках тоже будет меньше своих зависимостей" – тут я не спорю. Транзитивных зависимостей может быть меньше. Прямых зависимостей никак не может стать меньше.

Прямые зависимости — они явные. Транзитивные зависимости — неявны, этим они и страшны.

И? Какое отношение это имеет к моему изначальному вопросу?

Транзитивные зависимости вызывают большее беспокойство, чем прямые (прямые подключаются явно, а не ВНЕЗАПНО, они все видны). Описанный способ борется с лишними транзитивными зависимостями.

Описанный способ приведет (и приводит) к аду с управлением зависимостями, когда библиотека A зависит от библиотеки C v1, а библиотека B зависит от библиотеки C v2. А я про эту библиотеку C вообще ничего не знаю, и она мне нафиг не сдалась бы. И чем больше таких микро-библиотек, тем больше вероятность конфликтов.


Но это все лирика, повторюсь, к моему изначальному вопросу это не имеет никакого отношения.

к моему изначальному вопросу это не имеет никакого отношения.

По-моему, я описал механизм, как эта идея работает. Это отвечает на вопрос "как?"

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


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


А вы мне в этой ветке говорите про то, что транзитивные зависимости вызывают большее беспокойство. Отсюда и вопрос: "И что?"

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

Это не так.

Мне кажется, идеальными были бы библиотеки, которые вообще не тянут зависимостей. Пусть там будет на пять строк больше, но когда библиотека для проверки чётности числа тянет за собой библиотеку которая проверяет нечётность числа — это адок.
Ваш пример немного не к месту. То, что вы описали, это то, что мы имеем уже сейчас и без разбиения библиотек на более мелкие.

В случае с примером, описанным Akon32, библиотека A разбитая на библиотеки Ab, Ac и Ad — это одна библиотека. Все зависимости в данном случае должны быть едиными и иметь общую версию. Кроме того, версия библиотек Ab, Ac и Ad тоже должна быть общей, даже при выпуске новой версии где изменения коснулись только одной части. Если придерживаться этих правил проблем с зависимостями точно не прибавится.

При этом транзитивных зависимостей будет меньше только в теории. На практике же, если библиотека A тоже пошла этим путем, то Ab будет зависеть не от E, а от Ex, Ey, Ez. Каждая из которых, в свою очередь, будет зависеть еще от 5 микро-библиотек.


Получается, что вместо зависимости A –> E, F, G, у меня будет Ab, Ac –> Ex, Ey, Ez, Fp, Fq -> *

На практике же, если библиотека A тоже пошла этим путем, то Ab будет зависеть не от E, а от Ex, Ey, Ez.

Если E пошла тем же путём, возможно, что в зависимости Ab можно прописать только Ex, а не все Ex, Ey, Ez, поэтому ни Ey и Ez, ни их зависимости грузиться не будут; и т.д.
На практике может быть и так, что нужны все Ex, Ey, Ez, и тогда преимущества такого способа нет.

Вот на практике и получается 13000 зависимостей.

Скорее это комбинация отрицательных моментов первого и второго подхода, когда низкоуровневые библиотеки мелкие, а чем выше, тем больше «функциональности». В итоге и подключено лишнего, и количество зашкаливающее.

Теоретически да, практически — далеко не всегда.


  • Во-первых, поскольку нет единообразия, и учитывая, что для решения одной задачи уже существуют как правило несколько альтернатив на выбор, многие транзитивные модули будут зависеть от разных библиотек, предоставляющих один и тот же функционал.
  • Во вторых, транзитивные зависимости могут тащить разные версии одной библиотеки, и привести все это к общему знаменателю — серьезная проблема. Например производители дистрибутивов Linux или метафреймворков типа Spring Boot как раз решают эту проблему, унифицируя в каждой версии платформы большинство зависимостей.

С другой стороны проблемы не в размере самих библиотек, а в том, что современные технологии неприспособлены для автоматического dead code elimination. В сях все было просто: неважно сколько библиотек ты подключил — линкер урежет все, что статически недосягаемо из main(), делая очень компактный бандл. В других языках как Java, Python, JS пришлось искусственно городить модульную систему и требовать от пользователя каждый раз въявную указывать компоненты, которые он будет использовать. Так что это по большей части шаг назад.

В сях все было просто: неважно сколько библиотек ты подключил — линкер урежет все, что статически недосягаемо из main(), делая очень компактный бандл. В других языках как Java, Python, JS пришлось искусственно городить модульную систему и требовать от пользователя каждый раз въявную указывать компоненты, которые он будет использовать. Так что это по большей части шаг назад.

Угу, угу. И каково там управлять зависимостями на C? И что делать, если у двух зависимостей общая транзитивная зависимость, но разных версий?

  • Во-первых, стек библиотек, поставляемый с платформой (версией ОС, SDK, etc), как правило всегда унифицирован транзитивно.
  • Во-вторых, есть требование, чтобы библиотеки с одной и той же major version были обратно совместимы. http://www.sourceware.org/autobook/autobook/autobook_61.html В этом случае можно просто слинковать более свежую библиотеку.
  • И в-третьих, в одном бандле можно использовать транзитивные библиотеки разных версий. Для этого линкер должен включить номер версии в таблицу символов.
    https://blog.habets.se/2012/05/Shared-libraries-diamond-problem.html
  • Во-первых, стек библиотек, поставляемый с платформой (версией ОС, SDK, etc), как правило всегда унифицирован транзитивно.

Но не все зависимости в этот стек входят.


  • Во-вторых, есть требование, чтобы библиотеки с одной и той же major version были обратно совместимы. http://www.sourceware.org/autobook/autobook/autobook_61.html В этом случае можно просто слинковать более свежую библиотеку.

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


  • И в-третьих, в одном бандле можно использовать транзитивные библиотеки разных версий. Для этого линкер должен включить номер версии в таблицу символов.
    https://blog.habets.se/2012/05/Shared-libraries-diamond-problem.html

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

это просто работает

Просто это работать не может. Если есть цепочка A-B-D1 и А-С-D2 и нужно объект из библиотеки D передавать между функциями из B и С. Как это сделать?


Если же библиотеки D1 и D2 не торчат наружу, то возможно конкретная реализация в Си немного тупая. Но в целом решение очевидное.

Просто это работать не может. Если есть цепочка A-B-D1 и А-С-D2 и нужно объект из библиотеки D передавать между функциями из B и С. Как это сделать?

Если вы не указали, чтобы B и C использовали одну и ту же версию — никак, у вас объект из библиотеки D разных версий, т. е. фактически разных библиотек.

Окей, это интересно (нет, серьёзно), но что делать с зависимостями, которые линкуются статически?

Я не разрабатываю на Си, но насколько я могу судить (да поправят меня знающие люди), нет большой разницы слинкована библиотека динамически или статически. Любое приложение можно слинковать обоими способами (чем пользуются всякие flatpack и snappy). В первом случае резольвинг идет в рантайме на этапе загрузки бандла, тогда как во втором — сразу на этапе линковки бандла. Правила резольвинга не должны отличаться.


Или просто в новой версии транзитивной зависимости добавили новую функцию, которая имеет то же имя, что и в библиотеке.

Когда говорят о транзитивных зависимостях, почему-то нигде не указывают тип транзитивности. Вне зависимости от языка программирования любая библиотека всегда состоит из двух частей: интерфейса (структуры, типы, сигнатуры функций) и имплементации (непосредственно код). Интерфейс библиотека экспортирует наружу, тогда как имплепентация — это внутреннее поведение библиотеки. Если транзитивная зависимость используется полностью в имплементативной части библиотеки, то нет никаких проблем иметь разные версии в разных зависимостях: различные платформы предоставляют свои средства "изоляции" (namespaces, dynamic linkers, classloaders, etc...).


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


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

Если транзитивная зависимость используется полностью в имплементативной части библиотеки, то нет никаких проблем иметь разные версии в разных зависимостях: различные платформы предоставляют свои средства "изоляции" (namespaces, dynamic linkers, classloaders, etc...).

Только не в C, там из средств изоляции только static для функций.

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

Тут таки сложнее. В Windows, например, статические библиотеки линкуются как внутрь основного бинарника, так и внутрь DLL (это долго относилось, а может, и сейчас, к CRT — C runtime library); если статическая библиотека это не импорт DLL, то каждая DLL получит свою копию этой статической, со своей версией и своими глобальными переменными. Поэтому лучше, например, malloc/free/new/delete делать переходниками на соответствующие функции user32, если нет жёстких причин делать иначе; если же рантаймы у двух DLL различаются, то возникает жёсткое правило что освобождать память должна та же DLL, что её аллоцировала.

В Unix, соответствующие уровни обычно сделаны в общей libc, а в общем случае подключается только одна библиотека (самая свежая) каждого типа, но и там можно при желании натворить хаков — статическая линковка внутрь SO, прямой dlopen на желаемую библиотеку, и прочая и прочая.

> Вне зависимости от языка программирования любая библиотека всегда состоит из двух частей: интерфейса (структуры, типы, сигнатуры функций) и имплементации (непосредственно код). Интерфейс библиотека экспортирует наружу, тогда как имплепентация — это внутреннее поведение библиотеки.

Теоретически — да. Практически же этот механизм приводит к тому, что ссылка двух DLL друг на друга по кольцу без явного резолвинга в коде уже ломает всё, и аналогично для .a (.lib).
Деление на интерфейс и реализацию в этой схеме совершенно нетипично, это не классовая иерархия.
Это в теории. В практике 99% разработчиков будут писать что-нибудь типа «include *», а то мучаться, выбирать нужные библиотеки… Сразу все включить и не мучаться ((

include * не значит что используется всё. компилятор может знать что используется а что нет. А вот какой то __import__(random_string()) в интерпретируемых языках это уже хуже.

… Вот поэтому нужно развивать инструменты, которые позволят вырезать ненужный мусор (aka стриппинг). Не актуально для плюсов, но зато будет актуально для всех скриптовых языков.
Это тот путь, который давным давно есть в perl.

"Нужно оптимизировать ПО" — весьма банальная идея.
Программы, в которых действительно нужна скорость, и так тщательно оптимизируются.
Но есть и такие программы (и их много), где не важно, 100 или 200 миллисекунд будет обрабатываться нажатие кнопки. А процесс оптимизации — это некоторые затраты.


Робин Мартин предполагает, что хороший способ приступить к решению проблемы — разделить библиотеки. Вместо того, чтобы создавать одну большую библиотеку, которая делает всё возможное, просто создать много библиотек.

В ряде случаев это, конечно, хорошая идея, но постоянная память сегодня практически ничего не стоит. Какая-нибудь SD карта размером с ноготь может хранить сотни гигабайт. Нет смысла беспокоиться, пока система не начнёт работать настолько плохо, что за неё станет стыдно (или пока конкуренты не прижмут). Если 100500МБ библиотек перестали влезать в SSD — определённо, надо что-то делать.
Ну и собственно разделение библиотек может быть хорошей идеей по ряду других причин, не связанных с объёмом исполняемого кода, например уменьшение вероятности некоторых конфликтов зависимостей.

Проблема в том, что у разработчиков ПО обычно топовые компьютеры с кучей памяти, быстрыми многоядерными процессорами и быстрыми дисками. И быстрый интернет. Особенно быстрый канал связи до своих серверов. У них всё работает быстро и без тормозов. А у пользователей разные компьютеры, в том числе старые и тормозные.
Если предложить разработчику поработать на старом нетбуке с процессором Atom и двумя гигами оперативки и подключить его через ADSL, то наверняка он сразу задумается об оптимизации своего софта. И не только своего.
UFO just landed and posted this here
Проблема в том, что стоимость разработки должна стать меньше, чем стоимость железа у разработчиков, а не у пользователей. Я собственно про то и написал — что как только стоимость железа станет такой, что разработчики вынуждены будут сидеть на устаревшем железе, тогда они и будут оптимизировать.

Проблемы пользователей разработчиков не волнуют. По крайней мере проблемы 10-20% пользователей с наиболее слабым железом. Они кассу не делают.
Это не правда. Если разработчики поставляют ПО, которое у пользователей (проблемы которых, якобы, программистов не волнуют) тормозит, пользователи уходят к другим поставщикам софта. Тогда к программистам приходит менеджмент и их начинают волновать другие проблемы.
К какому поставщику ушли пользователи винды, ютуба, или гугломейла? (вопрос риторический)

Благо, ютуб пока что ещё смотрится через mpv, а в гугломейле не отрезали классический HTML-вид, но это пока :-)

А другого софта нет? Я работаю в ЕРП и у нас такое случается — клиент может громко хлопнуть дверью. Просто тут каждый клиент стоит как сотня клиентов в виндовзе. А ютюб и гугломейл вообще бесплатные.
пользователи уходят к другим поставщикам софта


… с новым глюкодромом и тормозами. А от «другого» поставщика переходит кто-то к первому, лелея мрию что тут ему сделают красиво :)
UFO just landed and posted this here
Повторюсь: оптимизация начнется, когда стоимость разработки станет меньше стоимости железа.

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

Вот неистово плюсую.
В современном мире оптимизацией, как правило, начинают заниматься только тогда, когда этого уже ну никак нельзя избежать. Когда производительность оказывается абсолютно неприемлемой.
Это доведенный до крайности принцип «решать проблемы по мере их поступления».
UFO just landed and posted this here

А можно ликбез зачем линкеру столько памяти? Казалось бы ему надо примерно столько, сколько будет весить итоговый бинарник. Развен он строит какое то дерево зависимостей по ходу дела?

UFO just landed and posted this here
не у линкера не хватало памяти, а у самого получающегося бинаря — ОС не могла его загрузить, потому что слишком много туда было влинковано, и оно тоже выходило за какие-то пределы

Банальный виндовый exe (PE) не может быть больше 2ГБ. Лимиты ближе, чем кажутся. Я видел dll от nvidia размером в несколько сотен МБ.

UFO just landed and posted this here
Самые большие бинари — это самораспаковывающиеся архивы. А у игрушек обычно компактный движок в виде exe или dll и гигабайты ресурсов лежат рядом.
У игрушек — возможно. Потому что там этих ресурсов слишком много и они регулярно обновляются. А вот у «обычных» подвиндовых программ как раз исполняемые файлы, включая DLL, используются в качестве контейнеров для хранения ресурсов.
Если я правильно помню, как происходит работа с динамическими библиотеками, то в память загружается только инициализирующий код, а остальное подтягивается по мере необходимости. Ну и у виндовых исполняемых файлов, в том числе у DLL, зачастую, основной объём — ресурсы, которые в *nix-ах в исполняемых файлах не хранятся, а лежат «рядом» отдельными файлами картинок и прочего подобного.

То есть это вопрос не того, что непонятно чего накодировали, а использования DLL в качестве «коробочки» для хранения картинок и чего-то там ещё.
А конкуренция — это как раз про отзывы пользователей. Точнее, про то, что пользователям надоедает, что их отзывы сливаются в канализацию и они уходят к конкурентам. То есть это одно и то же, в общем-то, только на разных стадиях.

Извините, ваша теория разбивается об энергопотребление современного железа.
Людям нужно чтобы ноутбук держал 5-10 часов. У нас есть работающая, но тормозящая программа. Пользователи пользуются. Но как только конкурент сможет предоставить более энергоэффективный аналог, это станет решающим фактором для части пользователей.
На десктопе отличие в том что сейчас счет пошел на сотни ватт. Пользователи не будут ставить чиллер чтобы пользоваться ПО про которое пишите вы.

UFO just landed and posted this here

Могу привести пример — Скайп. Когда-то безальтернативное решение, и один из сейчас. Последние несколько лет в связи с деградацией производительности точно потерял часть рынка.


А как вы решите деньгами разряжающийся за 2 часа ноутбук на core i7 8 поколения?


можете показать выписку с донатами Mozilla (если Вы ей пользуетесь), Canonical (если пользуетесь Ubuntu), Eclipse Foundation (если пользуетесь Eclipse IDE)?

Давайте без выписки. Если вам интересно, поддерживал и поддерживаю свободное ПО как Ubuntu, phpmyadmin и прочие линуксы. Буквально несколько дней назад отправил 10$ Википедии.
Вы правы, я буду платить за быстрое ПО.

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

У Скайпа, если МС окончательно его не решили угрохать, есть до сих пор киллерфичи — полноценные десктопные клиенты на разные плафтормы, аудио и видео в режиме конференций, показ экрана, режим редактора кода вроде был.
Даже у более успешных конкурентов или чего-то нет или что-то неполноценное неудобное или что-то, что в Скайпе второй десяток лет, завозят вот только что.
Скайп — не самый лучший пример, пожалуй. Всё-таки то, что им продолжают пользоваться, связано с тем, что на него завязана клиентская база. То есть, если сейчас LibreOffice начнёт портиться, я переползу на другой офисный пакет и меня это не напряжёт. Но вот что мне делать с кучей потенциальных клиентов, которые особо жаждут менять Скайп на что-то ещё? То есть я бы и перешёл, но «клиент всегда прав». Платёжеспособный клиент, разумеется. Но чтобы добраться до стадии, когда начинаешь интересоваться платёжеспособностью, надо ещё с ним связаться. А это — Скайп. Да, есть Телеграм. За последнюю пару лет он стал достаточно популярным, чтобы начали запрашивать уже его, но Скайп всё равно остаётся где-то в топе, а мне приходится из-за него страдать, потому что кривой и падает.

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


Так же что Скайп, к сожалению, хороший пример. Пока 80% готовы мириться с плохой скоростью ПО, остальные 20% тоже будут. Скорость — не определяющий фактор.

Нет, как раз поэтому Скайп — неудачный пример: выбор делает не один человек, а сообщество пользователей. И если офисный пакет, браузер, почтовый агент я могу менять хоть три раза на дню и ни от кого этот выбор зависеть не будет, то со средствами общения с закрытыми протоколами всё сильно хуже, потому что они завязывают пользователя на сообщество, которое использует это средство связи. И да, пока Скайп не осточертее достаточно большому количеству пользователей, таким, как я, кто использует Скайп для связи с клиентами, никуда с него не деться. Потому что клиент хочет использовать Скайп, а мне приходится подстраиваться. Раньше это был ICQ, к которому я в какой-то момент с смог подключиться и удалил аккаунт, потому что уже несколько лет мне на него никто не писал. Через какое-то время, видимо, та же судьба постигнет и Скайп, а потом и Телеграм, у которого своих косяков хватает. Например, врождённый недостаток — регистрация по номеру телефона, то есть завязка безопасности на сторонний сервис, потенциально подконтрольный враждебным структурам. А уже есть дыра в безопасности размером с корабль.
UFO just landed and posted this here
Дискорд прекрасно работает без номера телефона. Более того, он позволяет использовать 2FA без привязки телефона, что особенно радует.
офисный пакет

Если файлы сложные — не можете. У ваших клиентов просто поедет всё, придётся вам потерпеть. Если файлы простые, то повезло.


браузер

Не можете. Движка осталось, фактически два, более одного раза не поменяете. Скины к хрому не в счёт, их вы правда можете менять.

деградация производительности скайпа ерунда по сравнению с отвратительной работой на мобильных. Показать что мне пришло сообщение с опозданием на несколько часов или не показать вовсе — вот что для меня полностью убивает его как мессенджер.
А вот это, как я понимаю, косяк служб Google (если Вы про него, а не про iOS) или чего-то на этом уровне, потому что уведомления не приходят не только в Скайп. Причём, на старом смартфоне с Android 5.1 всё работает на ура. Но да, на смартфоне он тормозной. По крайней мере, это сильно заметно, если смартфон не тягается по производительности с дэсктопом.
UFO just landed and posted this here
Ну вот из всего, что стоит у меня, адекватно пуши работают только у WhatsApp, который используется вынужденно, и у GMail, у которого до недавнего времени так же были с этим проблемы.

Скайпом перестали пользоваться не из-за деградации производительности, а из-за деградации качества самого приложения — глюки, реклама, убогий UX, И так далее.

А если, к примеру, я предложу Discord с показателем потребления /10, но за подписку 5$/месяц?
На самом деле, цены на freemium-софт сильно завышены, потому что каждый покупатель подписки платит за себя и того парня взвод других парней. Помню, несколько лет назад писали, что у Evenote платят только 4% пользователей. Может быть, сейчас иначе, но тем не менее.
Так вот если заставить платить всех без исключения, то 5 баксов в месяц могут легко и непринужденно превратиться в 5 баксов в год :)
UFO just landed and posted this here

Заставить? Какая классная идея, модная, современная.

Да нет, идея стара как мир. За колбасу, ботинки и такси платят все, а не некоторые.
UFO just landed and posted this here

Меня ещё ни разу не заставляли платить за колбасу. Хочу покупаю, хочу нет. Те же и с сервисом. Хочет человек — делает платный сервис, хочет — с премиум-подпиской. Но если он сделает платный, клиенты могут уйти на условно бесплатный, если захотят. Никакое "заставить платить" тут быть не может.

Никакое «заставить платить» тут быть не может.

Винда же (если без пиратства). Да, есть линуксы, но сидя на работе под линуксом, дома поставил винду, потому что даже в steam из всех игр что у меня куплены — в линь умеют процентов 10 от силы. Плюс под винду написана просто масса по, которого нет под линь, а аналоги… Вот чем заменить мс офис именно при серьёзном документообороте? openoffice, libreoffice — простые документы обычно норм, но сложные, со сложным форматированием, с режимом комментирования — ломаются в 90+% случаев. То нумерация уплывает, то страницы рвутся криво, то вёрстка уезжает и иногда это важно… Мы пытались использовать и линухи и *офисы, но по моему субъективному опыту — самым стабильным был ooo 2.2 (выпущенное году этак 2010, последний раз сравнивали году в 2015), а либра била доки даже те, которые в ооо 2.2 показывались как надо.
И это при том что режим правок например терялся полностью. Итог — внутри фирмы — ООо, всем кто общался с клиентами и вообще с миром — винда и мс офис.
Возможно, мак был бы решением, там вроде как есть и мс офис и ещё много софта, но он сам по себе дороже и это отдельная экосистема.
простые документы обычно норм, но сложные, со сложным форматированием, с режимом комментирования
Вот никогда не понимал, а зачем нужны «сложные» доковские документы. Либра рецензирование, формулы и ссылки вполне себе вывозит в 5 версии.
Вот никогда не понимал, а зачем нужны «сложные» доковские документы. Либра рецензирование, формулы и ссылки вполне себе вывозит в 5 версии.


Внутри себя вывозит.
При импорте-экспорте — съезжает форматирование.
У кого как :)

Не у кого, а у чего.
Зависит от самого документа.

Причем съезжает форматирование и у элементарных вещей типа «выставить счет в OpenOffice и открыть в Excel или наоборот».

А счет это такая простейшая форма:

image

Вы можете предположить, что съезжает картинка с печатью или подписью?

Нет, съезжают рамки и то что в рамках написано.
Сталкиваюсь довольно часто.
В смысле ширина ячейки в docx? Кстати, это скорее всего связано с тем, что по-разному в ОО и Офисе ставится якорь картинки, поэтому для портабельности я стараюсь по максимуму верстать таблицами с невидимыми границами.
это скорее всего связано с тем, что по-разному в ОО и Офисе ставится якорь картинки

Написано же — дело не картинке.
Нет, написано, что съёзжает не картинка. Якорь может сбивать позиционирование полей и границ других элементов. Я с этим сталкивался, когда документ из 2007 перекосило в 2003, долго рассуждал о неочевидности решения инвективной лексикой.
Нет, написано, что съёзжает не картинка. Якорь может сбивать позиционирование полей и границ других элементов. Я с этим сталкивался, когда документ из 2007 перекосило в 2003, долго рассуждал о неочевидности решения инвективной лексикой.


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

Ну ОК. Ровно такой файл, состоящий из надписей и рамок имеет нередко ровно такие же проблемы.
Без картинок.
docx или doc?

Новый, конечно же.
Тогда лажа, да. И тут не важно, кто неправильно реализует стандарт.
Да просто договор, где описаны пункты которые нужно сделать. В оригинале был пункт 10.20, стало 11.2 — из постоянно встречающегося.
Берём сложнее. ТЗ. То есть документ, с которым работают обе стороны. И тут история правок и «совместная работа» это жизненно важно. Да, сейчас берём тот же гугл докс и не знаем бед, но суть была именно в локальном редакторе.
Ну и всякие рамки ползут даже в простых доках, это да.
Бесплатные пользователи наполняют базу, они жизненно необходимы любому софту с социальным взаимодействием. Никто бы не пользовался дискордом, если бы в нём сидели только люди с платными аккаунтами. С ПО которое не зависит от базы пользователей, естественно, ситуация другая — но там зачастую и нет бесплатной модели, либо она урезана ровно настолько, чтобы показать пользователю фичи и подвести к покупке.
Отчасти эту проблему можно разрешить изменением культуры. Да, пользователи практически никогда не сравнивают производительность программ выбирая, чем будут пользоваться (но я вот например сравнивал), просто потому что на это нужно много сил.

Разница в производительности играла бы какую-нибудь роль, если бы была видна. Но почему-то в списках/обзорах программ для задачи X из потребления ресурсов в лучшем случае указывают размер apk.

Хотел бы я, чтобы обзоров с измерениями было больше.
UFO just landed and posted this here
Разработчики даже в рамках госрегулирования чисто своей отрасли ничего лоббировать не осилят (каждый в своей кастрюльке варится, пока зарплаты относительно высокие), а вы про изменение культуры потребления ПО в принципе.

Вот по крайней мере для России.
Есть госреестр отечественного по.
И если будут включены требования по скорости, хотя бы по скорости отклика и по памяти.
Разработчики вынуждены будут изменить по, для включения в данный реестр.
UFO just landed and posted this here
И если будут включены требования по скорости, хотя бы по скорости отклика и по памяти.
Разработчики вынуждены будут изменить по, для включения в данный реестр.

Какая "интересная" идея. Ресурсоёмкое ПО сразу вылетает из реестра. Остальные пишут костыли, чтобы удовлетворить формальным требованиям.
А когда железо подешевеет, ПО его не может использовать, потому что законодательно будет ограничено лимитом, аналогичным "640кБ". Развитие приостановится.


Имхо, вместо этого лучше пролоббировать "разработчики обязаны ходить строем". Это сократит время на перемещения и просто красиво (по мнению некоторых).

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

Тут есть много факторов, скорость удобство цена, но потребление батареи у меня один из ключевых. Особенно на телефоне, где каждый калькулятор норовит висеть в бэкграунде и сливать телеметрию все сутки на пролет. Зоопарк мессенджеров это вообще идиотизм. Скайп на компе включаю только если надо позвонить по видео и потом сразу выключаю.
Да блин я бы хоть сейчас задонатил бы на хабр если бы они наконец убрали поыиксиили тормознутые комментарии, и сделали бы полноценную мобильную версию.

Скайп на компе включаю только если надо позвонить по видео и потом сразу выключаю.

У вас какая-то эгоистично-односторонняя связь получается. А если кому-то другому надо позвонить вам с видео — что делать? Связываться с вами по другому каналу связи и нижайше просить вас включить скайп?
Ну и второй вопрос — если для вас решающим фактором является энергопотребление — зачем выключать скайп на десктопе?

Так происходит что о видео звонках договариваемся заранее, я же не в калл центре работаю. Речь про ноут.

UFO just landed and posted this here

Ну Ops и SRE не могут позволить себе такой роскоши как выключенный телефон )

UFO just landed and posted this here

Тоже так думаю. Идеальный пример Whatsapp и и Telegram. Первый вышел на рынке раньше и сейчас является монополистом практически, на фоне телеграмма, который уделывает его по всем параметрам, но большинство, как пользовалось whatapp, так и пользуется. Кроме тех людей, которые попробовали telegram конечно...

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

Это не так. Изначально WhatsApp был заменой SMS и ничего кроме сообщений не умел. И причём был платным.

Первый выпуск приложения относится к январю 2009 года. К апрелю 2012 года ежедневно при помощи WhatsApp пересылалось 2 миллиарда сообщений, более 10 миллиардов в августе 2012 года, более 27 млрд в июне 2013 и более 50 млрд сообщений на март 2015. В феврале 2018 около 1 млрд человек отправляли через WhatsApp 55 млрд сообщений в день.
По мнению, опубликованному в газете Financial Times, приложение WhatsApp сделало с SMS то же, что сделала программа Skype с международными телефонными звонками.

В феврале 2014 года CEO WhatsApp намекнул, что к лету планируется добавить функциональность VoIP-звонков между пользователями, и в конце марта 2015 года эта функция была реализована на платформе Android. В апреле 2015 года звонки появились на платформе iOS. В июне 2015 года функция стала доступна владельцам Windows Phone.

19 февраля 2014 года компания Facebook Inc. объявила о приобретении WhatsApp за 19 млрд долларов.
WhatsApp стал бесплатным с 18 января 2016 года. Ранее за подписку на использование сервиса взималась плата в размере около 1 доллара США каждый год, начиная со второго года использования, либо (для платформ Apple), однократный платёж при покупке приложения

К 2015 году WhatsApp стал самым популярным приложением для обмена сообщениями в мире, и по состоянию на февраль 2020 года в нем насчитывалось более 2 миллиардов пользователей. WhatsApp стал основным средством электронной связи во многих странах и регионах, включая Латинскую Америку, Индийский субконтинент и большую часть Европы и Африки.


Пользовался и телеграмом и вотсапом на смартфоне, не вижу, чем именно телеграм лучше.
UFO just landed and posted this here

Ага т.е. он стал бесплатен после покупки фейсбук. Что они от этого выиграли? Куда идет телеметрия и какая, является ли проект дотационным?) С телегой тот же вопрос. Или телега ещё на стадии пилим деньги инвесторов?

UFO just landed and posted this here
Повторюсь: оптимизация начнется, когда стоимость разработки станет меньше стоимости железа.

Наверное даже так: оптимизация начнется, когда стоимость разработки и поддержки станет меньше дополнительной стоимости/задержек которые пользователи готовы заплатить за более оптимальный продукт, с учетом конкурентных продуктов.
В игровой индустрии очень хорошо все видно. Какие бы мощные компы не были у разрабов, если писать неоптимально, то просто некому будет играть.
Проблемы пользователей разработчиков не волнуют. По крайней мере проблемы 10-20% пользователей с наиболее слабым железом. Они кассу не делают.

Волнуют. В указанных в ТЗ рамках.
А если там например указано (или НЕ указано но сказано неявно) что телефоны с дисплеем меньше N" не поддерживаем — пользователю с таким — не повезло. Если по ТЗ надо при старте приложения показать пользователю продукты которые ну очень будут ему полезны — это и будет сделано.
Если надо сделать приложение «красивее» (пусть даже это значит на определенный период в приложении будет и новый и старый код ) — ну вы поняли.
Если надо «по соображениям безопасности» дергать 3rd party либу которая не только собирает данные все какие может но еще и спамит в logcat при этом (серьезно тормозя при этом работу) — ну значит максимум разработчики сделают возможность собирать версию где эта либа просто не инициализируется. Для себя сделают потому что в прод это выкатывать — «это ж безопасность».
Кэширование? Ну может быть сделаем, но нам же актуальность данных важнее.

Не помню точно, в какой корпорации это было, но кажется в Facebook. В общем, там в какой-то момент ввели «день 2G»: раз в неделю разработчикам настоятельно рекомендовали переключать свои убер-мега-топовые смартфоны на 2G, чтобы почувствовать себя «в Африке» и перестать пытаться загрузить видео прямо в шапку главной странице сайта. Последнее я кое-где встречал.

И да, у меня есть старый нетбук с 2 гигами ОЗУ, которого мне долго хватало для разработки, но вот просмотр сайтов он уже давно не тянул, хотя как бы НЕТбук. Последнее время стало получше — Firefox-у всё-таки навели рефакторинг, но всё-таки.
UFO just landed and posted this here
Ну ой. У кого щи жидки, у кого жемчуг мелок. Вроде, в областном центре живу, а знаю места в городе, причём, не в жопе мира, где связь сильно так провисает.
UFO just landed and posted this here
Проблема в том, что у разработчиков ПО обычно топовые компьютеры с кучей памяти, быстрыми многоядерными процессорами и быстрыми дисками. И быстрый интернет.

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

Постоянная память, хоть и дешевая, но слишком медленная, чтобы код исполнялся непосредственно из нее. Оперативная динамическая память стоит гораздо больше, а быстрая статическая память, используемая для кэша, еще больше.
В конечном итоге — в чем проблема в огромном количестве зависимостей (в плане производительности конечного ПО)? Да, при разработке выкачивается вся цепочка. Но уже сборщик потом решает, что брать и нет. И роль будет играть реализация тех или иных алгоритмов, а не объем кода разработки. Или я не прав?
Он может их не брать только если на 100% уверен, что условие их вызывающее не выполнится никогда. Беда в том, что программы так разжирели, что компилятор не может вычислить все возможные состояния программы. Соответственно тянет всё, что указано в коде. А алгоритмы позволяют оптимизировать только узкие места, но у современной программы, весь её код работает одинаково медленно. А ещё благодаря ООП подходу объекты инициализируют другие объекты, которые могут лезть к диску или сети. А результат окажется абсолютно ненужен!
Беда в том, что программы так разжирели, что компилятор не может вычислить все возможные состояния программы.Соответственно тянет всё, что указано в коде.

Нет, это связано с чем-то другим, например, с динамической типизацией, динамической линковкой, может быть чем-то ещё. Например, java обычно тянет в jar все class-файлы, даже если не все они используются, — из-за динамической линковки. Можно подгрузить класс по имени. Delphi и С++ имеют статическую линковку, но, насколько мне известно, первый вырезает неиспользуемые функции из кода даже в огромных проектах, а второй — почему-то не очень.

UFO just landed and posted this here
Нет, это связано с чем-то другим
Пример заставляющий VC++ генерировать большой бинарник без необходимости
//ни один другой объектный файл не увидит эту функцию
static int func() {
        // и этот массив тоже
        // собственно он будет вырезан компилятором, если не вызвать эту процедуру
	const static char arr[30 * 1024 * 1024] = { 50 };

	int retval = 0;
        // используем только пять первых байт, вероятность доступа к остальным 0%
	for (int i = 0; i < 5; i++)
		retval += arr[i];

        // очевидно, что процедура вернёт 250
	return retval;
}

int main()
{
	printf("%d\n", func());
}

По идее, всё работает примерно так: линковщик «заходит» в функцию main(), собирает список функций, которые из неё вызываются, потом заходит уже в них и проделывает аналогичную работу и так до тех пор, пока в списке не перестанут появляться новые функции. И вот это всё он линкует, а остальное выкидывает, потому что оно никогда и ни при каких условиях не могут быть вызвано просто потому, что не упоминаются в коде. А вот оптимизация на предмет «это не может быть вызвано, потому что этот код вообще не может быть выполнен» делается компилятором и именно на этом этапе лишние вызовы просто выкидываются из объектного файла.
Виртуальные методы не выкидываются никогда, даже если нет ни единого их вызова. Так же естественно подключаются все методы которые они используют и все виртуальные методы созданных объектов и т.д. Если в функции будет условный блок, которой не будет вызван никогда, он как правило всё равно будет засчитан, потому, что компилятор не сможет оптимизировать это.
Понятно, почему линковщик подтягивает виртуальные методы — на них есть ссылка. И, собственно, это как раз дело компилятора убрать ссылки, которые никто не использует. А однозначно отследить «мёртвый» код сейчас может только человек. IDE умеют его «заподозрить» и маякнуть человеку, что вот здесь код подозрительно похож на недоступный и его, возможно, стоит убрать нафиг. Но это именно что подозрение, а оконочательное решение принимает человек. Линковщик — довольно тупая программа, если смотреть на общую логику, а не на способы её реализации, включая многопоточность и прочую радость.
Человек не может и не будет менять код сторонних библиотек, подключенных как исходники. Хотя бы потому, что после такого изменения он не сможет обновлять их версию. Желательно, чтобы это делал именно линковщик при сборке версий.

Основные точки возникновения нигде не вызваемых озёр кода — это именно стык разных систем от разных команд.
А отсеивать должен не человек, а компилятор. И, видимо, по специальному ключу, который будет указывать, что библиотека будет прилинкована статически, а значит, лишние функции можно выкинуть, потому что к ним точно никто не обратится. Причём, выкидывать он должен именно из таблицы имён, на которые объектный файл ссылается.
UFO just landed and posted this here
Тренд на параллелизацию виден уже сейчас.

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

Общая информация понятна, но как это всё скажется на всём остальном? Сколько вариантов железа придётся делать под каждую задачу и почём все это железо потом будет стоить? Сейчас конечно мир пошатнулся, там ARM процессоры вышли вперёд, все сразу «захотели на них пересесть» потому что в отличии от «классического декстопного варианта» процессор не пересобирает лишний раз информацию и архитектура достаточно проста, но как оно пойдёт на пользовательском рынке — другой вопрос.
Мы же не зря пришли к мультизадачности, ко всему этому «мусору». Т.е. индустрия могла идти на поводу своих амбиций и где-то допускать ошибки и не туда сворачивать, но обычно всё возвращается на круги своя. Возникла потребность к приходу свежей крови, которая не сечёт конечно как работает логика процессора, не является программистами ядра, однако умеют довольно неплохо справляться с задачами, которые помогает от части решать более объемный язык.
То что пуля полетит быстрее ракеты на начальных этапах это конечно важно, но чтобы ударить ракетой по другой стране нужно как и соблюдать полётный план, так и предоставить средства защиты от ПВО, а казалось бы обычная банка с керосином и взрывоопасным веществом на борту.
Сложные системы становятся хаотичными, сколько в них всё не переставляй. А разделённым системам нужно пространство и свои инструменты под нужды каждого отдельного этапа. Может быть, какие-нибудь «жидкие процессоры» и смогут в будущем уместить в себя все нужные инструменты, но этого когда-нибудь, а сейчас если нужно — оптимизируй, но трать больше средств на поиск решений, пока твои конкуренты мчат на поезде из палок и гуано, покрашенным в красный цвет, а потом они его на ходу переделывают, добавляют еще палок, еще немного свеженького гуано, потом выпускают версию 10.1 в которой вроде все проблемы решены и это стало больше походить на поезд но из-за ошибок совершенных ранее некоторые палки стали упираться в новенькие колёса и так далее и тому подобное.
Частные случаи, они всегда такие лёгкие и невесомые. Такие решаемые, а потом ты на них всё-равно лепишь поверх всякое «нужное», а потом перебираешь, пересобираешь, ищешь маленькую трещинку, через которую льются все внутренности.
Насколько я помню есть еще закон, говорящий что распараллелить эффективно можно только определённое количество раз. Дальше идёт довольно быстрое снижение эффективности, если дело касается одной задачи.

Вы наверное говорите про закон Амдала? Но он про другое.

«В случае, когда задача разделяется на несколько частей, суммарное время её выполнения на параллельной системе не может быть меньше времени выполнения самого медленного фрагмента»
Не знаю, формулировал ли кто-то такой закон, но тут скорее:
Эффективное количество параллельных потоков не может превышать количество независимых частей, на которые можно разбить задачу.

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

Зато вы можете выполнять любую другую операцию на оставшихся 4-х ядрах.
Тут естественный лимит по нехватке данных.
Можно разбить задачи на более мелкие.

А ведь распараллелить можно только независимые задачи

Мой коммент был как раз про это.
Вот, например, скалярное произведение вектора.
dot = a.x*b.x+a.y*b.y+a.z*b.z
a.x*b.x, a.y*b.y, a.z*b.z < — параллельная часть
x' + y' + z' < — последовательная часть
Да, и вы уже не сможете, например, a.x*b.x разбить на ещё более мелкие части. А так же не сможете на простаивающих ядрах запустить операции, которые зависят от результата вашего скалярного произведения.

Я это писал к тому, что распараллеливание это очень полезно, но не панацея — в зависимости от задачи вы сможете использовать от одного потока(например, вычисляя последовательность Фибоначчи) до N потоков(обрабатывая N атомарных задач) но увеличение до N*2 вам всё равно не поможет во втором случае, а в первом — вообще все дополнительные ядра будут простаивать.
в зависимости от задачи вы сможете использовать от одного потока(например, вычисляя последовательность Фибоначчи),… вообще все дополнительные ядра будут простаивать

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

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

Ну, оптимизировать-то всё равно надо не всю программу, а только узкие места (см. закон Парето). Так что "на коне" будут те, кто умеет пользоваться профайлером и мозгами для их поиска и устранения.

Быть может, это подходит для высокопроизводительных вычислений, числодробилок итп. Ну, или для крайних случаев, когда Windows читает файлы десятки тысяч раз при нажатии ПКМ. Но что делать, если софт "подлагивает" немного, но в куче мест? Вот, какое-нибудь модное приложение, а оно написано на React + Electron. Сначала запускается отдельный инстанс Chrome, потом немного парсится JS, JIT и все такое. Пользователь нажал кнопочку — создался какой-то объект (аллокация памяти), потом он прошел через десяток всяких редьюсеров, строки сравниваюстя, объекты создаются, пересоздаются, аллоцируются, удаляются, сборщик мусора пыхтит… Вроде, каждое отдельное действие быстрое и оптимизированное (напр., сравние строк внутри сишных библиотек на SSE), но все вместе приводит к тому, что итоговый результат чуть-чуть лагает. И из тысяч таких кусочков складывается картина, что железо становится мощнее, а обычный "юзерский" софт, в тех моментах, которые не упираются в числодробилки, все лагает и лагает. Быть может, я заблуждаюсь, но мне кажется, что тут профилированием не решить.

Вот, какое-нибудь модное приложение, а оно написано на React + Electron.

Может быть, просто не надо лепить такие поделия? Когда мессенджер жрет гигабайт оперативной памяти — это не серьезно.

Skype сейчас — это именно такое приложение. Там даже интерфейс сейчас лагает.

Я вам больше скажу — VS Code тоже сделана на электроне, и… не тормозит и не лагает. Не в «модности» технологий дело.
Я вам больше скажу — VS Code тоже сделана на электроне, и… не тормозит и не лагает.

После того, как там переписали ядро на C++ — да, не лагает. До этого лагала.

Интерфейс (то самое что на электроне, ага) в VS Code не лагал примерно никогда.

А это не у них был одно время в трекере тикет, что если включить моргание курсором в редакторе, то начинает отжираться 20% процессора? Или это у Атома было? (про который вообще вспоминать страшно)

Какое ядро, вы о чем вообще?

UFO just landed and posted this here
«Более лучший» по каким параметрам?
UFO just landed and posted this here
У меня символы появляются мгновенно (т.е. в пределах 50-100ms, доступных для восприятия) и запускается VSCode меньше секунды — в чём для меня будет «более лучшим» опыт, где символы появляются так же мгновенно, а среда запускается так же за пренебрежимо малое время?
UFO just landed and posted this here
А секунда на запуск это из кеша ОС, попробуйте после перезагрузки, желательно достаточно быстро, а то ОС по типу Windows сама всё в кеш утащит.

Так а с точки зрения пользовательского опыта разница какая — закеширует ОС или просто быстро приложение откроется?

UFO just landed and posted this here

Ну это опять теоретические рассуждения. Для пользователя, на практике — разница какая?

Набросал наивную реализацию на JS.
Нода v12 на обычном среднем десктопе показала 1145 секунд.
Ну что тут сказать, питон огонь!

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

А в 3.8.5 какая производительность?

В оригинале статьи


The code takes about 7 hours on a modern computer to compute the matrix product, as shown by the first row (version 1) in Table 1, achieving only 0.0006% of the peak performance of the machine. (Incidentally, Python 3 requires about 9 hours for the same computation.)

Только 10е правило Гринспена (Любая достаточно сложная программа на Си или Фортране содержит плохо продуманную, плохо документированную, забагованную и медленную реализацию половины языка Common Lisp.) от этого никуда не девается — как только появляется ресурс для освобождения головы программиста от несущественных деталей, он на это используется.

Второй быстрее третьего))
Второй быстрее запускается, а вот насчёт скорости работы уже запущенной программы не уверен.
Если использовать jit — компиляцию (numba) то питон справляется за 808 секунд на колабе, а на стационарном компе (с распаралеливанием) — 232 с. Если использовать умножения матриц в numpy — 0.8 с.
NumPy — это всё-таки не Python, а очень даже C, прикидывающийся модулем Python. Хотя, конечно, именно так и надо делать подобные вещи на Python.

Так нельзя сравнивать. Может, у вас комп в 3 раза быстрее.
Надо на одном и том же железе запускать и вашу реализацию и питоновскую.


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

Не верю, что решение на C будет 10 минут работать.
Видимо, причина в размере матрицы — он подобран так, чтобы точно не влезать ни в какие кэши и постоянно ходить в оперативную память. Там если потестить с разными размерами, получается не совсем теоретическая кубическая зависимости, график покруче растёт.

JS-код для тестирования
const N = 4096;
const N2 = N * N;

const A = new Float64Array(N2);
const B = new Float64Array(N2);
const C = new Float64Array(N2);

function fillRandom (M) {
	for (let i = 0, len = M.length; i < len; ++i) {
		M[i] = Math.random();
	}
}

fillRandom(A);
fillRandom(B);

function index (i, j) {
	return i * N + j;
}

console.time('mul');

for (let i = 0; i < N; ++i) {
	for (let j = 0; j < N; ++j) {
		for (let k = 0; k < N; ++k) {
			C[index(i, j)] += A[index(i, k)] * B[index(k, j)];
		}
	}
}

console.timeEnd('mul');

// печатаем несколько произвольных элементов,
// чтобы оптимизирующий компилятор не счёл код мертвым
console.log(C[N]);
console.log(C[Math.round(N2/5)]);
console.log(C[Math.round(N2/2)]);
Думаю это проблема решится, когда в сферу разработки ПО войдет ИИ. Только он способен проанализировать гигабайты мусора и выбросить все ненужное. А в будущем, думаю, люди будут писать код на каком-то абстрактном метаязыке, а умный компилятор будет генерить оптимальный код под нужную архитектуру с учетом всех ее особенностей.
Нынешний ИИ, насколько он мне видится, это тоже распиленная часть чего-то, что должно быть целым. Мы учим машину зрению, хотя понимаем, что сами полагаемся не только на него и не только на собственный опыт, когда опознаём картинку или другое окружение. Хотим такое же восприятие как у нас, только быстрее и надёжнее, сами при этом состоим из категоричных минусов, которые являются частью каких-либо плюсов.
ИИ может хорошо проверить и построить по указке, но лично я бы не стал ему доверять именно создание чего-либо, особенно сложных систем.
А в будущем, думаю, люди будут писать код на каком-то абстрактном метаязыке, а умный компилятор будет генерить оптимальный код под нужную архитектуру с учетом всех ее особенностей.

Ирония в том, что под ваше описание подходят Java, Python… Да и С++. Возможно, что и Fortran.

Только этим ИИ никто не будет пользоваться, как сейчас не пользуются лысой лошадью от PVS-Studio, которая за час найдёт почти в любом современном проекте больше багов, чем отдел тестирования за месяц.
Пробовал лысую лошадь, сильного преимущества перед clang-tidy (встроенного, к слову, в CLion) не нашел.
UFO just landed and posted this here
О нет! Только не это!

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

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


Проблема тут в том что библиотека делается для пользователей, а не для разработчиков библиотеки, но 90% её пользователей (а то и все 99%) никогда не посмотрят внутрь, надеясь на то что разработчики сделали всё максимально эффективно, а не наглядно.

UFO just landed and posted this here

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


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


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

Либы конечно отдельная тема

Я говорил именно о них. Простой пример — функцию подсчёта числа установленных бит в слове (32 бита) можно написать перебором битов (96 операций), а можно с помощью bit twiddling (12 операций). Первая будет понятна но медленна, если попадёт в очень длинный цикл, вторая будет непонятна но очень быстрой и в зависимости от конкретной задачи может сэкономить массу времени выполнения (в несколько раз, да — умножьте это на триллионы операций и потраченные ватты в датацентре).


Причём, вероятность того что именно эту функцию придётся править когда-либо стремится к нулю (для распостранённых архитектур, по крайней мере), то есть это фактически "write once, read never" код, а комментарий рядом с отсылкой на принцип действия и поддерживаемые архитектуры решит все сомнения для тех кому вдруг придётся там копаться.


А так да, если известно что какой-то кусок кода требует аж 10ms на выполнение (вместо возможных 10ns), но при этом ждёт ответа от сервиса который требует минимум 500ms на обработку — то это имеет мало смысла оптимизировать.

Я говорил именно о них. Простой пример — функцию подсчёта числа установленных бит в слове (32 бита) можно написать перебором битов (96 операций), а можно с помощью bit twiddling (12 операций

Либо даже в managed языке дёрнуть какой-нибудь BitOperations.PopCount, который под капотом вызывает нативную инструкцию для x86 / ARM и только в крайнем случае делает фоллбэк на софт-реализацию.

Мой опыт показывает, что можно писать оптимальный и как бы нечитаемый код, если его тщательно задокументировать. Иногда приходится писать именно что очень запутанные алгоритмы, потому что по-другому они раздуются до совершенно невменяемых размеров и — внезапно — так и останутся нечитаемыми из-за своих размеров. В таких случаях я просто пишу развернутые комментарии по пять строк комментария на строку кода, иначе сам через пару часов не разберу, что там делается. И вот никто не мешает поступать так же при оптимизации. Но да, это надо писать комментарии, а это Лень-матушка да Лом-батюшка. Но что делать? И да, такие фрагменты кода надо выделять, чтобы было понятно, что здесь «всё сложно», влезать с осторожностью.

Более того, оптимальный код может быть даже проще и читабельнее. Несколько раз было, что наивный перебор занимает 100 строк навороченного рекурсивного кода, когда как решение через динамическое программирование кроме того, что быстрее, еще и занимает 20 строк кода+комментарии, где просто 2 вложенных цикла и простые вычисления.


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

В качестве примера исследователи приводят перемножение двух матриц 4096×4096. Они начали с реализации на Python как одного из самых популярных языков высокого уровня. Например, вот реализация в четыре строки на Python 2:

Какой-то наркоманский пример.

Если надо перемножать большие матрицы на Python — есть numpy. ( который для этого и придуман)
С тем же успехом можно было сравнивать трудоёмкость написания асинхронного веб сервера на nodeJS и ассемблере.

Я не к тому, что любое мобильное приложение надо писать на electron (привет Slack), просто инструмент — под задачу. ( хотя, очевидно, если все мобильные приложения будут писать на Rust люди с нормальной алгоритмической подготовкой — они будут сильно быстрее)

Если мне надо умножить две матрицы 1 — раз, чтобы получить результаты статистических расчетов по клиентам банка, возможно, самое простое —
import numpy
. Если надо их перемножать, чтобы в реальном времени управлять космическим кораблём — наверное — C\C++\Rust на процессоре с realtime-архитектурой.

А numpy не на C реализован? Получаетя нечестно, говорим про питон, а привлекаем C ему в помощь.
И сколько numpy займет гигабайт на SSD диске, а он ведь не резиновый. И если нужно в нескольких средах работать, и каждая, скажем, по 5 гигабайт. А еще — Keras и Tensorflow новых версий видите ли, не работают с некоторыми проектами, и нужно еще и прошлые версии тоже установить. И т.д.
Как раз речь и идет об ожирении программ...

1. На С, (как и питон)) ). Нечестно — сравнивать по производительности питон и С. (как нечестно сравнивать ассемблер и nodeJS по скорости написания асинхронного веб сервера)
2. Numpy в 5 ГБ — Вы слегка загнули. Поставил — 67 МБ ( python3.8 ).

Много ли какой-нибудь TODO list перемножает матриц? ( если не брать видеосистему ОС, где всё оптимизированно, кстати, это ещё и к честности сравнения, т.к. большинство приложений используют ещё и api ОС, которую написали на C)
Некоторым программам — нормально жиреть, некоторым нет. Как я сказал выше — инструмент под задачу.
Согласен, по 5 Гигабайт у меня среды занимают. Но их много. (Но, чтобы перемножить матрицы я не стал бы и 67 Мб тратить). Матрицы — это же для примера. Автору статьи нужно было нестандартную задачу привести, такую, для которой нет реализации в готовых библиотеках.
Это я о своем, пробовал машинное обучение на Windows, macOS, Linux. Работает нормально в Linux, в других системах модели получаются, но нерабочие.
А еще известно, что результаты научных расчетов на питоне могут различаться в зависимости от того, под какой ОС они получены. Из-за этого дискредитировано около сотни работ.
Вообще, float в стандартной компиляции — не гарантирует одинаковый результат ( он зависит от процессора), если нет специального флага, тем более — ML на GPU. ( Сомневаюсь, что если написать и обучить нейросеть на tensorflow-gpu + C++ — результат будет детерминированее, чем tensorflow-gpu + python.

stackoverflow.com/questions/7295861/enabling-strict-floating-point-mode-in-gcc
Сомневаюсь, что если написать и обучить нейросеть на tensorflow-gpu + C++ — результат будет детерминированее, чем tensorflow-gpu + python.

Обычно при обучении используются стохастические методы и случайная инициализация. Детерминированность результата возможна только в близких к тривиальным случаях.

UFO just landed and posted this here
Скорее тут не ОС виноваты, а авторы которые допустили неустойчивости в алгоритмах, проглядели деления на маленькие числа, и т.п…
NumPy занимает чуть меньше 23 МЕГАбайт. И это действительно серьёзная библиотека. А главное — универсальная. Потому и такая толстая. Остальное Python, который всё равно есть в системе, если речь о Linux.
Мечтать нужно не о мифической скорости (типа крайне редкой задачи перемножения матриц), а об эффективности.

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

Сколько читаю статьи на этом сайте — одни разговоры про моду, и почти ничего про реально нужное. Количество примитивно мыслящих убивает всё и вся, включая самих себя. Переходят на мобилки, на минимум движений, на минимум мыслей. И статьи вроде этой им кажутся «важными», «открывающими горизонты». Как же легко обманывать простодушных любителей мобилок…
А что такое по-вашему эффективность, если не скорость?
UFO just landed and posted this here
А как этот разумный баланс измерить?
Если бы я был заказчиком и мне бы сказали, что скорость загрузки моего сайта можно уменьшить до 120 мс, в то время как у моих конкурентов скорость загрузки 240 мс, поэтому при прочих равных я буду привлекательнее для потребителя, но за такую оптимизацию я должен заплатить 100 тысяч у.е., то я сразу пойму, что за эффективность тут имеется в виду.
А если мне скажут «За X тысяч у.е. мы улучшим взятый на потолке показатель эффективности на X%», то я, конечно, понятливо покиваю, а потом обращусь к тем людям, которые предлагали мне до этого скорость.

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

UFO just landed and posted this here
Извиняюсь, влезу.
Когда мы переходим к более сложным системам, эффективностью будет являться более точное и качественное решение с минимальными затратами и то насколько оно удержит позицию такового. Реалии говорят — делать что-то под определённые нужды не получится в большинстве случаев, потому что для этого нужна целая инфраструктура, поддерживающая продукт от начала до конца, а конечная цена производимого будет напрямую зависеть от количества произведённого, если нет других технологий для создания более дешевой версии аппаратной части.
Так что на бумаге это всё отлично, а когда начинает работать, понимаешь что без мультизадачности никак. И ты либо потратишь время на расчёт отдельно взятых частей задачи, а потом всё это скомпилируешь, либо часть за тебя сделает язык, а тебе придётся просто привнести в это порядок и лоск.
Не скоростью единой:
Есть класс задач, где скорость не поможет никак.

А есть такие, где скорость не желательна.
Например ребёнку делают тест ДНК. Симулируют сценарии его будущей жизни(с 90% вероятностью) и радостно сообщают, что он не будет гражданином образованным, так как не способен.

Или оптимизировать скорость вывода синего экрана смерти и ждать 15 секунд ввода от пользователя, вместо…

А в чем здесь нежелательность скорости?

крайне редкой задачи перемножения матриц

Разработчики игр и искусственного интеллекта с вами не согласятся.
Решил проверить пример на Java 10 и .NET Core 3.1.
Результаты:
Java 10: 68 sec.
.NET Core 3.1: 79 sec.

Даже не близко.

C#
            int[][] C = new int[4096][];
            int[][] A = new int[4096][];
            int[][] B = new int[4096][];

            Array.Fill(A, new int[4096]);
            Array.Fill(B, new int[4096]);
            Array.Fill(C, new int[4096]);

            var watch = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < 4096; i++)
            for (int j = 0; j < 4096; j++)
            for (int k = 0; k < 4096; k++)
            {
                C[i][j] += A[i][k] * B[k][j];
            }

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;
            Console.WriteLine($"Time: {elapsedMs / 1000} sec.");


Java
        int[][] C = new int[4096][];
        int[][] A = new int[4096][];
        int[][] B = new int[4096][];

        Arrays.fill(A, new int[4096]);
        Arrays.fill(B, new int[4096]);
        Arrays.fill(C, new int[4096]);

        long startTime = System.nanoTime();
        for (int i = 0; i < 4096; i++)
            for (int j = 0; j < 4096; j++)
                for (int k = 0; k < 4096; k++)
                {
                    C[i][j] += A[i][k] * B[k][j];
                }

        long endTime = System.nanoTime();
        long timeElapsed = endTime - startTime;
        System.out.println("Execution time in sec : " +
                timeElapsed / 1000000 / 1000);

А как работает fill в Java и C#? А то в питоне такой код единожды создаст массив из 4096 элементов и скопирует ссылку на него 4096 раз, но это не то, что надо.

Создается новый объект.

IL код
IL_0000: ldc.i4 4096 // 0x00001000
IL_0005: newarr int32[]
IL_000a: stloc.0 // C


IL_0000: Pushes a supplied value of type int32 onto the evaluation stack as an int32
IL_0005: Pushes an object reference to a new zero-based, one-dimensional array whose elements are of a specific type onto the evaluation stack.
IL_000a: Pops the current value from the top of the evaluation stack and stores it in a the local variable list at a specified index.

Вы уверены?
Из вашего листинга:


// [13 13 — 13 42]
IL_0021: ldloc.1 // A
IL_0022: ldc.i4 4096 // 0x00001000
IL_0027: newarr [System.Runtime]System.Int32
IL_002c: call void [System.Runtime]System.Array::Fill<int32[]>(!!0/int32[]/[], !!0/int32[]/)


Вот здесь вызывается Fill. Новый массив точно копируется целиком, а не лишь ссылка на него? В java переменные с типом "массив" — это ссылки на объекты "массив". В C# точно по-другому?


Посмотрите, не одинаковы ли строки в этих массивах.

В C# массивы это ссылочный тип. Однако тут ссылки на разные объекты. Метод Fill проходится по массиву и присваивает значения.
Вообще, присваивание ссылки выглядит так:
// B = A;
IL_0033: ldloc.1 // A
IL_0034: stloc.2 // B


Сам код Array.Fill из библиотеки
        public static void Fill<T>(T[] array, T value)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            for (int i = 0; i < array.Length; i++)
            {
                array[i] = value;
            }
        }

        public static void Fill<T>(T[] array, T value, int startIndex, int count)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            if (startIndex < 0 || startIndex > array.Length)
            {
                ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
            }

            if (count < 0 || startIndex > array.Length - count)
            {
                ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
            }

            for (int i = startIndex; i < startIndex + count; i++)
            {
                array[i] = value;
            }
        }


github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Array.cs


Вам не кажется некорректным вот это поведение?
https://ideone.com/DDV9EC


Код и вывод
using System;

public class Test
{

    public static void Main()
    {
        // your code goes here
        int[][] a = new int[5][];
        Array.Fill(a,new int[5]);
        printMatrix(a);
        a[1][2]=3;
        printMatrix(a);
    }

    private static void printMatrix(int[][]arr)
    {
        for (int i = 0; i < arr.GetLength(0); i++)
        {
            for (int j = 0; j < arr[i].GetLength(0); j++)
            {
                Console.Write(arr[i][j]+" ");
            }
            Console.WriteLine();
        }
        Console.WriteLine();
    }
}

Вывод:


0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 

0 0 3 0 0 
0 0 3 0 0 
0 0 3 0 0 
0 0 3 0 0 
0 0 3 0 0 

Это очень странное создание матриц.

Да, вы совершенно правы, я ошибся. Этот Fill просто создает ссылку на один и тот же подмассив, вместо этого нужно через for инициализировать.

Вообще-то многомерный массив на java выделяется как


double[][] a = new double[4096][4096];

а не


int[][] A = new int[4096][];
Arrays.fill(A, new int[4096]);

Ваш (некорректный) код мог целиком поместить данные в кэш, реальное умножение матриц менее дружелюбно к кэшу.

На double всё драматичнее. С массивами предварительно заполненными случайными числами время:
Java: 1358 sec.
C#: 325 sec.

а вы уверены, что компилятор не заоптимизировал циклы? А все указанное время он занимался выделением памяти и ее очисткой?

Не ленитесь выводить результат…
А все указанное время он занимался выделением памяти и ее очисткой?

Ну, уж выделение-то памяти для каких-то 12к объектов всяко быстрее 90 секунд работает. Не говоря уже о том, что там выделяются всего 6 объектов по 16-32кБ.
Но всё равно заведомо нулевые числа перемножать и суммировать — идея так себе.

не ну если все честно компилятор делает — то он выделяет примерно 400 МБ памяти. для int_16t

Порядка 384МБ для double (по 8 байт). 3*(4096*4096*8+ 4096*8) "нетто". "Всего" 12тыс. объектов. У меня на это уходит примерно секунда (если замерять визуально).


Это немного. Тормоза, как я помню, начинаются от нескольких млн. объектов.

Здесь основная проблема не в этом — на весь код всего 6 операторов new() — т.е. всего 6 объектов. Это неправильная матрица.

Не большой знаток IL, но вроде нет.

IL
.method private hidebysig static void
Main(
string[] args
) cil managed
{
.entrypoint
.maxstack 5
.locals init (
[0] int32[][] C,
[1] int32[][] A,
[2] int32[][] B,
[3] class [System.Runtime.Extensions]System.Diagnostics.Stopwatch watch,
[4] int64 elapsedMs,
[5] int32 i,
[6] int32 j,
[7] int32 k
)

// [9 13 - 9 41]
IL_0000: ldc.i4 4096 // 0x00001000
IL_0005: newarr int32[]
IL_000a: stloc.0 // C

// [10 13 - 10 41]
IL_000b: ldc.i4 4096 // 0x00001000
IL_0010: newarr int32[]
IL_0015: stloc.1 // A

// [11 13 - 11 41]
IL_0016: ldc.i4 4096 // 0x00001000
IL_001b: newarr int32[]
IL_0020: stloc.2 // B

// [13 13 - 13 42]
IL_0021: ldloc.1 // A
IL_0022: ldc.i4 4096 // 0x00001000
IL_0027: newarr [System.Runtime]System.Int32
IL_002c: call void [System.Runtime]System.Array::Fill<int32[]>(!!0/*int32[]*/[], !!0/*int32[]*/)

// [14 13 - 14 42]
IL_0031: ldloc.2 // B
IL_0032: ldc.i4 4096 // 0x00001000
IL_0037: newarr [System.Runtime]System.Int32
IL_003c: call void [System.Runtime]System.Array::Fill<int32[]>(!!0/*int32[]*/[], !!0/*int32[]*/)

// [15 13 - 15 42]
IL_0041: ldloc.0 // C
IL_0042: ldc.i4 4096 // 0x00001000
IL_0047: newarr [System.Runtime]System.Int32
IL_004c: call void [System.Runtime]System.Array::Fill<int32[]>(!!0/*int32[]*/[], !!0/*int32[]*/)

// [17 13 - 17 65]
IL_0051: call class [System.Runtime.Extensions]System.Diagnostics.Stopwatch [System.Runtime.Extensions]System.Diagnostics.Stopwatch::StartNew()
IL_0056: stloc.3 // watch

// [18 18 - 18 27]
IL_0057: ldc.i4.0
IL_0058: stloc.s i

IL_005a: br.s IL_00a8
// start of loop, entry point: IL_00a8

// [19 18 - 19 27]
IL_005c: ldc.i4.0
IL_005d: stloc.s j

IL_005f: br.s IL_0099
// start of loop, entry point: IL_0099

// [20 18 - 20 27]
IL_0061: ldc.i4.0
IL_0062: stloc.s k

IL_0064: br.s IL_008a
// start of loop, entry point: IL_008a

// [22 17 - 22 46]
IL_0066: ldloc.0 // C
IL_0067: ldloc.s i
IL_0069: ldelem.ref
IL_006a: ldloc.s j
IL_006c: ldelema [System.Runtime]System.Int32
IL_0071: dup
IL_0072: ldind.i4
IL_0073: ldloc.1 // A
IL_0074: ldloc.s i
IL_0076: ldelem.ref
IL_0077: ldloc.s k
IL_0079: ldelem.i4
IL_007a: ldloc.2 // B
IL_007b: ldloc.s k
IL_007d: ldelem.ref
IL_007e: ldloc.s j
IL_0080: ldelem.i4
IL_0081: mul
IL_0082: add
IL_0083: stind.i4

// [20 39 - 20 42]
IL_0084: ldloc.s k
IL_0086: ldc.i4.1
IL_0087: add
IL_0088: stloc.s k

// [20 29 - 20 37]
IL_008a: ldloc.s k
IL_008c: ldc.i4 4096 // 0x00001000
IL_0091: blt.s IL_0066
// end of loop

// [19 39 - 19 42]
IL_0093: ldloc.s j
IL_0095: ldc.i4.1
IL_0096: add
IL_0097: stloc.s j

// [19 29 - 19 37]
IL_0099: ldloc.s j
IL_009b: ldc.i4 4096 // 0x00001000
IL_00a0: blt.s IL_0061
// end of loop

// [18 39 - 18 42]
IL_00a2: ldloc.s i
IL_00a4: ldc.i4.1
IL_00a5: add
IL_00a6: stloc.s i

// [18 29 - 18 37]
IL_00a8: ldloc.s i
IL_00aa: ldc.i4 4096 // 0x00001000
IL_00af: blt.s IL_005c
// end of loop

// [25 13 - 25 26]
IL_00b1: ldloc.3 // watch
IL_00b2: callvirt instance void [System.Runtime.Extensions]System.Diagnostics.Stopwatch::Stop()

// [26 13 - 26 55]
IL_00b7: ldloc.3 // watch
IL_00b8: callvirt instance int64 [System.Runtime.Extensions]System.Diagnostics.Stopwatch::get_ElapsedMilliseconds()
IL_00bd: stloc.s elapsedMs

// [27 13 - 27 65]
IL_00bf: ldstr "Time: {0} sec."
IL_00c4: ldloc.s elapsedMs
IL_00c6: ldc.i4 1000 // 0x000003e8
IL_00cb: conv.i8
IL_00cc: div
IL_00cd: box [System.Runtime]System.Int64
IL_00d2: call string [System.Runtime]System.String::Format(string, object)
IL_00d7: call void [System.Console]System.Console::WriteLine(string)

// [28 9 - 28 10]
IL_00dc: ret

} // end of method Program::Main


UFO just landed and posted this here
А почему никто не говорит, что надо улучшать компиляторы? Если работа высокоуровневого программиста — перемножать матрицы в 4 строки и двигаться дальше, то почему он должен каждый раз нырять в низкоуровневые дебри? Описанный код вполне может быть ускорен, распараллелен и векторизован умным анализатором, JIT, AI компилятором и чем-либо еще. Если мы хотим сохранить разделение на уровни абстракции, а не смешивать все слои в попытках оптимизировать все перед релизом, то сами инструменты должны эволюционировать каждый год. Но никто из разработчиков ОС/языков/компиляторов не хвастается, что с новым апдейтом Windows или MacOS стала быстрее запускать программы, а код для Python 3.8 с апдейтом до 3.9 станет автоматом подключать numpy, прогонять нужный кусок на автоматических тестах и в итоге его заменять на быструю версию. Даже в случае явной эволюции .Net Framework -> .Net Core нельзя запустить старый код и получить прирост производительности за счет RyuJIT и других вкусностей.
Наверное, потому, что компиляторы и так улучшаются по мере возможности. А вот про оптимизацию софта такое сказать нельзя.
Даже в случае явной эволюции .Net Framework -> .Net Core нельзя запустить старый код и получить прирост производительности за счет RyuJIT и других вкусностей.

Вообще-то можно и получается: 2.0, 2.1, 3.0, 5.

Мое сообщение говорит о том, что код с .Net Framework не запустится на .Net Core. Разные CLI.
Скажем так, приличную часть кода можно из .Net Framework «портировать» в .Net Standard и спокойно запускатъ как в .Net Framework, так и в .Net Core. Причём опять же в большинстве случаев даже особо напрягаться не надо будет.

Но именно .Net Framework библиотеки в .Net Core работать не будут.
Описанный код вполне может быть ускорен, распараллелен и векторизован умным анализатором, JIT, AI компилятором и чем-либо еще.

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


К примеру, если вы пишите функцию для поиска простых чисел, то никакой оптимизатор не "догадается" что это — поиск простых чисел, а как раз в таких случаях алгоритмы решают и дают мощный выигрыш по ресурсам.


Максимум возможностей оптимизатора — это эффективно реализовать то что вы написали на C/C++/Rust/etc в машинном коде, с учётом особенной процессора и архитектуры, по дороге выкинув лишнее (CSE, упрощение выражений, etc).


Основная же проблема — это чрезмерное обобщение и абстрагирование, которым буквально пронизаны большинство современных фреймворков и библиотек — классический случай "Jack of all trades, master of none".


Да, разработчикам проще и быстрее, но — ценой ресурсов, причём не их ресурсов.

Никакой оптимизатор не знает с какой целью создан код, а без знания цели можно только оптимизировать очевидные вещи, которые хоть и помогают иногда, но всё же не далеко не всегда.
Сейчас DLSS умеет достраивать изображение в игре в реалтайме, повышая разрешение почти в два раза. Неужели рано или поздно оптимизатор не сможет понять, что конкретно в этом примере — умножение матриц, которое можно сделать с помощью AVX?
Аналогично с распараллеливанием — OpenMP и GCC уже два десятка лет обрабатывают #pragma omp parallel for, но аж в трех языках программирования и только с прямым указанием, что этот цикл можно параллелить.
Неужели рано или поздно оптимизатор не сможет понять, что конкретно в этом примере — умножение матриц, которое можно сделать с помощью AVX?

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


Разумней подходить с другой стороны — на входе должна быть спецификация (что ожидаем на входе и выходе, ограничения по ресурсам etc), а жутко вумный компилятор подберет самые эффективные алгоритмы для реализации задачи на конкретной платформе, что-то типа "Ok Google, сделай-ка для меня приложение которое...".


Впрочем… если это будет когда-либо реализовано, да ещё надёжно (почти неизбежно, хотя вероятно и не в этом столетии) — программисты в массе своей уже будут не нужны.

UFO just landed and posted this here

Разве нельзя в компиляторе сделать прогон хотя бы циклов с попыткой их оптимизации?
В цикле на миллион проходов выполняется n++. Может ли компилятор пропустить его в пользу n=1000000?

Это как раз делается (иногда), но опять-таки, компилятор может лишь "догадываться" что важно именно значение "n" на выходе, а не побочные эффекты (время выполнения, нагрузка на кэш/память etc).


К тому же, с точки зрения банальной эрудиции здравого смысла (если не исключать его наличие у программиста) цикл на миллион повторений явно неспроста, если результат можно получить обыкновенным умножением.

UFO just landed and posted this here

Зря недооцениваете ИИ… К примеру, написал кто-то js либу, и заюзали ее 100500 проектов на гитхабе. Плюс, если спарсить код топ 1000000 сайтов мира, то там тоже на 10% она встретится.
То есть, ии может
1) проанализировать код этих сайтов и гитхаба
2) запустить код с гх и сайтов и отпрофайлить его со всех сторон
3) запустить ещё несколько миллиардов синтетических прогонов
4) создать оптимальный код для самых частых ветвей исполнения кода.
5) вывести правила, при которых оптимизацию запускать можно (чтобы не запустить оптимизацию на коде, который появится потом и будет использовать какой-то нестандартный грязный хак).


Может ли человек сделать что-то подобное?

Неужели рано или поздно оптимизатор не сможет понять, что конкретно в этом примере — умножение матриц, которое можно сделать с помощью AVX?

Не сможет. Вдруг такой порядок суммирования нужен специально, чтобы ошибка не накапливалась или не было переполнения? IEEE 754 на этот счёт специально говорит, что порядок вычислений, задаваемый программистом, свят и нерушим. Векторизация допустима только если программист её явно разрешил.


Аналогично с распараллеливанием

Да, совершенно аналогично. Внезапно, на компьютере, помимо, перемножения матриц, может параллельно что-то ещё быть запущено. Яростное желание некоторых особо умных компиляторов выжрать все доступные ресурсы компьютера — это оптимизация под конкретный вид рабочего процесса, но он не обязательно у всех именно такой. Например, я могу на 18 ядрах захотеть перемножать 18 пар матриц параллельно, а не каждую пару раскидывать на все ядра.


То есть компилятор компилятором, но в языке должна быть хотя бы в принципе возможность выразить подобные намерения, предположение, что пользователь всегда хочет максимальных флопсов — оно не 100% верное.

Окей, отставим в сторону автоматическую замену кода будущим поколениям. Но даже полу-автоматический режим может быть весьма полезен — представьте, если анализатор скажет «вы пытаетесь перебрать коллекцию из 1000500 элементов в один поток, может стоит тут распараллелить или убрать прямой перебор?». Буквально, только PVS Studio движется в подобном направлении. Огромного количества медленных мест можно избежать, если IDE будет проводить глубокий анализ, а не примитивные советы вроде «результат функции нигде не используется». И технологии для этого уже есть, просто задачи такой нет.
Откуда анализатору знать, что в коллекции 1000500 элементов? Или Вы просто хотите получать варнинг каждый раз как используете цикл?
Буквально, только PVS Studio движется в подобном направлении

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

Лет 15-20 назад куча людей примерно тоже самое говорили про любые анализаторы в принципе. Так что я бы не зарекался… :)

Если программист допускает такие ошибки — значит он идиот.

Как показывает опыт PVS-Studio, этим идиотом может оказаться вообще кто угодно, в том числе и вы.

Опыт PVS-Studio, насколько мне известно, вообще не связан с ошибками архитектуры. Там про опечатки и UB в основном, рекомендаций вроде «тут перебор большой коллекции» я не припоминаю.
А я бы пользовался таким. Мне не страшно клеймо идиота или программиста на костылях, я согласен с мыслью, что алгоритмы и оптимизации могут развиваться быстрее, чем я их изучу.
Напишу где-нибудь (x*x*3 — x*x*x*2), а мне анализатор сразу «вы изобрели smoothstep, может не делать велосипед, а взять библиотечную функцию?»
Ясное дело, в голову приходят только примеры, которые я знаю как оптимизировать. Но наверняка есть еще сотня таких, о которых не в курсе.
Если программист допускает такие ошибки — значит он идиот.

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

если анализатор скажет «вы пытаетесь перебрать


Когда-то на Хабре писали про компилятор Фортрана. Он делал именно это.

Это нужен очень глубокий анализ, мне кажется.
Если узкое место — линейный перебор, то что можно предложить-то? Обычно это структуру данных нужно менять, а оно не всегда допустимо — эта коллекция может использоваться в других частях кода, где насчёт неё тоже есть какие-то свои предположения, которые замена способа хранения может нарушить.
Распараллеливание тоже не так просто, как кажется. Должна ли IDE анализировать, насколько далеко получится распараллелить, прежде чем задача перейдёт из compute-bound в memory-bound?
subcommande правильно говорит, такие вещи — это не уровень программиста, который должен выполнить задание. Это уровень архитектора, который задание выдал. Их нельзя подсовывать как точечные подсказки, должен быть язык описания требований и ограничений по масштабируемости на уровне конфигурационных файлов, иначе можно наворочать, что асинхронные параллельные части программы будут вырывать друг у друга канал памяти и тормозить ещё больше.

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

Небольшая модификация кода на Python — использование декоратора numba.jit с подключением AVX-инструкций заметно ускоряет его. На колабе получается 808 с, матрицы типа float64, float32 должно быть еще быстрее. Кто хочет проверить или поэкспериментировать — colab.research.google.com/drive/1-bo0Tiyj4zrh_JMYiGSj7Em_2bXKBvdK?usp=sharing. Но вот уже умножение с использованием встроенной функции numpy — всего 4-8 с, так что оптимизировать есть куда.
p.s. Воспроизводимость на колабе так себе — на разных ноутбуках результаты могут серьезно отличатся.

О, а colab не на сервере считает?!

На сервере по умолчанию. Но так как ресурсы выделяются скромные (все же бесплатный), на современной машине будет немного быстрее (скорее всего, но зависит от версий библиотек итп). Ну и каждый раз запуская колаб — вы не получите один и тот же набор железа (cpu, gpu). Стандартно там 2 потока (1 ядро с гипертрейдингом) выделяется, но какого поколения это проц — непонятно, есть ли там AVX2 соответственно тоже.

Понятно, спасибо. Я уж испугался, что мне в броузер загружается python и выполняется в броузере

При увлечении оптимизацией жертвуют в основном не скоростью написания кода, а надежностью и поддерживаемостью.
Надеюсь, будущее за высокоуровневыми языками, позволяющими детали реализации оставлять компилятору, и хорошими оптимизаторами.
Извиняюсь конечно, но статья похожа на бурчание старых дедов. Пока производительность растёт конскими темпами, а память ничего не стоит — такая ситуация и будет продолжаться дальше. т.к. нет смысла идеально оптимизировать свой софт. Гораздо важнее — как можно быстрее его реализовать и это абсолютно нормально. А то пока будешь заниматься оптимизацией, конкуренты выпустят 10 таких же но не оптимизированных приложений и все денюжки уйдут им.
Раньше занимались оптимизацией т.к. не было другого варианта — или оптимизируй почти до идеала или железо не потянет твою софтину. Вспоминаю описанные на хабре эпопеи с оптимизацией игруль для PS1. А сейчас лишние когда лишние 8ГБ оперативки стоят 30 баксов, жесткий диск на терабайт ещё 50, то кто будет заморачиваться с оптимизацией? Когда на рынке процессоров, кол-во ядер удваивается каждые пару лет, чего вы хотели — идеальной оптимизации? Seriously?
P.S. Меня тоже напрягает данная ситуация, но ныть об этом толку нет — всё изменится только тогда когда мы упрёмся в физический потолок увеличения производительности. Только когда оптимизация станет экономически оправданной — только тогда о ней и будут думать.
А вы не думали что данная проблема остановила рост функциональности новых программ.
Вместо появления новых функций, программа получает дизайнерский бантик, море «жира» и ноль нового функционала?
Я бы так не сказал. По крайней мере программы, которыми я пользуюсь, новый функционал всё-таки получают.

Как впрочем и те программы, которые я пишу.

Просто часто добавить новый функционал это много работы и это длится долго. А «бантик» сбоку прилепить часто дело пяти минут. Банально стайл поменял и вот тебе уже и совсем по другому выглядящая программа.
UFO just landed and posted this here

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

Так мы уже почти упёрлись в этот потолок. Остались считанные годы, думать пора заранее.

У программистов нет такого инструмента как автоматическая оптимизация программы.
Без такого инструмента написание быстрых и одновременно многофункциональных программ экономически не оправданно. Можно сказать даже невозможно из-за особенностей человеческого мозга — человек может одновременно оперировать 5-6 сущностями, а для высокоэффективных программ необходимо много больше.
UFO just landed and posted this here
у железячников он называется «карты карно» и тд -удаляет и оптимизирует все что не влияет на результат.
UFO just landed and posted this here
да к сожалению эффективного способа оптимизировать число тактов работы устройства нет. Поэтому тоже страдаем (((
Авторы рекомендуют сконцентрироваться на главной задаче — повышении скорости выполнения программ, а не на скорости написания кода.


Осталось выяснить, кто за это заплатит.

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

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

Библиотека: нарисовать_фигуры.
Функция "нарисовать_треугольник".
Функция "нарисовать_пентаграмму".
Код, написанный программистом:
бла-бла-бла
нарисовать_треугольник
бла-бла-бла
Результат: внутри exe файла не будет функции «нарисовать_пентаграмму».

Но что если дело обстоит так:

Библиотека: нарисовать_фигуры.
Функция "нарисовать_что-то_острое" (номер_фигуры: от 1 до 100500).
...
Если номер_фигуры = 30451, нарисовать треугольник
Если номер_фигуры = 30452, нарисовать пентаграмму
Если номер_фигуры = 30453, нарисовать кандибобрика
...
Код, написанный программистом:
бла-бла-бла
нарисовать_что-то_острое(30451)
бла-бла-бла
то результат: внутри exe файла будет ВСЁ.

Вот об этом надо подумать разработчикам компиляторов…
Может лучше разработчикам подумать и не писать убер-функции без надобности?
Пример утрирован для наглядности.
Вот другой пример: у вас есть мощная библиотека распознавания символов написанных от руки. Но вам нужны только цифры. Разработчик библиотеки об этом не подумал.
Если библиотека скомпилирована предварительно — то вопросов к компилятору быть не может, телепатически до того, как она будет использоваться, он не догадается. Если нет, и исходный код доступен — Вы по определению можете сделать с ней все что угодно.
Как в случае рисования фигур, так и в случае распознавания символов, выбор нужного функционала из более обширного (для включения в проект) это отсечение лишних данных, а не программного кода.

Библиотека может быть скомпилирована в dcu, dll или bpl. Все три варианта есть компиляция. Но первый вариант затем проходит через отсечение лишнего и включается в exe, а dll нет. С библиотеками bpl можно и так и так.

Кстати, более широкий чем нужно набор вводимых рукописных символов не только утяжеляет код, но и приводит к ухудшению качества распознавания.
Вы предлагаете дизассемблировать dll что ли? Даже если получится, модифицировать готовую библиотеку — это плохая идея с очень многих точек зрения.
Нет, я констатировал, что библиотеки dll поставляются с лишними функциями, но ведь существуют также и другие виды библиотек, при работе программиста с которыми, конечные пользователи лишних функций не получают. Это dcu и bpl. И я говорю только о вариантах, где не предоставляются исходники. И только то что хорошо знаю, наверняка есть уйма других типов файлов такого рода.
Насколько я знаю, dcu и bpl — это не совсем то же, что dll. Они не являются исполняемым файлом, а лишь содержат вывод стадии компиляции, используемый впоследствии на стадии линковки. То есть, все что в них есть — идет в основной исполнительный exe. Ну и я так понимаю, что на этом этапе все еще может как угодно оптимизироваться (link-time optimization). А вот с готовой dll ничего не сделаешь.
И все эти файлы (dll,dcu,bpl) — библиотеки. Словом библиотека назвают не только то, что идёт юзеру в неизменном виде. И то я перечислил только варианты без открытых исходников и только те с чем работаю.

Можно сконфигурировать проект, чтобы bpl хранились у конечного пользователя и подключались в рантайме. Это способ разгрузить ОЗУ и сократить время загрузки, если у пользователей разная специализация — не всем нужно всё. Именно так работает банковская система в крупнейшем негосударственном банке, где я работал.

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


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

Кажется, нечто подобное уже реализовано (в gcc, rustc) и называется link-time optimization (LTO).

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

UFO just landed and posted this here

Такое не будет работать, если используется рефлексия.

Ключевое слово "если". Есть код, который можно оптимизировать, потому что компилятор видит все возможные варианты, и есть код, который нельзя оптимизировать, потому что программист решил использовать хак. И есть ещё директивы и аннотации.

Все ПО будет в облаке. Будем подключаться к облаку Google и там у нас будет две кнопки: «сделать так» и «не делать так».
Для разработчика софта железо пользователя бесплатное (ведь его покупает и апгрейдит не он).
Пока это так — никто ничего оптимизировать не будет.
Работа на медленных компах не приводит к разработке быстрых программ, скорее наоборот.
И разработчики SQL свой код ещё как оптимизируют.
Я имел в виду веб-сайты в первую очередь, потом мобильные приложения, ну и десктопные тоже.
С оптимизацией серверного ПО все значительно лучше, там потребитель гораздо ближе и неиллюзорно голосует рублем.
При этом сам разработчик, как правило, пользуется топовыми компьютерами и не понимает как у кого-то что-то может тормозить…
На днях накрылся комп. Достал из кладовки старый ноут: Core 2 Duo, 2 гига, SSD. Зашёл на Авито и ужаснулся от тормозов. Те же объявления, те же картинки, те же сообщения, всё как и 5 лет назад, только тогда работало быстро, а сейчас медленно.
UFO just landed and posted this here
Да, они стали жрать 200 мегабайт вместо 20, но какая нахрен разница если у юзера 8 гигабайт оперативы

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

Я вотк стати в последнее время думаю что это вобще нифига не так. Юзеру ничего не хочется, работает как работается, но ему постоянно пытаются эти новые фичи продать, чтобы переманить к себе, удержать и тд. Т.е. нет никакого спрос рождает предложение, есть предложение навязывает спрос. И это во всех сферах так. Перестанут выпускать новую музыку и кино, за последние 50 лет столько контента создано что за всю жизнь не пересмотреть не переслушать не перечитать.
Я вотк стати в последнее время думаю что это вобще нифига не так. Юзеру ничего не хочется, работает как работается, но ему постоянно пытаются эти новые фичи продать

Немного странное на мой взгляд заявление. Можете привести конкретные примеры?
А то вот я смотрю на софт, которым я пользуюсь, и понимаю что мне конечно не нужны вот прямо все фичи актуальных версий, но приличная часть всё-таки нужна.


И на версиях скажем пятилетней давности я бы работать уже не хотел. Там уже не хватает как минимум приятных, а местами и даже прямо необходимых вещей…

Конкретный пример: ACDSee. Уж не знаю какая сейчас версия актуальная, но v15 уже точно давно была. При том, что реальные и нужные улучшения у них закончились где-то в районе v5. Больше того, v2 или v3 абсолютно юзабельны и достаточны для той цели, под которую изначально задумывались.
Наверно ты не правильно прочитал, или не правильно понял прочитанное. Я не сказал что фичи по факту оказались фигней, я сказал, что люди ничего не просили. Ну если хочешь примеров. Киллер фича хабра, который тормозит на 2к+ коментах перед классическими форумами с пагинацией? Ты конечно скажешь что тут все на ветки побито и это удобно, но это вкусовщина и в 2000х никто о таком и не думал, все перекликивали страницы на форумах, и если бы человека спросили «А чего не хватает» он бы сказал «Да все ок, страницы открываются, текст читается, что еще надо то?» Объем текста на странице(2к+ комментов) просто смешной, но он тормозит в хроме(в фф все ок), ради чего?

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

Оглядываясь назад, на 10-15-20. я не вижу для себя дизайнерских(архитектурных) проблем в софте.

Без каких новых фич ты не хочешь обходиться, ради которых заплатил производительностью?

А я не за какие фичи производительностью и не платил. Ну или точнее никакой потери производительности я не ощущаю, а большего мне и не надо.


А насчёт фич… Ну вот тот же Live Share у Visual Studio например на мой взгляд очень полезная штука. Особенно в нынешнее время. И нет, я его тоже не просил и даже не думал о таком до того как попробовал в деле.

Полагаю, проблема в том, что люди, которые пишут комменты на хабре, просто не попадают в ЦА "обычные юзеры". Я вот тоже много чем из новых фич последних версий софта пользуюсь, и обновления ОС, которые эти новые фичи приносят, мне чаще в радость, нежели наоборот. Но у меня ещё есть статистика, собранная за много лет установки ровно тех же обновлений на компы и телефоны родителей и жены… и вот они, как правило, вовсе не радуются новым фичам и не стремятся их изучать, как раз наоборот — большинство изменений приехавших в обновлении их огорчают и раздражают.


Навскидку, я бы сказал, что обратная реакция (радость после обновления) у них случается в 1-5% случаев, не больше. В целом это вырабатывает однозначно негативную реакцию на обновления, и если бы я их активно не пинал "надо обновляться из соображений безопасности", то они бы предпочли точечно обновлять 1-2 программы в год, после того как столкнутся с конкретной проблемой при их использовании (глючит или не поддерживает новые протоколы/форматы файлов)… и даже в этом случае их мечта в том, чтобы обновление принесло минимум других, видимых пользователю изменений, помимо нужного.


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

Ну не знаю. Среди моих знакомых не связанных с IT большинство просто не замечают новые фичи и всё. А если им их потом кто-то покажет, то часто начинают вовсю ими пользоваться. Я даже прекрасно помню фразу одной моей знакомой относительно преклонного возраста, которая выдала «Вот было бы здорово в вотсапе не писать/читать, а просто говорить/слушать» и была очень удивлена что такая возможность давно уже есть :)

И даже если мы возьмём сам андроид, то куча вещей по поводу которых с каждем апдейтом ругалась моя жена, она потом вовсю начинала использовать. Причём дай ей опять старый телефон со старым андроидом и тоже начинаются жалобы а ля «как здесь всё неудобно»…
У меня уже давно ощущение, что программы, игры, сайты разрабатывают те, кто этими программами, играми и сайтами не пользуется. Потому что как правило, после очередного обновления какая-то операция, которая раньше делалась в один клик или тап пальцем, после делается в 2-3. Но зато красивее, с анимацией там, градиентами и пр. Очевидно, что человек, который сам бы пользовался такой системой, никогда бы такого «улучшения» не сделал.
У меня уже давно ощущение, что программы, игры, сайты разрабатывают те, кто этими программами, играми и сайтами не пользуется.

В коммерческой разработке почти всегда так. Программисты — это в основном пользователи IDE, а не своих программ. В идеале, процесс разработки должен быть построен так, чтобы в нём было юзабилити-тестирование продуктов.

Программистам задачи ставит бизнес. Если сказано — не оптимизировать, программист не оптимизирует. Сказано — оптимизировать, будет оптимизировать. А чем там он пользователь или нет — это не важно совершенно.
Конкретные примеры:
Многие продукты из адобе клауд не работают на вин7. Позавчера работали, а сегодня уже нет. А за клауд, между прочим, просят денег. Нафига мне новые фичи, если я теперь не могу пользоваться даже старыми?
Недавний скандал с хромом, когда оказалось, что «выйти из гуглоакканта» совсем не выходит из него.
дропбокс постоянно добавляет новые ненужные (мне) фичи. А с некоторых пор андроидная версия разрешает только три устройства для синхронизации на базовом плане. А у меня больше. Поэтому использую версию примерно двухлетней давности. Айфонская версия тоже ругается, но хотя бы работает.
инстаграм постоянно добавляет какие-то новые перделки, которые ухудшают мой пользовательский экспириенс (который очень примитивен — тупо полистать ленту два-три раза в неделю, но и тут они умудрились сделать разражающие вещи). Несколько лет назад удалили из приложения карту, из-за чего собственно я и стал пользоваться инстаграммом.

За последние лет 15 очень редко было, что я про какие-то новые фичи в софте, которым пользуюсь, думал «о, молодцы, что добавили!». Обычно пофигу или даже «нахрена это надо».
Извините, но это уже из совсем другой оперы. Вы пользуетесь больше неподдерживаемой ОС и удивляетесь что там что-то не работает.
Потом вы жалуетесь что где-то поймали баг. Потом вы жалуетесь что фирма урезает бесплатную версию своего продукта чтобы сподвигнуть людей за него платить. Какое это имеет отношение к новым фичам в софте?

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

Какое это имеет отношение к новым фичам в софте?

Предложение «дропбокс постоянно добавляет новые ненужные (мне) фичи» вы не заметили? Про урезание новой версии это так, до кучи. Добавили? Добавили. Мне оно надо? Не надо.

но я бы вас наверное и не назвал целевой аудиторией этого самого инстаграмма.

Сейчас конечно нет. Только это не я не являюсь целевой аудиторией, а инстаграм стал ориентироваться на другую аудиторию.

В гугломапсах появилось дофигища новых фич, которые мне не только не нужны, но и мешаются (а линейку убрали и так и не добавили). Я тоже нецелевая аудитория? Телеграм вместо того, чтобы фиксить баги, добавляет всякие перделки.
Какой баг? Это про хром что ли? Это был как раз не баг, а фича.

В моём понимании это баг. Если это сделанно намеренно, то я бы сказал что это даже возможно причина для юридического наезда. Как минимум в отдельных странах.

Про урезание новой версии это так, до кучи. Добавили? Добавили. Мне оно надо? Не надо.

Естественно вам это не надо. Но это не добавление фич, а банальное зарабатывание денег.

а линейку убрали и так и не добавили.

Эээ, где убрали? Сейчас попробовал, всё работает. Может вы в lite модусе пытаетесь это делать?

Естетственно не все фичи нужны прямо всем людям. Такого я и не говорил. Но с другой стороны как-то странно утверждать что вот прямо все дпбавляемые фичи вот прямо вообще никому не нужны. Если бы они были бы никому не нужны, то их бы и не добавляли. Зачем на такое деньги тратить?

Про хром я перепутал, там было немного другое.

Но это не добавление фич,

Повторю еще раз: дропбокс постоянно добавляет новые ненужные (мне) фичи.

где убрали? Сейчас попробовал, всё работает. Может вы в lite модусе пытаетесь это делать?

В андроидном приложении. Давным-давно можно было тыкать пальцем по карте и показывалось расстояние между точками. Это выкинули то ли в 6-й, то в 7-й версии в 2014 (кажется) году.

Но с другой стороны как-то странно утверждать что вот прямо все дпбавляемые фичи вот прямо вообще никому не нужны.

Я такого не утверждал. Вы просили пример ненужных фич.

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

Повоторю: не все фичи нужны всем людям. Но вто добавляете ли дропбокс фичи не нужные никому? Или хотя бы ненужные большинству?

В андроидном приложении. Давным-давно можно было тыкать пальцем по карте и показывалось расстояние между точками. Это выкинули то ли в 6-й, то в 7-й версии в 2014 (кажется) году.

Зашёл сейчас на смартфоне и у меня всё работает.

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

Проблема только в том что куче юзеров новых фич не хочется ровно до тех пор пока они не увидят эти новые фичи у конкурента. И тут как в Алисе: надо бежать чтобы оставаться на месте…
не все фичи нужны всем людям.

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

Не, ну я же такого не могу знать.

Зашёл сейчас на смартфоне и у меня всё работает.

Блин, погуглил — действительно, вернули. Но так, что фиг наткнешься, если не знаешь. Раньше, правда, удобней было, но хоть так.
Вот и польза от сегодняшнего разговора :)
Блин, погуглил — действительно, вернули. Но так, что фиг наткнешься, если не знаешь. Раньше, правда, удобней было, но хоть так.
Вот и польза от сегодняшнего разговора :)

You are welcome :)
Еще про телеграм: вчера оказалось что в последней версии вместе с добавлением новых перделок выпилили выбор пропорций картинки при кропе. Ну вот нахрена удалять хороший работающий функционал? Лично мне это теперь значительно усложнит использование телеграма.
UFO just landed and posted this here
Да и сейчас есть. Но раньше можно было выбрать точные пропорции 1:1, 2:3 и т.п., а сейчас что получилось, то получилось.

Когда прицепляете картинку, внизу четыре иконки: кроп, кисть, яркость/контрасть и т.д. и самоудаление. И в кропе там, где сейчас кнопка для отзеркаливания, был выбор пропорций.

PS. Видео тоже можно перед отправкой редактировать.
UFO just landed and posted this here
В Андроиде 6 вроде версии включение/выключение/автомат вспышки делался последовательным нажатием на значок. То есть режим можно было выбрать за 1, максимум 2 нажатия и очень быстро. Потом это заменили на какую-то анимацию с раскрывающимися значками, длящуюся около секунды, и уже потом надо выбирать. То есть вместо 1 или 2 нажатий стало всегда требоваться 2 + время. То же с HDR. Раньше значок был прямо на экране и включался аналогично вспышке. После засунули куда-то в меню настроек. Стоит ли говорить, что на экране места навалом и этих значков можно засунуть десяток без всякой опасности.
Вы пользуетесь больше неподдерживаемой ОС и удивляетесь что там что-то не работает.

А ты не замечаешь что во фразе
Многие продукты из адобе клауд не работают на вин7.

как раз и есть подтверждение, что новые фичи не нужны самим пользователям? Да все бы еще на XP сидели, если бы она поддеживалась.
И офисом бы пользовались 97, но майкрософту же надо денег зарабатывать, как и всем производителям ПО, потому выпускают новый софт, «без которого вам не обойтись».
как раз и есть подтверждение, что новые фичи не нужны самим пользователям?

Нет, не вижу. О какой конкретной ненужной фиче в данном случае идёт речь?

Да все бы еще на XP сидели, если бы она поддеживалась.

Нет, не все. Я бы точно не сидел.

И офисом бы пользовались 97, но майкрософту же надо денег зарабатывать, как и всем производителям ПО, потому выпускают новый софт, «без которого вам не обойтись».

Кто вам мешает сейчас пользоваться 97-м офисом?
О какой конкретной ненужной фиче в данном случае идёт речь?

В том то и дело, что я тоже не вижу фичи, которую получил пользователь перейдя с xp на 10, ну кроме «а новая версия нашего софта больше не работает на xp и win7, а старую мы выключаем». Не припомню выкриков «Нам нужна фича 1234, срочно выпустите новую ОС»

Кто вам мешает сейчас пользоваться 97-м офисом?

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

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

И если лично вы её не видите, то её нет?

Но вобще, если 97 может открывать современные документы и там не будет ехать верстка, то я прям горд за него=)

Подождите, а разве поддержка новых форматов это не новая фича?

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

Кто-то заставляет кого-то покупать софт или вообще в принципе им пользоваться? Это для меня ново…
Подождите, а разве поддержка новых форматов это не новая фича?

А какие новые форматы открывает последний офис? Те самые с х в конце, которые он сам и придумал?
Ну там вроде бы всё-таки немного побольше вещей добавилось. Но даже если и допустить что был просто добавлен новый формат, то добавлен он был не просто так. Даже если 99% простых пользователей какой-то разницы кроме добавления х в конце не заметили.

Для себя могу сказать что docx гораздо приятнее в использовании когда ты работаешь с ним через API. То есть получается практически для любой автоматизации.
Подождите, а разве поддержка новых форматов это не новая фича?

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

Ты вот помнишь выкрики пользователей. «Хотим новые форматы, не совместимые с офис97!», я нет. Да даже «Хотим новые форматы!» не помню такого, пользовались тем что было.

И если лично вы её не видите, то её нет?

Мне кажется было бы конструктивней говорить не «Ты не видишь, а он есть», а на вскидку некоторые киллер фичи привести, которые люди просили и которые нельзя было принципиально впилить в XP. Диалог был бы полезней.

Кто-то заставляет кого-то покупать софт или вообще в принципе им пользоваться

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

так то и у молока в пакете объемом 870мл есть киллер фича, его нести легче, чем вон тот пакет конкурента — 1л, но врядли кто просил делать такой даунсайзинг.

P.S. к вопросу о «заставляют», где кстати купить office97, который условно меня устраивает?
Ты вот помнишь выкрики пользователей. «Хотим новые форматы, не совместимые с офис97!», я нет. Да даже «Хотим новые форматы!» не помню такого, пользовались тем что было.

Я мало того что их помню, я даже был одним из тех пользователей, которыe требовали эти самые новые форматы. То естъ любые форматы с котoрыми можно нормально работать через API.

Мне кажется было бы конструктивней говорить не «Ты не видишь, а он есть», а на вскидку некоторые киллер фичи привести, которые люди просили и которые нельзя было принципиально впилить в XP

Ну он например банально не поддерживал стакание иконок/программ на своём таскбаре. И чтобы это добавить надо было переделывать всю систему таскабара. А чтобы её переделывать это надо было уже кучу чего переделывать. С аккаунтами пользователей и правами у него была беда совсем и там всё тоже надо было глобально переделывать. С бэкапом. С UI у него была куча проблем. Полупрозрачные окошки и всё в этом роде. Да и вообще его тогда сравнивали с «яблочными» осями и он в сравнении часто проигрывал, а люди хотели себе часть фич оттуда.

И это только то что я могу вот так сразу припомнить…
UFO just landed and posted this here
Ну может я что-то уже и неправильно помню. Но вот бэкап там был отвратительный. То есть точнее как бэкап он работал более-менее, а вот трансфернуть свой аккаунт куда-то ещё было напряжно.

С правами и юзерами там однозначно была беда. Может не для домашнего пользования, но для корпоративного уж точно. И вещи вроде «щас вам админ всё быстро настроит и установит по ремоту» там тоже нормально не работали. Если вообще работали.
UFO just landed and posted this here
И как сейчас это изменилось в десятке?

Под капот не лез, но по моему уже с висты или даже с семёрки перенос юзера с компа на комп у меня работате без проблем. На ХP это каждый раз были танцы с бубном.

А для них что вообще изменилось? При нормальной настройке пользователь как работал под ограниченной учёткой, так и работает.

У вас нет разбития на домены, юзергруппы и так далее? И нет разного доступа к разным вещам для разных групп пользователей? Ну и для прикола можете попытаться имплементировать Windows Аuthentication модуль для всего этого дела для ваших программ/сервисов под XP. Думаете выучите много новых интересных ругательств.
UFO just landed and posted this here
> Я мало того что их помню, я даже был одним из тех пользователей, которыe требовали эти самые новые форматы. То естъ любые форматы с котoрыми можно нормально работать через API.

Если API это COM самого ворда/что там ещё в офисе, то как старые форматы могли мешать работе?
Docx это открытый стандартизированный формат. Вы с ним по идее можете работать напрямую. Это грубо говоря просто XML и CSS в архиве.

А с doc надо было работать через API и это было дико криво. Поэтому куча народа хотели хотя бы нормальный API.
Если бы они сделали новый directX под семёрку, до сих пор бы на ней сидел. Только ради поддержки новых игр поменял домашнюю систему. Хотя в целом к десятке претензий нет, но да, мне обновление ради обновления не было нужно, это была хорошая система.
UFO just landed and posted this here
Некоторые игры под 12 за счёт оптимизации просто лучше работают, та же цивилизация, например. Хотя да, сейчас это не такой болезненный удар, как с XP, когда начали появляться игры на DX10.
UFO just landed and posted this here

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


Да и вообще, есть прекрасный пример с флешем, который таки тормозил.

Флеш умер совсем не из-за того, что тормозил. По сравнению с тогдашным js он просто летал.
Моё субъективное мнение по данному вопросу сильно отличается от того что написано в статье. Источник проблемы состоит в том, что «потребителю» нужно красиво, а не быстро. Вот эта «красота» сжирает все мощности. На заре тырнета на страницах картинки не часто вставляли, а сейчас на лево и на право видеоролики вставляют. Переходите на терминалы с текстовыми консолями и будет вам скорость.
Проблема бездумного написания кода конечно тоже есть, но причина, по которой железо не поспевает за софтом, не в этом.
UFO just landed and posted this here
Аська перестала устраивать когда в официальном клиенте всё стало завалено рекламой, а альтернативные клиенты регулярно отваливались из-за намеренных изменений в протоколе для борьбы с этими клиентами, и нужно было ждать когда поправят плагин.
Миранда это конструктор на любителя, слишком много возьни.
Скайп перестал устраивать после продажи в Майкрософт, похорон всех изначальных технологий типа п2п, и опять же полезли реклама, тормоза.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Не жирное, а бодипозитивное.
Нельзя ругать ПО за то что оно ест слишком много ресурсов.
ПО не плохое, оно с индивидуальными особенностями.
Бодипозитивное ПО с особенностями не должно стоит дешевле, иначе это угнетение.
Нельзя выбирать ПО по отсутствию особенностей и требованиям к ресурсам.
Вопрос об ожирении ПО чем-то похож на вопрос о строительстве человейников за МКАДом.
Берут — потому что а) никто не предлагает другое за те же деньги б) государство никак не регулирует этот вопрос.
UFO just landed and posted this here
Хех, много шума, много споров :)
Я может не прав, но статья не о настоящем, пока железо со скрипом, но справляется
Вход в нашу индустрию для новичков прост и недавние новички создают давление на систему своими предпочтениями, выбирая одни инструменты вместо других.
Статья скорее о будущем, о том что «ребята, время халявы кончается, будущее где придется над кодом думать много и оптимизировать уже за следующей дверью, воспользуйтесь этим знанием и прокачайтесь»
Я давненько работаю в индустрии где ASIC это не матерное слово, а насущная необходимость, где код вынуждены вылизывать и клиентов со временем у таких компаний все больше и больше. Нет больше запросов — сделайте мне из говна и палок, все больше — «сделайте так чтоб на этом железе помимо вот этого еще поместился лунапарк и продажные женщины»
Еще 10 лет назад картина была принципиально другой.
Гении из Интела и АМД пока не справляются с тем что производит индустрия софта и тенденция такова, что ситуация становится все хуже.
Сейчас у многих людей в индстрии есть уникальный шанс — тренд понятен и нужно успеть подготовиться, а дальше дело каждого — адаптироваться или надеяться на лучшее. Кто прав покажет время.
Гении из Интела и АМД пока не справляются с тем что производит индустрия софта
Гении из Интела и АМД справляются на отлично, они не виноваты в том, что индустрия софта зачастую производит откровенный отстой.
В слове гении не было и тени иронии, они реальные молодцы и вытягивали эту индустрию уже не 1 десятилетие и то что сейчас идет пробуксовка винить их не в моей компетенции.
+ векторизация
+ интристики AVX
А AVX — это не векторизация?

Вероятно, имеется в виду автовекторизация, которую может сделать компилятор.

Например, Никола Дуза написал простое приложение для ведения списка дел. Оно работает в вашем браузере с HTML и Javascript. Как вы думаете, сколько зависимостей оно использовало? 13 000. Тринадцать. Тысяч. Пруф.
Почему людям вообще приходит в голову для таких приложений подключать вообще какие-то зависимости? Меня выворачивает от самой идеи этого. Такое должно быть написано руками на ванилле.
Вообще говоря ускорение в 1000 раз — это часто вообще не проблема для многих бизнес-задач (и часто на это даже не требуется много времени). Сам пару раз ускорял в несколько тысяч раз некоторые долгие задачи.

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

И часто почему-то перформанс ассоциируется со скалабилити. Нет, господа, скорость не всегда подразумевает 1000 серверов.
Сраный драйвер для звуковой карты — 1.5 Гб, это как вообще?
И таких примеров тьма, сорри накипело.

Возможно, этот пакет содержит на всякий случай драйвера для всех звуковых карт производителя за все времена, нескучный графический интерфейс и демо во FLAC. Ах да, и shitware тоже может присутствовать. А гигабайты никто из маркетологов не считает.

ИМХО, там где это реально нужно, код и без того вылизывается и оптимизируется, а в подавляющем количестве случаев это просто не нужно, ну отработает какой-то метод не за пол секунды, а за одну тысячную, если он вызывается раз в день этого никто даже не заметит, какой смысл тратить время и деньги на его оптимизацию.
Сейчас основа коммерческого успеха — это быстрый выход на рынок с MVP, желательно, на дешёвых программистах. Производительность, безопасность и ресурсоёмкость уходят на второй план. Ситуация длится не первый код и в общем-то всех устраивает, кроме тех, кто не хочет обновлять железо, и принципиальных бородачей. Что остаётся делать: улучшать компиляторы, чтобы лишнего не пихали, и ядра ОС, чтобы могли сопровождать приложение с момента установки и оптимизировать по живому, как это планировалось в Clang, когда тот был диссертацией. Оптимальный код всё равно в основной массе писать не будут.
На свете очень мало ресурсоёмких задач, требующих именно последовательного выполнения одним процессором. Где стоит задача ресурсоёмкости, прекрасно справится облако из 100500 примитивных типа-компьютеров. Причём все эти мини-компьютеры ещё и ценят своё время и силы, выбирая себе задачи с учётом вознаграждения. Именно так работают нейроны человеческого мозга. Задача о перемножении матриц похожа на то как если бы кучу народа посадили на фабрику за одинаковые станки. Есть более интересные ресурсоёмкие задачи.
В некотором смысле есть утилиты для ускорения
Например обфускатор от РейдГейта — не только запутывает код но и переводит «что то» на ассемблер — тем самым ускоряя работу дотнетовского экзешника
Вот интересно, в полупроводниковом мире набирает популярность «темный кремний», то есть обмен числа транзисторов на производительность. Будет ли происходить обмен размера программы на производительность? Кажется, что чем программа меньше, тем она и быстрее? Всегда ли это так? Интуитивно кажется что да, размер кеша процессора невелик, а различие во времени доступа иллюстрируется примерно так:

Если вы процессор, то свои регистры вы видите как желтые наклейки на столе, повернул голову и прочитал.
Кеш первого уровня выглядит примерно как взять со стола папочку, достать файлики, пролистать и выбрать из сотен нужный лист, на листе выбрать из тысячи строк нужную.
Кеш второго уровня заставляет вас встать и лойти до книжного шкафа, надо найти полку, книжку, страницу, прочитать, запомнить, поставить обратно и вернуться.
Кеш третьего уровня это как спуститься в подвал, где надо подвигать сундуки, открывать их, доставая и убирая книжки по очереди…
Оперативная память подобна городской библиотеке, пара остановок на автобусе, библиотекарь нам поищет требуемое и принесет. Но надо посидеть и подождать.
SSD накопитель подобен курьерской службе, примерно в течении суток-двух он доставит в библиотеку нужную книжку, далее в библиотеку надо сходить.
HDD диск подобен почте РФ, недели, а иногда и месяцы, надо ждать пока в библиотеку приедет нужная нам книжка.

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

Быть может, когда нибудь машинный код нам будет писать нейросеть, по принципу состязательности — сделать то же самое, но быстрее.

Сейчас разница между регистрами и L1-кэшем, между кэшами и RAM не так уж велика — единицы и десятки крат, насколько я помню. SSD тоже приближаются к RAM, по крайней мере к RAM прошлых лет.


Быть может, когда нибудь машинный код нам будет писать нейросеть, по принципу состязательности — сделать то же самое, но быстрее.

Нечто подобное достигается с помощью profile-guided optimization или даже jit — код оптимизируется под требуемую архитектуру на основе замеров производительности. Хотя я не слышал, чтобы компилятор сам проводил бенчмарки вариантов кода и брал лучший.

UFO just landed and posted this here
Увы, примерная скорость доступа в RAM сейчас порядка 50нс, к SSD NVME диску 0.5mс. Примерно в 10000 раз медленнее. Вносят заблуждение скорости передачи данных, это как увеличив число вагонов в поезде, мы увеличиваем скорость перевозки людей, но не отдельного человека.
к SSD NVME диску 0.5mс

Видел значения latency 20мкс. Реальную задержку случайного доступа не замерял.


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

В ряде случаев задержки не так важны. Например, в сценариях с последовательным доступом. Часть задержек случайного доступа нивелируется кэшированием (если есть много попаданий в кэш).

По задержкам разница очень велика. По пропускной способности L1 часто делают многопортовым, то есть опять разница в разы.
UFO just landed and posted this here
Быть может, когда нибудь машинный код нам будет писать нейросеть, по принципу состязательности — сделать то же самое, но быстрее.

Зачем писать код человеку — понятно. Чтобы потом код сам работал и зарплату не просил.
А зачем нейросети писать код? Если она сразу сама может задачу решить.
Сразу два ответа на такой простой вопрос.

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

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

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

Пример с питоном и матрицами не особо корректен. O(N^3) можно написать и на C и выйдет та же дрянь. Нормальные программисты знают, что при больших N N^3 и N^2 в программе быть не должно.
Предложите свой метод умножения матриц быстрее O(N^2) и войдёте в историю математики :)
Все существующие быстрые алгоритмы имеют асимптотику примерно от 2.4 до 2.8, причем методы у нижней границы мало применимы на практике из-за огромного константного множителя.
Стоимость. Сроки разработки.
Почти моментальный (а по меркам прошлого века — моментальный) расцвет Google Play и App Store с их миллионами программ.

Компьютер в прошлом веке был роскошью. Поэтому стоимость ПО в тысячи долларов особо не смущала.

Всё меняется. И много меняется не по закону Мура, не количественно. А качественно.
В современных системах тормозит прежде всего сеть и диски.
Но не процессор.
Если не пользоваться кэшем, из-за которого диски тормозят, резко кончится память.
Если не пользоваться кэшем, из-за которого диски тормозят, резко кончится память.

Оперативная?
Давно такое видели лично?
Недавно. Считал хэши всех файлов для дедупликации, запретил хрому юзать кэш, внезапно кончилась память :)
Недавно. Считал хэши всех файлов для дедупликации, запретил хрому юзать кэш, внезапно кончилась память :)

Ну то есть вы заведомо включили режим приводящей к этой проблеме?
Ну не заведомо. Всё-таки когда с кэшем занято 4 гига оперативки, а без кэша 12 кончаются — это несколько неожиданно.
Оперативная?
Давно такое видели лично?

Постоянно. Вот на текущем лаптопе:


$ free
              total        used        free      shared  buff/cache   available
Mem:        8014216     6960236      127192      605648      926788      187924
Swap:      24784888     8369108    16415780

Своп нарощен — раньше когда он был 8GB, регулярно заканчивался. Linux почему-то в этом случае неспособен даже быстро убить кого-то по OOM, впадая в позу вечного поиска смысла жизни с выжиранием процессора. Ждал полчаса, надоело.
Теперь с 24GB — своп регулярно подскакивает до 12GB, если начинает уж очень тормозить — перезапускаю кого-то.
Основные прожоры — firefox (по сумме) и почему-то Telegram (зачем ему столько?)


Предупреждая вопросы — c хромом ещё хуже, на моих шаблонах использования он ещё прожорливее, раза в два.

UFO just landed and posted this here
Может проблема тут? 8ГБ ни о чём сейчас.

Да, я знаю, и сам такое постоянно говорю. На десктоп меньше 32GB сейчас не ставлю. Десктопы я всегда сам себе комплектую, стандартные комплекты это безумие непонятно под какого потребителя. Но на лаптоп… поставщики железа уже много лет дают такие стандартные конфигурации, где RAM занижен вдвое от адеквата для таких характеристик, а если смотреть модели с 16GB в коробке и расширением минимум до 32, то у них и другие характеристики сразу выше, и цена. Это походный лаптоп, который 500$ и не сильно страшно даже случайно убить, расширять память ему не очень хотелось.

8ГБ ни о чём сейчас.
Не впервые вижу это заявление. Вопрос простой — а сфига ли? Почему, чтобы пользоваться браузером, музыкальным проигрывателем и офисным редактором (типовое использование домашнего ПК), мне резко перестало хватать 1-2-4 гиг? Это или веб не туда развивается, или браузеры.

Объём памяти сильно зависит от шаблонов использования. Если не запускать много задач одновременно, 1-2-4 ГБ, возможно, хватит.


Веб развивается в сторону ускорения и усложнения веб-приложений. JIT, кэши, нескучные градиенты — это всё жрёт либо CPU, либо память. Т.к. увеличение объёма памяти более дёшево, чем увеличение скорости CPU, разработчики, скажем так, не стесняются агрессивно использовать все доступные объёмы памяти в погоне за скоростью.

Из личного опыта: гига уже не хватает вообще никак, для использования браузера на 3-5 вкладок с 2 гигами надо обвешаться баннерорезками по максимуму. Жаль, а я так любил EeePC.
Т.к. увеличение объёма памяти более дёшево, чем увеличение скорости CPU

Это в каком смысле?
Цены на память не падают с 2012 года, хотя процессоры в пересчёте на доллар, считаем, ускорились раза в 3 минимум (а с учётом инфляции и все 5).
Да, пока полно наглых прожор, которые считают, что они одни в системе и можно отхватить пару гигабайт просто так, но скоро их перестанут покупать.


Если не запускать много задач одновременно, 1-2-4 ГБ, возможно, хватит.

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


не стесняются агрессивно использовать все доступные объёмы памяти в погоне за скоростью.

Чувствуется. Ну скоро начнут получать по рыжим мордам.

Это в каком смысле?

Вы легко можете добавить память (хм, если материнская плата имеет свободные слоты), но процессор, работающий (в одном потоке) на 3х скорости от современных, так просто не купить.


Почему "не запускать много задач одновременно"?

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

Вы легко можете добавить память (хм, если материнская плата имеет свободные слоты)

Да при чём тут слоты. Вот посмотрите на типовой лаптоп с поставкой сколько угодно RAM "из коробки" — сколько у него материнка тянет в пределе? В типовом варианте — всего лишь в 2 раза больше от этого значения. Это при том, что вообще адекватная конфигурация, соответствующая всему остальному железу, должна иметь как раз минимум вдвое RAM. А теперь возьмите любимый сайт — агрегатор цен разных магазинов и попробуйте выставить не только текущий объём RAM, но и предельный — сколько моделей отсеется, для которых даже вендоры не публикуют этот максимальный объём, и сколько останется?


Так что пусть оно даже формально дёшево (сколько там например 16GB DDR4 лаптопной — я вижу цены типа 80$), но вам поставили жёсткое ограничение — и страдайте себе в тряпочку. И сколько будет стоить переход на модель, где можно ставить больше? Там сразу прыжки цены по 200-300$ — это сильно больше, чем цена перехода, например, i3->i5.


Вы имеете в виду, "Почему бы не запускать задач больше, чем помещается в оперативной памяти?"?

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


Так ведь своп медленнее оперативной памяти, и активное его использование — это довольно неудобно (медленно).

Всё равно это лучше, чем рекомендуемый вами однозадачный режим.


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

Извините, я в это "мышки, станьте ёжиками" не играю — тем более, когда за счёт большого свопа эти проблемы тривиально решаются. Вот тут уж точно я предпочту отщипнуть, например, 20GB от 128GB SSD, но получить устойчивую работу с плавным ухудшением количественных показателей, а не непредвиденно-рывочным убийством рабочих программ.

Вы легко можете добавить память (хм, если материнская плата имеет свободные слоты)


Да при чём тут слоты. Вот посмотрите на типовой лаптоп с поставкой сколько угодно RAM «из коробки» — сколько у него материнка тянет в пределе? В типовом варианте — всего лишь в 2 раза больше от этого значения. Это при том, что вообще адекватная конфигурация, соответствующая всему остальному железу, должна иметь как раз минимум вдвое RAM. А теперь возьмите любимый сайт — агрегатор цен разных магазинов и попробуйте выставить не только текущий объём RAM, но и предельный — сколько моделей отсеется, для которых даже вендоры не публикуют этот максимальный объём, и сколько останется?


Давайте отталкиваться от применений.

Если вы говорите о типовом ноутбуке, то берите и типового пользователя.

Типовой 8 Г. 4 Г — это уже крайне бюджетный вариант, точно не для комфортной работы на нём.

Для подавляющего большинства типовых пользователей — ноутбук используется для веб-серфинга, просмотра фильмов HD, не QHD, да как печатная машинка, еще как игровой компьютер.

С всеми задачами кроме игр задачей прекрасно справляется ноут с 8 Г.

Игры… Тут даже не в памяти дело, а в охлаждении, чего подавляющее большинство ноутов (даже игровых) не имеют.

Посему те нетребовательные к видеопроцессору игры, что тянет типовой ноут, им и 16 Г нормально, да и 8 Г терпимо, если видеокарта дискретная. Ну да, придется браузер закрыть.

Вот для комфортной работы, если тебе нужно что-то там запускать еще, Фотошоп, виртуальные машины, браузер, IDE и еще пару программ — тут да, нужно бы побольше.

Но это совсем не типовое использование (для большинства людей), посему не нужно под это применение рассматривать типовой ноутбук.

8ГБ ни о чём сейчас.


Не впервые вижу это заявление. Вопрос простой — а сфига ли? Почему, чтобы пользоваться браузером, музыкальным проигрывателем и офисным редактором (типовое использование домашнего ПК), мне резко перестало хватать 1-2-4 гиг? Это или веб не туда развивается, или браузеры.


А какая разница кто виноват, если лично вы ничего изменить не можете.
Еще лет 10 назад можно было себе позволять пользоваться браузерами на старых компактных движках…
Но сегодня вы, пожалуй, что и половину сайтов не увидите.
Оперативная?
Давно такое видели лично?

Постоянно. Вот на текущем лаптопе:

-> % free
total used free shared buff/cache available
Mem: 33480392 16317828 16933212 17720 229352 17028832
Swap: 0 0 0


Ну это же плохой пример.
Неужели вы не видите?

Где то лет 10 назад 8 Г это было круто.

Сейчас, ну… Будет комфортно только под браузер разве что. И то если вы не любитель по 50 вкладок держать.

UFO just landed and posted this here
Ну это же плохой пример.
Неужели вы не видите?


Что плохого то?


Это же не сервер?
GUI, desktop?

По нынешним временам нормальные показатели затрат памяти.
У меня прямо сейчас столько же занято. Всего лишь браузер и IDE открыты.

Это нормальные показатели затрат памяти.
Но вот общего количества памяти маловато. Если, конечно, компьютер не «всего лишь пишущая машинка».
UFO just landed and posted this here
32ГБ


Этого точно уже мало? Вон выше 8ГБ, да, маловато. А 32 вполне себе достаточно, занято обычно около половины, остальное бесконечные кеши.


32 — нормально, согласен.
Там в вашей цитате было про 8 Г, я спутал. Маловато — это 8 Г.

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


8ГБ — обычно этого вполне достаточно для браузера. Если ваши шаблоны использования требуют больше памяти, то тут (какая банальность...) либо менять шаблоны использования, либо покупать память. Данные не ужмутся магическим образом, даже если вы этого хотите. Увы, это так не работает.


P.S. сколько у вас открыто вкладок? >50? >100?

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

Про тормоза — источник в студию, пожалуйста. Отключение, очевидно, не метод.


Данные не ужмутся магическим образом, даже если вы этого хотите. Увы, это так не работает.

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


P.S. сколько у вас открыто вкладок? >50? >100?

150-300. Не все сразу активированы, но некоторые могут быть крайне тяжёлые (как видео или хабростатьи на дофига комментариев).

Про тормоза — источник в студию, пожалуйста. Отключение, очевидно, не метод.

Личный опыт. Можете проверить. Как только ram закончится, без свопа linux начнёт прибивать процессы, не задумываясь.


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

Опять же, из личного опыта: windows работает описанным вами образом (с увеличением потребления памяти тормозит сначала понемножку, потом сильно). Linux сначала не тормозит, а при начале активного своппинга тормозит адски. Я сталкивался с этой проблемой лет 10 назад, а воз и ныне там, и решил её для себя добавлением памяти.


но некоторые могут быть крайне тяжёлые (как видео или хабростатьи на дофига комментариев).

Это не "крайне тяжелые". Бывают страницы с 3D графикой, где только текстур — под гигабайт.


>P.S. сколько у вас открыто вкладок? >50? >100?
150-300.

Имхо, это сверх разумных пределов. Примерно как держать всю городскую библиотеку на офисном столе. Есть же механизм закладок. Но, вроде бы, были какие-то браузерные расширения для выгрузки неактивных вкладок...

Личный опыт. Можете проверить. Как только ram закончится, без свопа linux начнёт прибивать процессы, не задумываясь.

Тем более — даже проверять не буду. Мне не нужно убийство "не задумываясь", мне нужно, чтобы выживали по максимуму.


Linux сначала не тормозит, а при начале активного своппинга тормозит адски.

Я с ним почти 20 лет работаю, и такого нет.
12309 — да, проблема. Но не то, что вы пишете.


Это не "крайне тяжелые". Бывают страницы с 3D графикой, где только текстур — под гигабайт.

Спасибо за ещё один аргумент в пользу моего решения.


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

Дополнительные бессмысленные движения, в большинстве случаев.

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

FreeBSD

Я на ней много лет сидел дома (с 2001 по 2017)… но сумма остальных факторов пересилила в сторону Linux. Увы.

Вообще-то, если зависимости не являются бинарными библиотеками, а исходными текстами (реверанс в сторону Open Source), то оптимизирующий компилятор, теоретически, в состоянии сгенерировать код без неиспользуемого кода и работающий оптимально в рамках конкретной задачи. Другое дело, что межпроцедурная оптимизация сейчас находится в зачаточном уровне. Я даже не припомню копилятора, способно заметить, что какая-то функция везде вызывается с константным значением конкретного параметра и может быть оптимизирована именно для такого вызова.

Что же касается алгоритмической оптимизации кода, то, увы, мне приходится заниматься этим чуть-ли на ежедневной основе, но, преимущественно, на SQL. То что замечательно работает на гигабайтной БД разработчика не редко оказывается совершенно неудовлетворительным на терабайтной продуктивной БД.