LINUX.ORG.RU

Си-шарп-ствуете ли вы?

 


0

1

Этот вопрос интересует преимущественно в контексте Unity\C#\Linux.
Есть ли у вас личный опыт в создании коммерческих проектов (игры, VR, AR) с использованием Unity\C# именно под Linux?
Как там с доставкой на различные платформы и стабильностью работы.
Заранее благодарен.



Последнее исправление: cross_platform (всего исправлений: 2)

Ответ на: комментарий от Kogrom

В проекте было очень много потоков, а доступ к общим данным был либо через стандартный lock, либо даже через самописный lock, который от стандартного ничем не отличался. Решалось ограничиванием числа потоков, а также заменой лока на монитор с таймаутом (по крайней мере монитор позволяет выяснить где слабое место)

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

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

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

Справедливости ради надо сказать, что если недопустимы задержки в десятки миллисекунд, то да, лучше C# не использовать. Но тут и Windows может миллисекунд 15 украсть. Linux крадёт меньше, особенно, если его специально настроить под задачу

Где? Десктопный планировщик семерки имеет шаг 1 миллисекунду, в поздних системах и вовсе переменный. Даже современный параллельный сборщик мусора в CLR на гигабайтных масштабах может давать заморозку под секунду. Да, выход есть — тормозить на десятки и сотни миллисекунд, но чаще.

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

Для исполнения такой программы рантайм ненужен. il2cpp как раз и позволяет проделать такой трюк

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

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

Для повышения же производительности даже в компилируемых языках применяют оптимизацию на основе данных предварительного профилирования

il2cpp усё «профилирует» при конвертировании intermediate language в с++.

cross_platform
() автор топика
Ответ на: комментарий от byko3y

Ты описываешь серверную разработку.

Для игр оно тоже справедливо. Если для персонажей выделять отдельные потоки, то эти потоки надо как-то синхронизировать. Когда персонажей много, то возрастает нагрузка на систему синхронизации. Я подозреваю, что в играх, которые виснут, именно выделяют по потоку на персонажа. Это более правдоподобная версия, чем GC. Могу ошибаться.

Это уже проблемы распределенных систем

Не совсем. В C# есть система сообщений. Один участок кода может кинуть сообщение в другой поток, а оттуда одновременно прилететь другое сообщение. Это близко к тому, что происходит в распределённых системах. Если объекты из разных потоков активно обмениваются сообщениями в обе стороны, то можем получить аналогичные зависания.

Где? Десктопный планировщик семерки имеет шаг 1 миллисекунду, в поздних системах и вовсе переменный.

Да, я измерял в XP и на одноядерном процессоре. Проверил на восьмёрке, core i5 таким кодом:

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono_literals;

int main()
{
    int counter = 0;
    for(int i = 0; i < 1000; ++i)
    {
        auto start = std::chrono::high_resolution_clock::now();
        std::this_thread::sleep_for(50ms);
        auto end = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double, std::milli> elapsed = end-start;
        std::chrono::milliseconds border{52};
        if(elapsed > border)
        {
            std::cout << i <<". Waited " << elapsed.count() << " ms" << std::endl;
            counter++;
        }
    }
    std::cout << counter << std::endl;
}

Вывело 127 превышений на 2 миллисекунды из 1000. Но больше 3 миллисекунд ошибок не было, да.

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

Возможно, ты прав. Остаётся загадкой, почему авторы OpenSim (который opensimulator.org) выбрали именно C#, а не Java. При том, что кроссплатформенность для них важна, линукс — одна из основных платформ, и когда я этим интересовался, на сайте присутствовали инструкции по сборке их творения под Mono для разных линукс-дистрибутивов.

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

Вот пример убогой игры

Это с какого перепугу она убогая? Это головоломка с TUI, нацеленная на достаточно специфическую аудиторию. Даже достаточно стильная.

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

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

il2cpp усё «профилирует» при конвертировании intermediate language в с++

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

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

Си-диез, нота на полтона выше Си.

Если уж название ноты написали по-русски, C - это нота До.

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

По гуглу и то бы толк был, по ютубу видео уроки от SumrachniyVasya777

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

Для игр оно тоже справедливо. Если для персонажей выделять отдельные потоки, то эти потоки надо как-то синхронизировать. Когда персонажей много, то возрастает нагрузка на систему синхронизации. Я подозреваю, что в играх, которые виснут, именно выделяют по потоку на персонажа. Это более правдоподобная версия, чем GC. Могу ошибаться

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

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

Это было во-первых. Во-вторых, CLR совсем вообще никак не защищает от дедлока или гонок, потому, учитывая более низкий порог вхождения, многопоточное программирование запрещено вне строго огороженных и проверенных механизмов, как правило.

Не совсем. В C# есть система сообщений

Нету. Я загуглил. Есть способы отправки сообщений в конкретных либах, но в общем нету. С четверки появился класс ConcurrentQueue, который может быть использован для реализации отправки сообщений, но с таким же успехом можно использовать для задачи много чего, что и применялось до появления ConcurrentQueue. Причем, механизм можно реализовать вполне себе грамотно, но все это неактуально в контексте игр и просто десктопного софта.

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

Нету. Я загуглил. Есть способы отправки сообщений в конкретных либах, но в общем нету.

Не знаю про что говорили про C#, но в F# встроена система сообщений без всяких либ, и любой класс/функция из F# может быть создан/вызвана из C#:

https://fsharpforfunandprofit.com/posts/concurrency-actor-model/

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

Нету. Я загуглил.

Я говорил об event (событие). Это, конечно не сообщение, а хитрый способ использовать функцию обратного вызова. Для Windows.Forms есть специальный паттерн InvokeRequired, позволяющий безопасно передать данные из неглавного потока в поток с GUI через event. Воспринимается как обмен сообщениями.

но все это неактуально в контексте игр и просто десктопного софта.

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

многопоточное программирование запрещено вне строго огороженных и проверенных механизмов

Это правильно. Но мне сейчас приходится вычищать от бесконечных потоков проекты, оставленные c#-программистами. И софт не только серверный. Я думал, что это общепринятая практика у них.

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

Для игр оно тоже справедливо. Если для персонажей выделять отдельные потоки, то эти потоки надо как-то синхронизировать. Когда персонажей много, то возрастает нагрузка на систему синхронизации. Я подозреваю, что в играх, которые виснут, именно выделяют по потоку на персонажа. Это более правдоподобная версия, чем GC. Могу ошибаться.

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

Aber ★★★★★
()

Си-шарп-ствуете ли вы?

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

Когда мне будет восемьдесят пять,
Когда начну я тапочки терять,
В бульоне размягчать кусочки хлеба,
Вязать излишне длинные шарфы,
Ходить, держась за стены и шкафы,
И долго-долго вглядываться в небо,
Когда все женское,
Что мне сейчас дано,
Истратится и станет все равно —
Уснуть, проснуться, или не проснуться.

Владимиp

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

Владимиру от Владимира

Когда мне будет тридцать пять,
Горшок держать перед кроватью.
Тогда начну я ОС писать,
На ЛОР-е часто флудить,
Нести на нем всякий бред,
И спорить, спорить, спорить,
И бегать часто в туалет,
И в нем Онегина читать,
И думать в нем о судьбах мира,
Тогда мне будет все равно, 
Зачем я вляпался в говно.

Владимир

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

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

ОС кривая/перегрузил проц/использовал блокирующую логику — сами по себе современные ОС такого поведения не создают.

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

Этот код в любом случае пишется не на C#. На шарпе дай бог чтобы с предзагруженными ресурсами всё работало.

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

Но мне сейчас приходится вычищать от бесконечных потоков проекты, оставленные c#-программистами. И софт не только серверный. Я думал, что это общепринятая практика у них

Например что? Какого рода софтина? Системная тулза, офисная, научная, морда к вебсервису?

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

Debugging and profiling применительно к il2cpp от создателей Unity:
https://www.youtube.com/watch?v=s7Ple1G83jc

Можно смотреть с 24:49. Performance and profiling.
Создатели Unity утвержают, что optimizing могЁм «сделать за вас на автомате». Мы, дескать, генерируем С++ код, и далее этот С++ код компилируется оптимизированным под конкретную платформу компилятором. Короче, есть средствА, которые работают и есть не просят.

А теперь главное. Всё вышеперечисленное не препятствует ковырянию ручками в сгенерированном С++ или где-то ещё.
Но -

  • на дворе 21 век
  • С++ я не знаю и знать не хочу
  • Я топлю за то, чтобы написать аккуратный, вылизанный и хорошо откоментированный код на C#, а потом поехать на море с пальмами.

Я не планирую продолжать беседу по теме, пока

Ну, это просто ребячество. Мы так мило беседовали и вдруг нате вам!

cross_platform
() автор топика
Ответ на: комментарий от byko3y

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

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

реальная кросс-платформенность

Go

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

Я понимаю, что сейчас прошла эпидемия микросервисов, и проявился эффект «если у тебя единственный инструмент — молоток, то вокруг всё становится похоже на гвозди». Go упал в нишу микросервисов, но микросервисы — это мягко говоря не единственное применение. Как ты собрался писать на Go под десктоп? Под андроид? Монолитные сервисы? Да никак.

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

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

Вот посмотрите на «нехитрую бизнес-логику» https://golang.org/pkg/

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

Вот посмотрите на «нехитрую бизнес-логику» https://golang.org/pkg/

И что ты хотел мне показать этим? Там половину пакетов — это кодирование-раскодирование, еще четверть — это пакеты для сетевых протоколов.

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

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

Зачем вы затрагиваете темы в которых вы «не бум-бум»?

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

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

Блин, это боль. Когда тебе нужно железобетонно через равные интервалы выдавать сигнал или получать его, а ты пишешь на C#. Я сам делал подобные софтины на дельфи в студенческие годы, на даже там проблема тормозов главного потока прекрасно решается воспомогательными потоками, которые пишут в буфер и ни про какие тормоза не знают. Собственно, примерно для чего-то такого создавался Tcl, в котором заложены фундаментальные механизмы параллелизации.

У меня тогда возникает вопрос: ты убирал потоки из этих программ? Потому что лично я не представляю, как можно продолжать получить гарантию непрерывного ввода-вывода в одном потоке с убогим синхронным GUI родом из 80-х годов. Даже WPF и UWP эту проблему не решают, потому что параллельный там только рендер, а параметры интерфейса меняются, считаются, и скармливаются рендеру полностью синхронно.

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

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

Зачем вы затрагиваете темы в которых вы «не бум-бум»?

Докажи.

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

Владимиру от Владимира

Вертаю вам обраточку, Владимир

Мы технари, мы соль культуры,
мы Землю держим на плечах!
Без нас бы до сих пор в натуре
скакали люди на ветвях.

Владимиp

anonymous
()

Родные мои, я ни коим образом не хочу вас цензурировать, но эта тема про «Unity на Linux». Если вы хотите обсудить Go, Rust, Assembler, Python, просьба проследовать на винфак в другие темы.

cross_platform
() автор топика

Java + go - всё остальное ненужно!

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

Это всего лишь шутка и не направлена именно к вам.

Мы не из тех кто соль культуры,
Нам наплевать на все и вся!
Мы можем в магазин пойти в натуре
И станцевать в нем гопака.

Владимир

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

Так тред то об использовании C# в Linux?

Тред совершенно не об этом.

cross_platform
() автор топика

Без Linux-а вполне себе существует.

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

За механику и датчики отвечает отдельный контроллер с прошивкой на си. Компьютер только настройки передаёт и результаты работы получает по rs-232. Так что достаточно пары потоков. Один на gui, один на обмен с контроллером. Ну и для камер могут быть потоки. Всё. А коллеги мои поток вешали на любое нажатие кнопки.

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

Это всего лишь шутка и не направлена именно к вам.

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

Владимиp

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

Могу только предполагать. Есть у нас программа на Windows.Forms, проверенная годами. По разным причинам решили переписать на WPF. Человек, делавший новое View в качестве Model сделал заглушку на потоках. В принципе, для заглушки, которая не привязана к реальным устройствам, так даже работает, ибо каждый поток живёт очень мало.

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

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

Зачем?

Чтобы интерфейс не лагал от долгих действий. Очевидно же.

Всякие gedit и mousepad в Linux обычно до такого не додумались, и встают(вставали хз как сейчас) колом если попытаться открыть какой-нибудь текстовый файл на гигабайт. А была бы загрузка файла в отдельном потоке, то можно было бы легко показывать процент загрузки файла, и закрыть программу не дожидаясь конца.

И скорее всего там писали не на обычных потоках, а на BackgroundWorker, который не создаёт потоки, а отправляет задачу на встроенный ThreadPool.

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

До сих пор встают, убогие поделки. Даже гигабайта не надо. Пол сотни мегабайт и можно сказать досвидание

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