Обновить
53
Valentin Nechayev@netch80

Программист (backend/сети)

20
Подписчики
Отправить сообщение
Ну я бы в таком случае ответил, что наиболее эффективный метод — это использовать готовую инструкцию POPCNT, а если у вас процессор её не умеет — дешевле его заменить :) Формально и для enterprise подхода — это было бы ещё правильнее (но не для попугая на входе).
Почему promise API несимметричен относительно деления на первичные функции (в new) и вторичные (во then/catch)?

В первичных надо получать аргументами resolve и reject, и вызывать их явно (проверил на promise 7.1.1 для nodejs — простой return со значением игнорируется, как будто промис незавершён).
Во вторичных надо возвращать значение или генерировать исключение, параметров resolve, reject нет.

Я бы понял логику, или что
1) у всех функций-коллбэков возврат значения работает как resolve с этим значением, а генерация исключения — как reject,
или что
2) все функции-коллбэки имеют три входных параметра — input, resolve, reject,

а лучше — и то, и другое (можно вернуть значение в конце, а можно — вернуть исключение и выйти; а ещё лучше — предусмотреть специальный тип исключения для resolve).

Также нет возможности написать .resolve(значение), и аналогично для reject — тоже было бы значительно удобнее (и извне, как уже обсуждают, и изнутри). (Тогда можно было бы вторым параметром передавать сам объект промиса, для вызовов его методов.)

Или я не вижу каких-то хитростей, которые решают это, и которые можно найти только с заметным опытом их использования?
> Проблема не в пропускной способности, а в сетевых задержках.

Я рассматривал в контексте передачи сравнимого с от «100,000 обращениями к оперативной памяти» и до «1,000,000,000 тактов» объёма передачи, там задержки уровня одного пакета уже не столь существенны, а скорость значительно больше влияет на общую задержку. В контексте коротких передач — да, безусловно, суммарные задержки важнее, и пример «512 байт из iRAM по сети vs. HDD локально, которому надо ещё переместить головки на полный диапазон» — отличная иллюстрация.
> Но ведь 100.000 обращений к оперативной памяти делается операциями, которые сами по себе займут 100.000 * x тактов?

64 чтения из областей, не входящих в одну выровненную 64-байтную область (как строка кэша), займут ~64*250 тактов. 64 чтения подряд из одной такой области займут, по описанной таблице, 64*4 такта. Достаточно просить prefetch на одну такую строку в начале чтения предыдущей, чтобы последовательное чтение не задерживало процессор. В реальности ситуацию ещё больше улучшают микросхемы памяти с несколькими одновременно открытыми строками и многоканальные контроллеры памяти.

> Как часто можно встретить ситуацию, когда 100.000 раз обращений к оперативки выгоднее, чем одно обращение к диску, особенно учитывая существование SSD и PCI-SSD?

При хоть сколь-нибудь продуманном доступе к памяти — считаем, практически всегда.

> Тем более, что сетевой сокет в гигабитной локалке, может быть быстрее, чем обращение к диску.

Гигабитный — по сравнению с SATA даже 1-м — уже нет :) Вот 10GB, или Infiniband'овские скорости — да, уже стоит упоминать.
Именно эта статья — нет, но аналогичные — да. Cетевой транспорт некоторого специфического протокола (средняя длина сообщения около 200 байт); внутреннее представление сообщения — или разложение в таблицу пар имя=значение, или как две строки (std::string, заголовок и тело) с манипуляцией над строкой с массовыми перемещениями частей при вставлении или удалении тегов. Без проблем медленной RAM — работа с разложенным представлением была бы в разы быстрее, но с учётом медленной памяти и кэширования — работа с цельными строками в ~2 раза быстрее. Ещё процентов 30 получается за счёт предаллокации строк на предполагаемую длину, вместо того, чтобы позволять рантайму несколько раз делать realloc.
12 ...
174

Информация

В рейтинге
7 413-й
Откуда
Киев, Киевская обл., Украина
Дата рождения
Зарегистрирован
Активность