Дело не в редкости задачи, а в том, сколько раз в секунду эту задачу приходится выполнять. Конкретно эта задача - определение високосности года - если и требуется где-то, то не чаще одного раза за кадр, что явно недостаточно, чтобы заморачиваться ради сотни тактов.
Сначала я такой: О! Крутая оптимизация. Заберу в свою коллекцию.
А потом задумался. А в какой задаче требуется максимально быстро проверять год на високосность? Думал думал и так и не придумал. Единственное, что приходит в голову - преобразование даты в секунды при обработке каких-то массивов данных. Но всё равно мысль буксует, зачем это надо делать быстро и даже если очень надо, не быстрее ли сделать какой-то lookup в табличку с нужным диапазоном годов и сразу получать готовые вычисления.
Но в целом я одобряю подобные извращения над битовой арифметикой. Как разминка для ума, и, иногда оно бывает очень полезным с практической точки зрения
Это настолько критичный по времени код, что есть смысл проверять указатель перед вызовом free
Это прям какой-то дико извращенный алгоритм должен быть, чтоб вот прям надо много раз (буквально миллиарды) вызывать free и это надо делать быстро. Не. Программисту, который такое напишет, надо дать по рукам и заставить переписать код так, чтобы он вообще аллокации не использовал. Это даст намного больший выигрыш в скорости, нежели эта проверка.
Мои навыки программиста распространяются только на два языка: c++ и java. Я просто не в курсе, как обстоят дела с другими языками, может и ошибусь сейчас. Так вот, мне кажется, что никакой язык, который позволяет программисту писать многопоточный код, не "подложит мьютекс" автоматически. Ну то есть программист в любом случае должен как-то намекнуть компилятору/интерпретатору, что обращение к массиву будет из разных потоков. Повторюсь, возможно ошибаюсь, и такой язык существует. Ну а если нет, то и c++ и java вполне себе умеют "соломки подкладывать".
Мы делали свой прогресс бар (в одной старой игре) относительно честным. Немножко мухлевали в начале (до 15%) и в конце (после 85%). Работало это так: до 15% ползунок идет плавно в течении одной секунды. Далее честная загрузка с отображением реальных 0..100 в 15..85 на экране. Ну и с 85 до 100 тоже плавно за секунду. Даже несмотря на то, что загрузка шла на 2 секунды дольше, чем могла бы, визуально воспринималась бодрее.
Всё просто. Энергия и масса - это одно и то же. Эта формула буквально говорит нам: есть некое явление, которое мы измеряем в килограммах или в джоулях, а для пересчета из килограмм в джоули просто умножьте на константу (c^2)
Правильно ли я понял, что автор библиотеки реализовал виртуальные методы на шаблонах, со своей собственной vtable? И что в итоге получили? Усложнение синтаксиса. Ну да ладно, привыкнуть можно. К генерации столь-же оптимального кода, как сейчас на встроенном vtable тоже есть вопросы. Я бы не стал тут полагаться на магию оптимизатора. А вот умеет ли библиотека (не сильно ковырялся в ней) делать множественное виртуальное наследование? Да, это спорная фича и вызывает у многих вопросы, но в моей практике множественное виртуальное наследование довольно часто оказывается самым удобным, быстрым и красивым решением задачи.
Про virtual не понял. Вы хотите как в java, где все, что не помечено как final или private, по факту virtual? Или вообще vtable выпилить из языка? Если vtable убирать, то я против. Это очень мощная фича языка и я даже не представляю, как писать эффективный код без этого.
У многих компаний регулярные обновления с перестановкой кнопок интерфейса и одной новой фичей — бизнес-модель. Нужно как-то заставлять старых клиентов, которых всё и так устраивает, приносить денежку снова и снова. Да что там говорить, постоянные обновления — это и в реале сейчас тренд. Запланированное устаревание — из той же оперы.
> Одновременно настолько развитая и настолько отстающая по технологиям страна
Забавно, только что прочитал статью о тех, кто тормозит прогресс. А ведь Япония потому и развита, что максимально эффективно использует старые технологии, не отвлекаясь на апгрейды.
Я, в целях экономии ресурса ssd, сделал хардлинк папки с кэшами gradle на рам-диск. На рам-диске, естественно, fat32. Но в один прекрасный момент, после очередного обновления системы сборки, собственно сборка стала завершаться с непонятной ошибкой. В поисках решения, после долгого копания по форумам, кто-то где-то вскользь упомянул, что такая ошибка возникает, если студия стоит не на ntfs разделе (дело под виндой, да). Это оно, подумал я и, скрепя сердце, отказался от линка на рам-диск и fat32 для кэшей gradle. Прошел год или что-то около, и Android Studio, после очередного обновления, стала наглухо зависать при сборке с вероятностью >50%. Я думаю, это из-за того, что intermediates проекта я таки держал на рам-диске с fat32. Я даже багрепорт накатал, ответили, что проблема известная. Где-то месяц промучался и, о чудо, в очередном обновлении (bumblebee) всё починили, даже сборку с кэшем gradle на fat32. Ума не приложу, как можно умудриться сделать так хреново работу с файлами в кроссплатформенном (на минуточку) проекте, что всё висло на "неправильной" файловой системе.
Если перенести brave в папку не по умолчанию, то автообновление сразу ломается. Замена путей в реестре не помогает (да, речь о windows). Уж не знаю, зачем так жестко brave прибит гвоздями к program files.
А не говорят ли фейлы (о чем, собственно, статья) в попытке его измерить, что способ(ы) ошибочны? Я вообще сомневаюсь, что крутильные весы измеряют G. Просто все крутильные весы для измерения G плюс/минус показывают G, потому что те, что показывают что-то другое, просто отбраковываются. Эксперементаторы делают сотню опытов чтобы получить на 101-м наконец G хотя бы приблизительно. А если громко скажут, что G нихрена не получается, в научном обществе их заминусуют. Например, как этот коммент.
Значение G ни на что не влияет. Погодите минусовать, сейчас поясню.
Взгляните на формулу: F=G(m1*m2)/(r^2)
Предположим, что G на 10% больше (или меньше, не важно — просто другое), чем принято считать. Как это проверить? Никак. В пределах гравитационного колодца Земли проверить не выйдет — тут вторую массу всегда полагают нулевой и оперируют т.н. напряженностью гравитационного поля (то, которое у поверхности = 9.8mc^2), по умолчанию и без какого либо объяснения считая, что пробное тело никак на него не влияет и является точечным. Если проверять через небесную механику, то просто на соответствующую величину измените массу тел и формула сойдется с новой G. Никто ведь точно не знает массы звезд, планет и их спутников. Остается вариант с проверкой траекторий посылаемых аппаратов. Но опять же, масса аппарата известна, а масса планеты, вблизи которой наблюдается искривление траектории — нет. Напомню — мы выводим G из формулы и в такой ситуации масса планеты нам неизвестна. Текущее официальное значение G — просто выглядит правдоподобным, не более.
Сделаю осторожный вывод: гравитация вовсе не то чем кажется.
Ну да, в лоб без нужных знаний не выйдет. У меня была чудо-книжка, я ее где-то по почте заказывал и мне прислали, ныне утеряна, к сожалению. Так вот в той книжке были расписаны все команды Z80, включая недокументированные, и то, сколько они тактов выполняются. Вот я и высчитал такты, требуемые для записи/чтения на ленту. Нужо было с точностью до такта всё аккуратно сделать, иначе не заработает.
Ясно, издержки несоврешенства технологии на этапе проектирования. Немного выиграли в аппаратной части, но проиграли на круг в общей производительности в играх.
если делать таблицу Y -> Addr, то это целых 384 байта. Это охренеть как много для спектрума, но, видимо многие так делали. А куда деваться.
К примеру, для кода и данных игры максимум доступной памяти — 42240 байт. Ну экзотику, когда код в видеопамяти и закрыт аттрибутами, я не рассматриваю. Так делали редко. Если использовать backbuffer, да потратиться на такие вот таблицы (например, еще обязательно нужна была таблица переходов с прерывания по таймеру 50 раз в секунду — 256 байт, ну или там, таблица синусов, таблица умножений, таблица квадратных корней, много всяких таблиц), то на графику и код оставалось с гулькин нос. Впрочем, было интересно.
Так устроена видеопамять у спектрума. Чем руководствовался ее разработчик, сказать сложно. Но вряд ли это были соображения производительности.
Устроена так: 32 байта на горизонтальную линию — 256 бит. Каждые следующие 32 байта на экране отображались ниже на 8 пикселей. И так восмь раз. Затем вторая скан линия и снова 8 раз через 8 пикселей вниз. Ровно 2kb на блок, занимающий ровно одну треть экрана. И таких блоков 3 штуки. Итого 6144 байта. Это была битовая матрица. Далее идут 768 байт аттрибутов, каждый байт отвечал за матрицу 8x8 пикселей, указывая, в какой цвет красить нули, а в какой единицы на битовом поле.
Очень заморочено. В ПЗУ есть кусок кода, который вычисляет в этой схеме адрес следующего байта относительно произвольного, который на экране расположен на один пиксель ниже. Как сейчас помню, эта операция занимала 191 такт. Сделать это быстрее мне тогда не удалось. Между тем такая операция очень важна при рисовании спрайтов в произвольной Y координате в играх. Вобщем, мы крутились как могли.
Из моего коммента ниже видно, что между полупериодами сигнала логического нуля 855 тактов. Я щас не помню кнкретных цифр, но на саму загрузку требуется порядка 50 тактов на каждом полупериоде. Остальные 800 процессор просто впустую ожидает изменения бита сигнала с ленты на порту. Т.е. есть где развернуться. Я в своё время сделал загрузчик, который картинку в процессе загрузки выдвигал с правого края экрана. Т.е. скролинг экрана во время загрузки. TF-COPY (если я правильно помню название) — программа для копирования, могла загружать в среднем до 60kb в память 48k байтового спектрума. Т.е. в процессе загрузки в реальном времени эта программа осуществляла сжатие. Вобщем, многие разработчики создавали свои загрузчики.
Дело не в редкости задачи, а в том, сколько раз в секунду эту задачу приходится выполнять. Конкретно эта задача - определение високосности года - если и требуется где-то, то не чаще одного раза за кадр, что явно недостаточно, чтобы заморачиваться ради сотни тактов.
Сначала я такой: О! Крутая оптимизация. Заберу в свою коллекцию.
А потом задумался. А в какой задаче требуется максимально быстро проверять год на високосность? Думал думал и так и не придумал. Единственное, что приходит в голову - преобразование даты в секунды при обработке каких-то массивов данных. Но всё равно мысль буксует, зачем это надо делать быстро и даже если очень надо, не быстрее ли сделать какой-то lookup в табличку с нужным диапазоном годов и сразу получать готовые вычисления.
Но в целом я одобряю подобные извращения над битовой арифметикой. Как разминка для ума, и, иногда оно бывает очень полезным с практической точки зрения
Сложно представить, для чего может потребоваться:
Вызов free с нулевым указателем в 99% случаев
Это настолько критичный по времени код, что есть смысл проверять указатель перед вызовом free
Это прям какой-то дико извращенный алгоритм должен быть, чтоб вот прям надо много раз (буквально миллиарды) вызывать free и это надо делать быстро. Не. Программисту, который такое напишет, надо дать по рукам и заставить переписать код так, чтобы он вообще аллокации не использовал. Это даст намного больший выигрыш в скорости, нежели эта проверка.
Мои навыки программиста распространяются только на два языка: c++ и java. Я просто не в курсе, как обстоят дела с другими языками, может и ошибусь сейчас. Так вот, мне кажется, что никакой язык, который позволяет программисту писать многопоточный код, не "подложит мьютекс" автоматически. Ну то есть программист в любом случае должен как-то намекнуть компилятору/интерпретатору, что обращение к массиву будет из разных потоков. Повторюсь, возможно ошибаюсь, и такой язык существует. Ну а если нет, то и c++ и java вполне себе умеют "соломки подкладывать".
Третий пример не сильно то и про c++. Писать и читать массив из разных потоков одновременно - будет плохо в любом языке.
Мы делали свой прогресс бар (в одной старой игре) относительно честным. Немножко мухлевали в начале (до 15%) и в конце (после 85%). Работало это так: до 15% ползунок идет плавно в течении одной секунды. Далее честная загрузка с отображением реальных 0..100 в 15..85 на экране. Ну и с 85 до 100 тоже плавно за секунду. Даже несмотря на то, что загрузка шла на 2 секунды дольше, чем могла бы, визуально воспринималась бодрее.
Всё просто. Энергия и масса - это одно и то же. Эта формула буквально говорит нам: есть некое явление, которое мы измеряем в килограммах или в джоулях, а для пересчета из килограмм в джоули просто умножьте на константу (c^2)
Правильно ли я понял, что автор библиотеки реализовал виртуальные методы на шаблонах, со своей собственной vtable? И что в итоге получили? Усложнение синтаксиса. Ну да ладно, привыкнуть можно. К генерации столь-же оптимального кода, как сейчас на встроенном vtable тоже есть вопросы. Я бы не стал тут полагаться на магию оптимизатора. А вот умеет ли библиотека (не сильно ковырялся в ней) делать множественное виртуальное наследование? Да, это спорная фича и вызывает у многих вопросы, но в моей практике множественное виртуальное наследование довольно часто оказывается самым удобным, быстрым и красивым решением задачи.
Так что все равно нет.
Про virtual не понял. Вы хотите как в java, где все, что не помечено как final или private, по факту virtual? Или вообще vtable выпилить из языка? Если vtable убирать, то я против. Это очень мощная фича языка и я даже не представляю, как писать эффективный код без этого.
Забавно, только что прочитал статью о тех, кто тормозит прогресс. А ведь Япония потому и развита, что максимально эффективно использует старые технологии, не отвлекаясь на апгрейды.
Я, в целях экономии ресурса ssd, сделал хардлинк папки с кэшами gradle на рам-диск. На рам-диске, естественно, fat32. Но в один прекрасный момент, после очередного обновления системы сборки, собственно сборка стала завершаться с непонятной ошибкой. В поисках решения, после долгого копания по форумам, кто-то где-то вскользь упомянул, что такая ошибка возникает, если студия стоит не на ntfs разделе (дело под виндой, да). Это оно, подумал я и, скрепя сердце, отказался от линка на рам-диск и fat32 для кэшей gradle. Прошел год или что-то около, и Android Studio, после очередного обновления, стала наглухо зависать при сборке с вероятностью >50%. Я думаю, это из-за того, что intermediates проекта я таки держал на рам-диске с fat32. Я даже багрепорт накатал, ответили, что проблема известная. Где-то месяц промучался и, о чудо, в очередном обновлении (bumblebee) всё починили, даже сборку с кэшем gradle на fat32. Ума не приложу, как можно умудриться сделать так хреново работу с файлами в кроссплатформенном (на минуточку) проекте, что всё висло на "неправильной" файловой системе.
Если перенести brave в папку не по умолчанию, то автообновление сразу ломается. Замена путей в реестре не помогает (да, речь о windows). Уж не знаю, зачем так жестко brave прибит гвоздями к program files.
Взгляните на формулу: F=G(m1*m2)/(r^2)
Предположим, что G на 10% больше (или меньше, не важно — просто другое), чем принято считать. Как это проверить? Никак. В пределах гравитационного колодца Земли проверить не выйдет — тут вторую массу всегда полагают нулевой и оперируют т.н. напряженностью гравитационного поля (то, которое у поверхности = 9.8mc^2), по умолчанию и без какого либо объяснения считая, что пробное тело никак на него не влияет и является точечным. Если проверять через небесную механику, то просто на соответствующую величину измените массу тел и формула сойдется с новой G. Никто ведь точно не знает массы звезд, планет и их спутников. Остается вариант с проверкой траекторий посылаемых аппаратов. Но опять же, масса аппарата известна, а масса планеты, вблизи которой наблюдается искривление траектории — нет. Напомню — мы выводим G из формулы и в такой ситуации масса планеты нам неизвестна. Текущее официальное значение G — просто выглядит правдоподобным, не более.
Сделаю осторожный вывод: гравитация вовсе не то чем кажется.
К примеру, для кода и данных игры максимум доступной памяти — 42240 байт. Ну экзотику, когда код в видеопамяти и закрыт аттрибутами, я не рассматриваю. Так делали редко. Если использовать backbuffer, да потратиться на такие вот таблицы (например, еще обязательно нужна была таблица переходов с прерывания по таймеру 50 раз в секунду — 256 байт, ну или там, таблица синусов, таблица умножений, таблица квадратных корней, много всяких таблиц), то на графику и код оставалось с гулькин нос. Впрочем, было интересно.
Устроена так: 32 байта на горизонтальную линию — 256 бит. Каждые следующие 32 байта на экране отображались ниже на 8 пикселей. И так восмь раз. Затем вторая скан линия и снова 8 раз через 8 пикселей вниз. Ровно 2kb на блок, занимающий ровно одну треть экрана. И таких блоков 3 штуки. Итого 6144 байта. Это была битовая матрица. Далее идут 768 байт аттрибутов, каждый байт отвечал за матрицу 8x8 пикселей, указывая, в какой цвет красить нули, а в какой единицы на битовом поле.
Очень заморочено. В ПЗУ есть кусок кода, который вычисляет в этой схеме адрес следующего байта относительно произвольного, который на экране расположен на один пиксель ниже. Как сейчас помню, эта операция занимала 191 такт. Сделать это быстрее мне тогда не удалось. Между тем такая операция очень важна при рисовании спрайтов в произвольной Y координате в играх. Вобщем, мы крутились как могли.