Re[16]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Cyberax Марс  
Дата: 12.02.14 00:02
Оценка:
Здравствуйте, Константин, Вы писали:

C>>AIO никто не использует, так как для файлового IO проще использовать пулы потоков.

К>Проще не значит эфективнее.
Примерно значит. Дело в том, что для AIO (что в Винде, что в Линуксе) всё равно в итоге используется поток в ядре — для создания объектов, поиска данных в кэше, обслуживания очереди и т.п. Выигрыш от AIO будет, если есть очень большая очередь IO-запросов.

Дело только в том, что по сравнению с сетью у дискового IO меньше масштабируемость. Обычно даже пара десятков параллельных writer'ов или reader'ов — это слишком много для вращающихся дисков.

C>>Под Виндой, кстати, тоже

К>Нет, под виндой не тоже: в .NET это прекрасно работает.
Тоже.

C>>приколов типа блокирующегося CloseHandle

К>Он блокируется только если есть pending операции.
К>При правильном использовании (сначала подождать завершения pending IO потом закрывать) ничо не блокируется.
Нет такой гарантии — и на практике оно тормозит. Кстати, такой операции вообще в overlapped нет.

C>>За пределами файлового IO, epoll работает быстрее Overlapped IO из-за лучшей оптимизации TCP-стека в Линуксе.

К>Подтверждения "лучшей оптимизации TCP-стека в Линуксе" есть какие-то?
http://www.slideshare.net/PrincipledTechnologies/comparing-network-performance-red-hat-enterprise-linux-6-vs-microsoft-windows-server-2012 — для примера

К>>>Соответственно, асинхронный IO (и построенные на его основе технологии вроде async-await) на других платформах неизбежно будут глючить и/или тормозить.

C>>Хех. Разработчики Nodejs, libev и других мультиплексирующих систем под Юниксы недоумевают.
К>Разработчики этих систем не пишут на .NET.
А что, .NET магически имеет свой IO-стек?

К>Чтобы посмотреть, что получается при портировании, смотрите производитиельность Node.js на винде: они там не то что IOCP, даже overlapped IO не смогли, используют select, с ожидаемым результатом по производительности.

Не надо говорить о том, чего не знаешь. В libuv (и nodejs) используется Overlapped IO. См.: https://github.com/joyent/libuv/blob/master/src/win/core.c

К>Если бы .NET framework проектировался кросс-платформенным, об эффективном асинхронном IO можно было бы забыть, см. например состояние этого в Java.


C>>http://1-ps.googleusercontent.com/h/www.salmanq.com/wp-content/uploads/2013/03/performance-comparison-net-nodejs.png.pagespeed.ce.1YsnSc2NdF.png

К>На красивом графике мы видим, что уже 200 одновременных запросах (что в условиях того теста всего лишь 67 запросов в секунду) .NET становится быстрее NodeJS.
Эээ.. Вообще-то, на графике показано, что до 200 соединений у nodejs меньше латентность. Т.е. работает она быстрее. Более 200 соединений тестов просто нет.

К>Ничего удивительного для меня в этом нет: очевидно же, что на винде, где multiplexed IO развивается ещё с 1993 года, оно будет лучше работать.

Нет, его задизайнили в 93-м и с тех пор вынуждены это пииииии поддерживать из-за невозможности сделать полноценный рефакторинг. В Линуксе оно началось с тупой реализации, которую потом несколько раз переписали до того, что она сейчас лучшая в мире.
Sapienti sat!
Re[20]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Cyberax Марс  
Дата: 12.02.14 06:01
Оценка:
Здравствуйте, Константин, Вы писали:

К>«обычный многопоточный IO» более-менее пригоден только для hello world, и ещё для очень узкого класса приложений, например что-то вроде офиса, когда все данные в RAM, а от IO требуется только [де]сериализация раз в полчаса на быстрый локальный диск.

К>Посмотрите ради интереса, какое API использует скажем chromium для работы с диском и сетью.
Блокирующийся IO для файлового IO и epoll/kqueue/overlapped для сети. То что они сегрегируют IO и процессы-рендереры не считаем — внутри дочерних процессов используется только асинхронный API для всего.
Sapienti sat!
Re[19]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Ночной Смотрящий Россия  
Дата: 12.02.14 16:19
Оценка: +2
Здравствуйте, alex_public, Вы писали:

_>Я намекаю, что асинхронный IO будет эффективнее обычного многопоточного только на очень узком круге задач.


В этот узкий круг, помимо серверов, входят, как минимум, смартфоны. Именно поэтому в WP искусственно покоцан весь синхронный IO из API.
Re[20]: Зачем Майкрософту рубить сук, на котором он сидит?
От: alex_public  
Дата: 12.02.14 18:31
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>В этот узкий круг, помимо серверов, входят, как минимум, смартфоны. Именно поэтому в WP искусственно покоцан весь синхронный IO из API.


С чего бы это? )
Re[21]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Ночной Смотрящий Россия  
Дата: 12.02.14 19:42
Оценка:
Здравствуйте, alex_public, Вы писали:

НС>>В этот узкий круг, помимо серверов, входят, как минимум, смартфоны. Именно поэтому в WP искусственно покоцан весь синхронный IO из API.

_>С чего бы это? )

К какой части высказывания вопрос?
Re[22]: Зачем Майкрософту рубить сук, на котором он сидит?
От: alex_public  
Дата: 12.02.14 20:37
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>К какой части высказывания вопрос?


К первой. )
Re[21]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Sinix  
Дата: 13.02.14 06:19
Оценка:
Здравствуйте, alex_public, Вы писали:

НС>>В этот узкий круг, помимо серверов, входят, как минимум, смартфоны. Именно поэтому в WP искусственно покоцан весь синхронный IO из API.

_>С чего бы это? )
тут речь о наблюдаемой производительности (aka perceived performance).

Под wp/winrt большинство тяжёлых операций можно выполнить только асинхронно. Благодаря этому надо очень постараться, чтобы завесить UI-поток (и с определённой долей вероятности такое приложение не пройдёт в маркет). В прочих мобильных ОС ситуация прямо противоположная
Re[14]: Зачем Майкрософту рубить сук, на котором он сидит?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.02.14 07:27
Оценка:
Здравствуйте, Константин, Вы писали:

К>В стандарте нет ничего платформозависимого.

К>А вот в рантайме, есть много вещей, которые сложно перенести в силу того, что в других ОС не хватает каких-то важных кусков.
К>Один из них многопоточность.
К>В самом центре .NET-ового thread pool и всего асинхронного IO лежит IO completion port.

В моём случае всё, что нужно было для целевого приложения, уже было перенесено. Там даже обычного poll() хватало с головой для работы, потому что не было "10k" параллельных клиентов с отдельными соединениями на каждого, а был один большой сокет на всё. Плюс несколько небольших пулов ниток для медленных партнёров типа БД.

К>Это объект ядра, уникальный для винды (в *nix какие-то потуги, а именно kqueue и epoll, появились на много лет позже, и намного хуже работают),


Последнее утверждение требует обоснования, как минимум про kqueue.

К> и хорошо интегрированный в остальные API (в linux почему-то epoll только для сокетов, а для файлов не особо совместимый native AIO).


И в Linux, и во FreeBSD тот же AIO работает неплохо. Правда, в случае Linux нет адекватной связи между AIO и epoll (или я её не знаю). Для FreeBSD EVFILT_AIO подключает статус завершения операции.

К>Соответственно, асинхронный IO (и построенные на его основе технологии вроде async-await) на других платформах неизбежно будут глючить и/или тормозить.


Я не увидел достаточно обоснований для такого вывода.

К>Второй из них 3D графика.


Как уже сказал, мне она тут совершенно пофиг, у меня другие задачи.

К>Соответственно, «подумать не только про виндовую среду» означало бы, что .NET лишился бы существенных преимуществ, и стал бы ещё одной Java, которая конечно переносима ОК, только ни на одной платформе нормально не работает


"Нормально" для каких целей? Сеть — штука на 99% кроссплатформенная.
The God is real, unless declared integer.
Re[15]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Cyberax Марс  
Дата: 13.02.14 07:37
Оценка:
Здравствуйте, netch80, Вы писали:

К>> и хорошо интегрированный в остальные API (в linux почему-то epoll только для сокетов, а для файлов не особо совместимый native AIO).

N>И в Linux, и во FreeBSD тот же AIO работает неплохо. Правда, в случае Linux нет адекватной связи между AIO и epoll (или я её не знаю).
Есть несколько вариантов:
1) Использовать сигналы для нотификаций — напрямую или через signalfd().
2) eventfd() для превращения event'ов в дескрипторы для epoll()
Sapienti sat!
Re[20]: Зачем Майкрософту рубить сук, на котором он сидит?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.02.14 07:46
Оценка:
Здравствуйте, Константин, Вы писали:

_>>Я подразумевал совсем не то, что вне нагруженных серверов наплевать на ресурсы.

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

С этим вполне можно согласиться (хотя детали организации могут портить картину).

К>Если в системе есть и другие активные процессы, "эффективнее" станет "в разы эффективнее".

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

Серьёзно, винда на среднем десктопе от 400 ниток уже выжирает память? Что-то мне даже про неё не верится. Linux спокойно выдержит тысяч 30 при дефолтных настройках и миллионы при разумном тюнинге. Кажется, Вы что-то таки спутали.
Или речь про адресное пространство в 32 битах? Тогда не надо говорить про "дорогой системный ресурс", это не системный ресурс, а ресурс процесса.

Если принять за основу, что нить в Windows очень дорога в держании и переключении, то неудивительно стремление MS к IOCP — выигрыш идёт действительно в разы. В Linux разница значительно меньше.

К>«обычный многопоточный IO» более-менее пригоден только для hello world, и ещё для очень узкого класса приложений, например что-то вроде офиса, когда все данные в RAM, а от IO требуется только [де]сериализация раз в полчаса на быстрый локальный диск.

К>Посмотрите ради интереса, какое API использует скажем chromium для работы с диском и сетью.

Это показывает пока что только то, что его изначально рассчитывали в том числе и на системы, где нить является крайне дорогой сущностью (как по Вашему описанию в Windows).
API в стиле "заказать операцию, ждать callback", кроме того, универсально тем, что оно достаточно легко превращается с помощью врапперов в API с ожиданием результата, если требуется таки синхронная реализация (в первый раз такую технологию использовали, кажется, ещё в OS/360). Но это значит всего лишь, что выставлены в userland ядерные потроха (с минимальной защитой).

К>Например, по этой причине из нового WinAPI повыкидывали вызовы, которые могут блокировать вызывающий поток хотя бы на 50 миллисекунд.


И в результате 99% индусов будут писать в духе

    startOperation();
    waitOnEvent(operation_finished);


эффективно умножая эти старания разработчиков WinAPI на ноль.
The God is real, unless declared integer.
Re[16]: Зачем Майкрософту рубить сук, на котором он сидит?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.02.14 07:52
Оценка:
Здравствуйте, Cyberax, Вы писали:

К>>> и хорошо интегрированный в остальные API (в linux почему-то epoll только для сокетов, а для файлов не особо совместимый native AIO).

N>>И в Linux, и во FreeBSD тот же AIO работает неплохо. Правда, в случае Linux нет адекватной связи между AIO и epoll (или я её не знаю).
C>Есть несколько вариантов:
C>1) Использовать сигналы для нотификаций — напрямую или через signalfd().

Похоже. Но сигналов тут ограниченное количество.

C>2) eventfd() для превращения event'ов в дескрипторы для epoll()


Примеры, которые я вижу, используют io_submit(), который фиг так просто вызовешь.
Интересно, почему не lio_listio().
The God is real, unless declared integer.
Re[21]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Sinix  
Дата: 13.02.14 09:34
Оценка: 3 (1) +1
Здравствуйте, netch80, Вы писали:

N>Серьёзно, винда на среднем десктопе от 400 ниток уже выжирает память? Что-то мне даже про неё не верится. Linux спокойно выдержит тысяч 30 при дефолтных настройках и миллионы при разумном тюнинге. Кажется, Вы что-то таки спутали.

N>Если принять за основу, что нить в Windows очень дорога в держании и переключении, то неудивительно стремление MS к IOCP — выигрыш идёт действительно в разы. В Linux разница значительно меньше.
Дело не столько в "дорога в держании и переключении", сколько в накладных расходах на kernel switch и загруженный впустую планировщик. Сравни сам:
        static void Main(string[] args)
        {
            //RunTasks().Wait();
            RunThreads();
        }

        static int s_TaskCount;
        static async Task RunTasks()
        {
            int i = 0;
            while (true)
            {
                i++;
                Task.Run(async () =>
                    {
                        Interlocked.Increment(ref s_TaskCount);
                        await Task.Delay(5000).ConfigureAwait(false);
                        Interlocked.Decrement(ref s_TaskCount);
                    });

                i++;
                if (i % 100 == 0)
                {
                    await Task.Yield();
                    Console.WriteLine(s_TaskCount.ToString("N"));
                }
            }
        }

        static int s_ThreadsCount;
        static void RunThreads()
        {
            int i = 0;
            while (true)
            {
                new Thread(() =>
                    {
                        Interlocked.Increment(ref s_ThreadsCount);
                        Thread.Sleep(5000);
                        Interlocked.Decrement(ref s_ThreadsCount);
                    },
                    100 * 1024).Start();

                i++;
                if (i % 100 == 0)
                {
                    Console.WriteLine(s_ThreadsCount.ToString("N"));
                    Thread.Yield();
                }
            }
        }

Вариант с потоками под x86 затыкается с OutOfMemory уже на ~3000 потоков (несмотря на стек в 100 кб), под x64 — стабилизируется где-то на 30k потоков.
Вариант с тасками спокойно пережёвывает 800k одновременно работающих тасков.

Если перейти на пул потоков с IOCP при должном везении получается нечто среднее.

N>И в результате 99% индусов будут писать в духе

    startOperation();
    waitOnEvent(operation_finished);

С вероятностью выше >>0.5 не пройдёт тест в маркете. Даже не ручное тестирование, а WACK tool.
Re[17]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Cyberax Марс  
Дата: 13.02.14 12:12
Оценка:
Здравствуйте, netch80, Вы писали:

C>>Есть несколько вариантов:

C>>1) Использовать сигналы для нотификаций — напрямую или через signalfd().
N>Похоже. Но сигналов тут ограниченное количество.
Для простой нотификации сойдёт — просто прервать epoll и дальше посмотреть что там пришло.

C>>2) eventfd() для превращения event'ов в дескрипторы для epoll()

N>Примеры, которые я вижу, используют io_submit(), который фиг так просто вызовешь.
N>Интересно, почему не lio_listio().
Должно работать и с ним.
Sapienti sat!
Re[22]: Зачем Майкрософту рубить сук, на котором он сидит?
От: alex_public  
Дата: 13.02.14 12:23
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Под wp/winrt большинство тяжёлых операций можно выполнить только асинхронно. Благодаря этому надо очень постараться, чтобы завесить UI-поток (и с определённой долей вероятности такое приложение не пройдёт в маркет). В прочих мобильных ОС ситуация прямо противоположная


Ну так а зачем запускать тяжёлые операции в UI потоке, а не в отдельном? )
Re[23]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Sinix  
Дата: 13.02.14 12:37
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Ну так а зачем запускать тяжёлые операции в UI потоке, а не в отдельном? )

В терминах мобильных приложений к "тяжёлым" относится всё, что может завесить поток больше, чем на 50 миллисекунд. Т.е. любой ввод-вывод как минимум.

Жёстко конечно, зато я не видел ни одного намертво зависшего приложения под wp/winrt, в отличие от всех прочих платформ.
Re[22]: Зачем Майкрософту рубить сук, на котором он сидит?
От: alex_public  
Дата: 13.02.14 13:24
Оценка: 2 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Дело не столько в "дорога в держании и переключении", сколько в накладных расходах на kernel switch и загруженный впустую планировщик. Сравни сам:

S>...
S>Вариант с потоками под x86 затыкается с OutOfMemory уже на ~3000 потоков (несмотря на стек в 100 кб), под x64 — стабилизируется где-то на 30k потоков.

Это исключительно проблемы .net'a. ) Аналогичный код на C++ спокойно стабилизируется где-то на 11 000 потоков на древнейшей машине (WinXP 32 бита, Core2Duo, 2Гб). Т.е. на современном процессоре было бы под 50К (на тех же 32 битах).

S>Вариант с тасками спокойно пережёвывает 800k одновременно работающих тасков.


Естественно. Потому как этот тест измеряет совсем другое. Тут скорее соревнование в накладных расходах на создание потока/задачи. И т.к. здесь время работы (а не жизни) потока микроскопическое в сравнение с процессом создания потока (а у внутренних задачек тут всё хорошо), то такой вариант естественно получается невыгодным. А вот если эти же 5 секунд поток/задача будут заняты вычислениями, то у нас будет совсем другой расклад...

Но вообще, я конечно же согласен, что в случае многих тысяч одновременных задач правильнее переходит от системной многозадачности, к внутренней рукопашной (и как следствие этого, асинхронный IO). Только это же у нас опять же получается крайне узкая область применения, о чём я и говорил изначально.
Re[24]: Зачем Майкрософту рубить сук, на котором он сидит?
От: alex_public  
Дата: 13.02.14 13:36
Оценка:
Здравствуйте, Sinix, Вы писали:

_>>Ну так а зачем запускать тяжёлые операции в UI потоке, а не в отдельном? )

S>В терминах мобильных приложений к "тяжёлым" относится всё, что может завесить поток больше, чем на 50 миллисекунд. Т.е. любой ввод-вывод как минимум.

И как это отвечает на мой вопрос? )

S>Жёстко конечно, зато я не видел ни одного намертво зависшего приложения под wp/winrt, в отличие от всех прочих платформ.


Похоже что данного преимущества недостаточно для популярности платформы. Кстати, сама винда это показывала в далёком прошлом: более открытая платформа выигрывает, даже если она более глючная.
Re[23]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Sinix  
Дата: 13.02.14 13:46
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Это исключительно проблемы .net'a. ) Аналогичный код на C++ спокойно стабилизируется где-то на 11 000 потоков на древнейшей машине (WinXP 32 бита, Core2Duo, 2Гб). Т.е. на современном процессоре было бы под 50К (на тех же 32 битах).

Вот тут я не уверен честно говоря От .net-а там всего ничего, почти всё уходит в нативные вызовы. Как вариант — выложите бинарник, проверю.
Кстати, а в запускаюшем коде есть что-то типа Thread.Yield? Без него "рабочие" потоки скорее ждут своей очереди на завершение чем работают. С тасками так счётчик растёт до нескольких миллионов, что конечно же неверно.

S>>А вот если эти же 5 секунд поток/задача будут заняты вычислениями, то у нас будет совсем другой расклад...

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

_>Но вообще, я конечно же согласен, что в случае многих тысяч одновременных задач правильнее переходит от системной многозадачности, к внутренней рукопашной (и как следствие этого, асинхронный IO). Только это же у нас опять же получается крайне узкая область применения, о чём я и говорил изначально.

Это во многом зависит от дизайна языка и фреймворка. Для дотнета замена абсолютно прозрачна. Для скалы/эрланга — незаметна в принципе.
Re[22]: Зачем Майкрософту рубить сук, на котором он сидит?
От: Евгений Акиньшин grapholite.com
Дата: 13.02.14 14:36
Оценка: 2 (1)
Здравствуйте, Sinix, Вы писали:

S>С вероятностью выше >>0.5 не пройдёт тест в маркете. Даже не ручное тестирование, а WACK tool.


Пройдет.

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

  someObject.SomeMethodAsync().AsTask().Wait();


Тестирование уже раз 50 проходил, проблем не было.
Не шалю, никого не трогаю, починяю примус Diagrams Designer for iPad and Windows 10
Re[24]: Зачем Майкрософту рубить сук, на котором он сидит?
От: alex_public  
Дата: 13.02.14 15:11
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Вот тут я не уверен честно говоря От .net-а там всего ничего, почти всё уходит в нативные вызовы. Как вариант — выложите бинарник, проверю.


Легко: http://files.rsdn.ru/98162/test.exe

S>Кстати, а в запускаюшем коде есть что-то типа Thread.Yield? Без него "рабочие" потоки скорее ждут своей очереди на завершение чем работают. С тасками так счётчик растёт до нескольких миллионов, что конечно же неверно.


Thread.Yield это в реальности функция SwitchToThread из win api. И её добавление/убирание для потоков в данном случае естественно никак не влияет на ситуацию — не стоит путать кооперативную и вытесняющую многозадачность.

S>Это во многом зависит от дизайна языка и фреймворка. Для дотнета замена абсолютно прозрачна. Для скалы/эрланга — незаметна в принципе.


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

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