Как стать автором
Обновить
1
0
Калмыков Юрий @Videoman

Пользователь

Отправить сообщение

На сколько я понял, номер шарда у них, это аналог версии баннера, а дальше делается просто CAS или Test And Set, как у многих атомарных операций - параллельно два обработчика меняют данные одно и того же баннера, но закоммитить изменения сможет только один из них, т.к. коммит выполнится только при условии, что версия баннера в базе совпадает с ожидаемой. Второй же обработчик увидит новый номер версии, проставленный первым, транзакция не пройдет и ему придется заново читать изменения из базы и снова пытаться повторить свои изменения.

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

Тема действительно интересная, обширная и сложная. Если брать изображения вообще в общем, как буфер кадра который может прийти откуда угодно, с любой аппаратной части, находится в разного типа памяти, то например в ffmpeg или библиотеках обработки видео и изображений всё становиться еще сложнее. Там у буфера кадра одновременно присутствует и align, и такие понятия как pitch и stride, причем все они могут иметь разные значения в общем случае:
align - это выравнивание начала строки в байтах. Необходимо для того, что бы строка могла быть обработана SIMD инструкциями, которые требуют выравнивания.
pitch - это выравнивания в пикселах (может быть горизонтальным и вертикальным). Необходимо тем или иным алгоритмам, которые работают блоками, например кодеки или специфические фильтры.
stride - это выравнивание строки в байтах. Необходимо как для работы SIMD, так и для менеджера памяти, который используется для хранения изображения (например в видеопамяти).
Также в зависимости от формата изображения могут иметь так называемые плоскости (цветовые компоненты), которые хранятся отдельно друг от друга и имеют собственные выравнивания. На практике всё это может быть не кратно друг другу, а каждый кодек имеет свои значения. В своё время пришлось плотно разбираться с этим и разрабатывать хитрые обертки, что бы сделать прозрачную передачу (без копирования):
кадр из оперативной памяти -> медиа семпл DirectShow -> ffmpeg кадр -> медиа семпл DirectShow -> кадр в оперативной памяти

Да, тоже становится грустно, почему люди не проверяют факты, которые сами же вскользь и указывают:
Wolf 3D - ray casting и DDA, ускорение относительно честного 3D происходит из-за того, что все расчеты происходят на 2-мерной карте, разделённой на прямоугольные блоки одинакового размера. Стены могут быть только кратны определённой сетке и вертикальными.
Duke Nukem 3D - portals, ускорение относительно честного 3D происходит за счет того, что отсечение происходит на 2-х мерной карте пошагово, от ближнего портала (выпуклое множество полигонов), потом следующие порталы, те, что потенциально могут быть видны из текущего и т.д. В отличие от BSP, все расчеты происходят в реальном времени, соответственно карта игры большими частями может меняться динамически.
Doom - BSP, ускорение относительно честного 3D происходит за счет того, что стационарные стены рисуются по порядку, от ближних к дальним по специальному дереву, опять же на 2-мерной карте. Стены также строго вертикальные, но уже под любым углом по оставшимся плоскостям.
Quake - честный 3D, но стационарные стены рисуются по 3-х мерному BSP на 3-х мерной карте. Отсюда ограничения, большая часть мира - статическая, т.к. BSP очень дорого рассчитывать в динамике.

Итого, из основных родоначальников жанра, только Wolf 3D использует ray casting.

Цитата:

в UTF-16 кодовая точка всегда использует 2 байта (16 бит)

И тут же противоречие:

Но максимальным значение 16-битного числа является 65535! Как представляются большие числа в UTF-16? Для этого используется концепция суррогатной пары (surrogate pair)

Вывод: В UTF-16 кодовая точка, также как и в UTF-8, занимает максимум 4 байта.

Моё замечание относится к тому, что хотя в общем идея чисел с плавающей точкой объяснена, только вот в IEEE-754 экспонента (e) - это показатель степени по основанию 2, а не по основанию 10, как в статье. Т.е. не 10^e, а 2^e.

10 - или я не понял вопроса ?!

Всё хорошо в объяснении, только вот экспонента (порядок) это степень двойки, а не десятки. Неплохо бы было объяснить и это момент.

Мне кажется, что в современном С++ это можно сделать на уровне библиотеки и работать с такими числами почти как с встроенными. Вот моя попытка написать такое для целых - Simple long integer math library for C++. Посмотрите, может подойдет.
Из того, что вам нужно, там нет точности до бита и динамического изменения размера, так как я пока не знаю как выполнить эти требования и при этом быть сравнимым по эффективности с встроенными типами.

constexpr auto uo = 03766713523035452062041773345651416625031020_ui128;  // octal unsigned integer
constexpr auto ud = 338770000845734292534325025077361652240_ui128;       // decimal unsigned integer
constexpr auto uh = 0xfedcba9876543210fedcba9876543210_ui128;            // hexadecimal unsigned integer
constexpr auto io = -03766713523035452062041773345651416625031020_si128; // octal signed integer
constexpr auto id = -338770000845734292534325025077361652240_si128;      // decimal signed integer
constexpr auto ih = -0xfedcba9876543210fedcba9876543210_si128;           // hexadecimal signed integer

constexpr auto u = 0xfedcba98'76543210'fedcba98'76543210_ui128;          // hexadecimal unsigned integer

Так ведь _pascal calling conversion давно уже устарело и не рекомендуется к использованию. Это смотря где определение.
https://learn.microsoft.com/en-us/cpp/cpp/obsolete-calling-conventions?view=msvc-170

У меня в 2022 Студии, например, вот такое определение.
У меня в 2022 Студии, например, вот такое определение.

В общем это всё дела уже минувших дней и неактуально сегодня.

Ну я как-раз про это и говорю, откуда слухи - от не разобравшихся преподов. Увидели слово pascal - значит паскаль, однозначно!
PASCAL тут - это define __stdcall

Да, всё верно. Тип вызова pascal отличается от stdcall противоположным порядком проталкивания аргументов. Я не хотел вдаваться в дебри различных типов вызовов, тем более, что сейчас в x64 многие из них уже не актуальны и унифицированы. Я лишь хотел этим проиллюстрировать откуда могли взяться слухи, что Windows писался на Pascal-е и что разработчикам на конференции задавали уже этот вопрос. Ответ был - Windows писался на С.

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

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

Вроде фильтры совсем базовые и простые но есть одно замечание и один совет.
Замечание - gamma у вас работает неправильно. В нем граничные значения динамического диапазона [0, 255] (или [0.0, 1.0], если удобно) должны переходить сами в себя. Поэтому лучше сначала отнормировать значение яркости к [0.0, 1.0], а потом уже возводит в степень, затем обратно.
Совет - так как фильтры точечные и каждый канал обрабатывается независимо, лучше считать их в таблице для всех значений динамического диапазона, [0, 255] например, и уже потом брать оттуда. Во-первых, это сделает скорость любого фильтра независимой от размера изображения и от сложности самого фильтра. Во-вторых, можно применять сразу несколько фильтров к таблице, а потом обсчитывать уже каналы изображения по ней. Это еще увеличит скорость обработки.

Современные процессоры устроены совсем не так, как в 80-х. Здесь, мне кажется, нужны замеры - насколько это медленнее. Нельзя же производительность в этом случае линейно, по количеству команд, мерить.

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

В любом случае, если в архитектуре нет команды adc, то будут накладные расходы, но не большие.

constexpr bool addc(uint32_t& value1, uint32_t value2, bool carry) noexcept
{
    value1 += value2;
    bool carry_new = value1 < value2;
    value1 += carry;
    carry_new = carry_new || (value1 < uint32_t(carry));
    return carry_new;
}

Вот например выхлоп для RISC-V:

 add     a0, a0, a1
 sltu    a1, a0, a1
 add     a2, a2, a0
 sltu    a0, a2, a0
 or      a0, a0, a1
 add     a0, a0, a2

Выглядит очень не плохо, на мой взгляд.

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

value1 += value2;
bool carry = value1 < value2;

Он и так это без костылей оптимизирует: adc, sbb всякие, simd где может использует. О каких костылях речь ? На 32-х битной архитектуре 64-х битные целочисленные операции (long int) уже через вызовы отдельных функции выполняются, а как иначе, это костыли?

1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность