<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>amarao</title>
  <link>https://amarao.dreamwidth.org/</link>
  <description>amarao - Dreamwidth Studios</description>
  <lastBuildDate>Wed, 17 Mar 2021 14:36:53 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>amarao</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/14605094/3740325</url>
    <title>amarao</title>
    <link>https://amarao.dreamwidth.org/</link>
    <width>100</width>
    <height>100</height>
  </image>

<item>
  <guid isPermaLink='true'>https://amarao.dreamwidth.org/6977.html</guid>
  <pubDate>Wed, 17 Mar 2021 14:36:53 GMT</pubDate>
  <title>фреймворк моей мечты</title>
  <link>https://amarao.dreamwidth.org/6977.html</link>
  <description>&lt;p&gt;Ну чем не ZX-Spectrum? Это целиком весь main.rs, который мигает разноцветным экраном. Обратите внимание на отсутствие event loop&apos;а и прочей ерунды.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use lib::EasyScreen;

fn main(){
    let screen = EasyScreen::new();
    let mut c = 0;
    loop{
        c+=1;
        screen.fill(c);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;https://github.com/amarao/equart/blob/switching_to_sdl/src/main.rs&lt;/p&gt;

&lt;p&gt;Рисование я начну писать после того, как доделаю всякие put_pixel и т.д. Алсо, не реализовать ли мне спектрумовский circle, который умел рисовать муары при углах больше 3 радиан?&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=amarao&amp;ditemid=6977&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://amarao.dreamwidth.org/6977.html</comments>
  <category>rust</category>
  <category>equart</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://amarao.dreamwidth.org/6661.html</guid>
  <pubDate>Tue, 16 Mar 2021 21:54:45 GMT</pubDate>
  <title>Абсолютный, грандиозный успех!</title>
  <link>https://amarao.dreamwidth.org/6661.html</link>
  <description>Итог:&lt;br /&gt;render fps: 2400 fps&lt;br /&gt;draw fps: 60 fps&lt;br /&gt;cpu use: 120%&lt;br /&gt;&lt;br /&gt;или&lt;br /&gt;&lt;br /&gt;render fps: 2100 fps&lt;br /&gt;draw fps: 310 fps&lt;br /&gt;cpu use: 200%&lt;br /&gt;&lt;br /&gt;lockless rendering. Один тред считает в цикле (тупо fill новым цветом, 100% CPU в треде), второй это читает и выводит, либо asap (310 fps, 100% CPU в треде), либо по vsync (60 fps, 20% CPU в треде).&lt;br /&gt;&lt;br /&gt;Сам код - я на питоне бы не смог написать короче. 55 строк вся библиотека (и то, я не уверен, что нужно руками clone делать). ... Уверен, вся библиотека 47 строк.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/amarao/equart/tree/switching_to_sdl/src&quot;&gt;https://github.com/amarao/equart/tree/switching_to_sdl/src&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Это просто счастье какое-то! Наконец-таки, у моего нового быстрого компьютера появился новый быстрый код!&lt;br /&gt;&lt;br /&gt;Ближайший роадмп: сделать инверсию (вынести SDL в тред, в main сделать только рисование), чтобы остался только init_graphics()...&lt;br /&gt;&lt;br /&gt;Заметим, этот же алгоритм идеально режется на параллельны треды. Каждому свой диапазон значений считать, а вывод - в общий буффер, и всё. Сравните это со старой версией (piston) - 1200+ строк, в которых ад и погибель с message&apos;ами и копированиями буферов.&lt;br /&gt;&lt;br /&gt;AtomicU32 вместе с Arc и Ordering::Relaxed звучит как читерство. Слишком просто, слишком волшебно, слишком легко.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=amarao&amp;ditemid=6661&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://amarao.dreamwidth.org/6661.html</comments>
  <category>equart</category>
  <category>rust</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://amarao.dreamwidth.org/6507.html</guid>
  <pubDate>Tue, 16 Mar 2021 14:51:29 GMT</pubDate>
  <title>Shared memory crazy fast</title>
  <link>https://amarao.dreamwidth.org/6507.html</link>
  <description>&lt;p&gt;Итог трёх дней моей возни с проблемой... Грандиозный успех safe and sound Rust&apos;а.&lt;/p&gt;

&lt;p&gt;Предистория: Я решил-таки сделать себе в программе рисования удобно, как было на zx-spectrum. То есть - программа рисования рисует себе в цикле, когда нужно точечки на экран ставит, точечки появляются на экране и остаются там пока программа не перезапишет. Никаких спецусилий, никаких event loop&apos;ов и т.д.&lt;/p&gt;

&lt;p&gt;Я хотел иметь то же самое в условиях оконного отображения. Оконное отображение - это event loop, надо реагировать на кнопочки и команды выхода. Если мы в цикле 10с считаем Солнышко Лиссажу, то мы 10с не реагируем на кнопки (aka зависли). Классические подходы: резать задачу на кусочки и перемежать их с ответом на event loop. Плюсы: относительно просто. Минусы - не ясно где резать, можно промахнуться с отправкой отрисованного и получить лаг на экране. Второй подход: соседний тред, который шлёт мелкие сообщения об обновлениях, основной тред рисует их на экране и отвечает за кнопки. Плюсы: если сообщения мелкие, практически гарантировано можно успеть ответить на event. Минусы: безумные накладные расходы на сообщения, проблема &quot;очереди&quot; (либо блокирующая, либо память течёт). В целом, если точки генерируются достаточно быстро, то снова та же проблема &quot;когда прекратить принимать сообщения и отправлять кадр на рендеринг&quot;?&lt;/p&gt;

&lt;p&gt;Моя идея: shared область памяти, в которую рисующий (считающий) тред пишет непрерывно (как хочет), а отображающий заглядывает для обновления текстуры. Схватил текстуру, отобразил в буффер, дальше библиотека SDL (да и любая другая) с режимом vsync вернёт управление как только будет отрисован кадр на экране. Ляпота, да?&lt;/p&gt;

&lt;p&gt;Только была пробелма: Rust не любит двойной доступ к памяти. Это тот самый danger quadrant, где конкуретный read и write.&lt;/p&gt;

&lt;p&gt;В процессе я нырнул глубоко в unsafe, прочитал много про pointer&apos;ы, в целом стал лучше понимать rust.&lt;/p&gt;

&lt;p&gt;итог: код без атомиков (я себе таки его написал прямо сейчас) не работает от слова вообще. Один тред пишет, второй наслаждается кешем процессора.&lt;/p&gt;

&lt;p&gt;Код с атомиками я сначала написал ужасно, с двойным указателем в один и тот же slice, отдаваемый в разные треды. unsafe, unsound and dangerous. Но он работал с офигенной скоростью в 13.5 ГБ/с (в режиме максимального congestion, когда один тред непрерывно меняет ячейку, а второй непрерывно её читает).&lt;/p&gt;

&lt;p&gt;Мне сказали &quot;переходи на arc&quot;. Для меня было открытием, что atomic позволяет сделать store для значения на non-mut ref, но я пошёл и написал. Стало порядка 9ГБ/с.&lt;/p&gt;

&lt;p&gt;И тут мне сказали про Arc&amp;lt;[AtomicU32]&amp;gt;. Это было безумие! У меня скорость стала ещё выше - 17.5ГБ/с. Я подозреваю, что это подозрительно близко к скорости моей памяти (25.5ГБ/с в один канал), и, возможно, ограничена скоростью IPI (который как раз кеши процессорам и инвалидирует).&lt;/p&gt;

&lt;p&gt;При этом в коде 0 unsafe!!! Я писаю кипятком.&lt;/p&gt;

&lt;p&gt;А ещё я проверил насколько проверка индексов всё тормозит. Ответ: мало тормозит. около 0.2с (с 9.9s на 10 прогонов полного цикла по u32 до 9.7s), и оно того не стоит.&lt;/p&gt;

&lt;p&gt;Фух. Сейчас я пойду приделывать это всё в свой основной проект. Подумав головой, я хочу сделать хитрое - засунуть рисовалку в дополнительный тред, а в основном оставить только код рисования.&lt;/p&gt;

&lt;p&gt;Чтобы было так:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn main(){
   let mut screen = Screen::new();
   for i in foo(){
      screen.put_pixel(x, y);
   }
   screen.done();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;А всякая SDL&apos;ная фигня была в этом самом screen::new().&lt;/p&gt;

&lt;p&gt;Это будет моя спектрумовская мечта. Берёшь и рисуешь, no thinking required. Я думаю, она много кому понравится как библиотека, хотя рисковать делать библиотеку пока я не готов (вероятнее всего, задумаюсь, по результатам успеха).&lt;/p&gt;

&lt;p&gt;Proof-of-concept: https://github.com/amarao/rust_dual/blob/arc/src/main.rs&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=amarao&amp;ditemid=6507&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://amarao.dreamwidth.org/6507.html</comments>
  <category>equart</category>
  <category>rust</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://amarao.dreamwidth.org/5861.html</guid>
  <pubDate>Sun, 14 Mar 2021 19:34:52 GMT</pubDate>
  <title>Я не уверен, что это хорошо, но меня прёт</title>
  <link>https://amarao.dreamwidth.org/5861.html</link>
  <description>&lt;pre&gt;&lt;code&gt;pub struct Screen{
    bytes: Vec&amp;lt;std::sync::atomic::AtomicU32&amp;gt;,
    width: u32,
    height: u32
}

impl Screen {
    pub fn copy_to_buffer&amp;lt;T&amp;gt;(&amp;amp;self, target: &amp;amp;mut [T]) -&amp;gt; Result&amp;lt;(), &amp;amp;&apos;static str&amp;gt;
    where T: bytemuck::Pod{
        if self.bytes.len() != target.len(){
            return Err(&quot;Size of target should be the same as source.&quot;)
        }
        let target_u32: &amp;amp;mut [u32] = bytemuck::cast_slice_mut(target);
        for idx in 0..self.bytes.len(){
            target_u32[idx] = self.bytes[idx].load(Relaxed);
        }
        Ok(())
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Так сказать, &quot;а что, так можно было&quot;?&lt;/p&gt;

&lt;p&gt;Если мне сейчас удастся малой кровью сделать его мутабельным (я верю в тебя, атомик) и пропихнуть между тредами, то это же просто праздник какой-то. У меня будет шаренная между тредами память с Relaxed моделью, в которой в одном треде я мирно делаю copy_to_buffer&lt;u8&gt; (для нужд рендеринга в текстуру), а в другом я в него делаю set_pixel/get_pixel, которые работают со скоростью mov для u32.&lt;/u8&gt;&lt;/p&gt;

&lt;p&gt;Что мне нужен атомик, меня уговорили на форуме, пригрозив, что без атомика компилятор может просто соптимизировать повторный доступ к непоменявшимся (с его точки зрения) данным.&lt;/p&gt;

&lt;p&gt;Бенчмарк показал, что запись в атомик в Relaxed занимает столько же времени, как и в обычный u32.&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=amarao&amp;ditemid=5861&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://amarao.dreamwidth.org/5861.html</comments>
  <category>rust</category>
  <category>equart</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://amarao.dreamwidth.org/1733.html</guid>
  <pubDate>Sat, 20 Feb 2021 22:08:57 GMT</pubDate>
  <title>отставить opengl</title>
  <link>https://amarao.dreamwidth.org/1733.html</link>
  <description>Я потыкался-потыкался и обнаружил, что есть же sdl, и её биндинги для rust&apos;а. А у него (неё?) есть window().into_canvas(), которая, в свою очередь, чистой воды 2D (то, что мне и нужно).&lt;br /&gt;&lt;br /&gt;Сейчас попытаюсь отбенчмаркать, может ли оно выдержать честные 60FPS в фулскрине с поточечным рисованием.&lt;br /&gt;Не выдерживает. 15 fps для FullHD, 8 fps для 2560x1440. Но, это worst case (draw_point для каждой точки экрана каждого кадра). Интересно, что в отличие от piston, оно супер-мега smooth, даже не смотря на эти 15.&lt;br /&gt;&lt;br /&gt;Моя реальная задача-то - не рисовать безумно быстро, а обновлять экран по мере надобности, и не страдать при этом из-за тяжёлой математики.&lt;br /&gt;&lt;br /&gt;Каждется, SDL - это реальное решение.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=amarao&amp;ditemid=1733&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://amarao.dreamwidth.org/1733.html</comments>
  <category>sdl</category>
  <category>equart</category>
  <category>2d</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://amarao.dreamwidth.org/984.html</guid>
  <pubDate>Mon, 15 Feb 2021 09:17:16 GMT</pubDate>
  <title>рисование из Rust</title>
  <link>https://amarao.dreamwidth.org/984.html</link>
  <description>Полировка QuadTree идёт, в принципе, люди с форума предложили использовать переменные сборки для управления кодом (сейчас у меня важные константы производительности просто константами в коде, но для некоторых значений может быть специфичный, более быстрый код).&lt;br /&gt;&lt;br /&gt;Но параллельно меня продолжает смущать глубокая некрасивость в районе piston&apos;а. Я добился на нём некоторой скорости рисования, но очень дорогой ценой. У меня идёт двойное копирование (кто-то это может назвать &quot;двойной буфферизацией&quot;), и мне оно не нравится. Ещё там шути что в районе текстур, и вообще, я чувствую себя слегка заброшенным, потому что документации по сущностям piston почти нет, там сквозят нюансы opengl, но они не полностью применимы.&lt;br /&gt;&lt;br /&gt;Так что я начинаю думать о переезде на что-то другое. wayland пока что звучит слишком радикально (я домашнюю машину ещё не перевёл), а вот vulkan можно считать состоявшимся и готовым к использованию. Мне хочется найти какой-то компромисс между понятностью того, как оно всё работает, и минимальным количеством низкоуровневых деталей с которыми надо возиться. Ну и быстро рисовать. Раньше на компьютере 10-летней давности у меня ещё были excuses по производительности; на новом их нет. Должно быть 2560x1440@60FPS без лагов и с плавной визуализацией прогресса (пока считаются медленные формулы).&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=amarao&amp;ditemid=984&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://amarao.dreamwidth.org/984.html</comments>
  <category>rust</category>
  <category>equart</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>
