netch80: (Default)
2030-12-31 11:00 pm

[header]

Это субжурнал для [livejournal.com profile] netch по тематике IT. Все вопросы - к оригиналу.
netch80: (Default)
2017-04-21 08:41 am

Возврат нескольких значений

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

C сохраняет подход с единственным значением. Где нужно возвращать более одного значения - начинается передача по указателю (примеры на каждом шагу).

В C++ уже можно за счёт tuple делать возврат с распаковкой в набор переменных, хотя реализация этого на уровне ABI скорее всего идёт через структуру в памяти, а не регистры. Ну и передача по ссылке, конечно же, как косвенный метод (с затратами памяти).

Pascal - та же передача по ссылке.

Forth изначально не имел этой проблемы (хотя держание всего на стеке - само по себе источник тормозов).

В Java формально одно значение (возврат объекта, пока нет value types, слишком дорог, хотя JIT это может соптимизировать). В результате возникают ситуации типа возврата массивов, или битовых трюков (которые работают только потому, что нету типов целых беззнаковых; заметим, что в этой доке везде пишут -1-x, а не ~x - почему?)

В C# вначале сделали out-параметры (и, я считаю, требование писать out и ref в списке параметров фактического вызова - гениальное и чрезвычайно важное требование; Паскаль до этого не дошёл), теперь наконец добавили кортежи.

Fortran за счёт требования передачи по ссылке или входного-выходного копирования всех параметров решал это изначально (считаем, что аналог ref из C#) и даже чрезмерно (вспомним тему модификации константы).

Динамические языки (типа Python, JS, Erlang) возвращают по-прежнему одно значение, но за счёт того, что оно может быть кортежом (списком...), получается произвольное количество (за счёт затрат на распаковку) - не решение, но лёгкий обход проблемы.

Go, Swift, Rust - возврат нескольких параметров сделан изначально.

Но на уровне скомпилированного кода приходится ориентироваться на монстров компиляции C, так LLVM сделал возможность возврата нескольких параметров, а GCC - нет. Он тормозит всех. В результате в свежайших разработках типа RISC-V ABI имеем только одно возвращаемое значение (может растягиваться на два регистра, сути это не меняет). Не могу нагуглить, что мешает GCCʼшникам.
netch80: (Default)
2017-04-18 04:39 am

Perl, версии, defined() на списки

Обновление Perl до 5.24 принесло, что defined() нельзя применять к массивам (уж не помню, для какой версии это рекомендовалось - чуть ли не 5.5, наверно), сломав скрипты домашнего mailnews. Фикс тривиален.

Зато на Centos 7 используется 5.14 - это ж в какой древности они его такой закрепили.
netch80: (Default)
2017-04-05 12:32 pm

gtk3 scrollbar fix

Кого задолбали перепутанные кнопки мыши на скроллбарах gtk3 - лекарство.
Я с этим столкнулся, проапгрейдившись до (K)Ubuntu 16.04.
netch80: (Default)
2017-02-16 07:22 pm

Более хитрый профайлер хочу.

Видел ли кто-нибудь в природе профайлер для C/C++, который бы выдавал не только среднее, а ещё и как минимум стандартное отклонение? (А с задаваемыми квантилями так полное Щастье было бы)
Для начала в пределах opensource.
netch80: (Default)
2017-01-30 02:20 pm

дыбросорт

Сегодня впервые в жизни применил устойчивую сортировку, и впервые за последние, наверно, лет 5, сортировку вообще. Может, и больше времени прошло (что-то мне такое смутно вспоминается из раннего массолита). (Всякие du -akx | sort -rn | less не учитываю.)

В то же время построения на std::map используются постоянно.
netch80: (Default)
2017-01-29 08:48 am

ssh с ключом и паролем от сервера?

Хочется странного. При стандартной авторизации ssh по ключу есть кодовая фраза на стороне клиента. При этом он может менять её, отдавать ключ другому, контроль доступа слабоэффективен (по ip не годится, если ip может меняться)...
Вот если бы ключ принимался, но при этом сервер требовал дополнительный пароль. После успешного входа - попадает в полноправного пользователя (но, если не знает основной пароль пользователя, не может управлять доступом).
Для самого ssh можно к ключу добавить forced command (типа "ask-password foo"), но дальше пароль должен попросить кто-то другой. Причём желательно, чтобы управление доступом тут (какие есть дополнительные пароли (названия - ключи к словарю) и сами пароли) было доступно пользователю не по умолчанию, а через свой основной пароль.

Один вариант реализации понятен - вход в дополнительного системного пользователя, который имеет право sudo su в основного. Но это очень громоздко и требует странных подпорок. А более прямо?

Я бы накостылял что-то в духе:

1. /var/lib/add_pass/$user/$key - хэш пароля
2. /usr/lib/add_pass/check $key - forced command для ключа, проверяет пароль, для доступа к п.1 требует suid или лучше sgid.
3. /usr/lib/add_pass/control - средство управления - тоже шлюз привилегий.

Как защитить authorized_keys?

Или убедите, что это всё бесполезно, если вообще кого-то пускаем шеллом :)
netch80: (Default)
2017-01-27 09:18 am

so-injections horror

https://laurent22.github.io/so-injections/
Это адский мрак. Половина вопросов с дырами => из них половина выйдет в релиз нелеченными.
netch80: (Default)
2017-01-13 08:16 am

Рабочий вечер, пляски вокруг kdb

Обычный рабочий вечер, переписка в slack после того, как некий запрос завесил сервер так, что Ctrl+C из локальной консоли не помогло.

user1: почему запрос `select count time/5 from sesslog` убил кдб сервер?
user2: http://code.kx.com/wiki/Reference/Slash
user3: я подозреваю что user1 хотел разделить на 5))
user2: 1. приоритет операций строго справа налево. если нет скобок
user2: 2. для деления используется %, а не /
user2: Или div если целочисленное
user1: почему убилось kdb
user2: 3. если нужно считать кол-во записей, используйте i вместо имени столбца.
VN: user2, ты как на русском форуме - отвечаешь на что угодно, кроме исходного вопроса
user2: Валик, я ткнул носом в доку
VN: user2 блин. Можешь объяснить, при чём тут over к глобальному заклину процесса?
user1: хорошо.
user1: что из этого http://code.kx.com/wiki/Reference/Slash
user1: и почему
user3: потому что твой овер рекурсивно выжрал всю доступную память процессу
VN: неправда.
VN: я вот тут воспроизвожу - память не меняется, хотя процесс жрёт 100%
user2: over: The iteration form of / terminates when either: (1) two successive results agree within comparison tolerance or (2) the result matches the initial input. The latter will save you from some infinite cycles but not all
user2: converge: When / is following a monadic function f/[g;x] will apply f to x until g returns 0b
VN: user2, ты программист. Я это понял.
guru4: а вы смотрели, во что он скомпилился? на K
guru4: (,`x)!,((/;`time);#:;5)
guru5: а ну да, теперь все понятно
(под репликой чужой смайл типа "слёзы из глаз от смеха")
user1: и это зацикливает инстанс?
guru4: да
user1: и какое поведение будет если добавить нитей?
user1: как, кроме как административно, избежать отказа в обслуживании
guru5: а в нашем интерпретаторе подсчет инструкций и всегда отдается yield в интерпретатор :)
guru4: это вежливый, хороший интерпретатор
guru4: а К просто крутит цикл

Картинка в тему.
netch80: (Default)
2017-01-11 08:34 am

Уже не пять, но сколько?

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

На 2000 год ~80% усилий приходилось на "внутреннее" ПО. Но появился мир онлайна и соответствующих технологий, причём поглотив существенную часть и "внутреннего", и "коробочного"/"ширпотреба", и игр (убрав фактор одноразовости). И не просто появился, а приближается к основному по размаху (а судя по местам скопления молодёжи, типа DOU, >50%, если не 80%). Спольски его упоминает как частный случай "ширпотреба", но это уже не так. По свойствам он не ложится ни на один из предшествующих. Подходы к разработке (на серверной стороне - особенно, на клиентской - частично) больше соответствуют "внутреннему", чем "ширпотребу", из-за давлений на темпы разработки и резкого смягчения ограничений на переносимость (браузеры более сходны, чем разные среды для ОС; даже для мобилок есть обобщённые среды разработки). Соответственно, "гуру" получили резкое расширение поля деятельности. Внутренности серверных сторон - между "внутренним" и "консультационным", но грязное бельё уже никто не считает (или сделал это мелким частным случаем). Юзабилити критично. Код клиентской стороны закрыть невозможно. Полностью частные разработки не окупаются, зато очень много переносимого в реализациях.

Игры - прежних коробочных бегалок больше не осталось. Всё больше чем "Angry Birds" ушло в Интернет и создало новую структуру, ориентированную на многолетнюю игру. С другой стороны, все наработки 30-50-летней давности ещё от игровых автоматов на дискретной рассыпухе и вплоть до PCʼшек конца 80-х успешно слились в мобайл.

И embedded не тот (хотя вполне себе торт) - старые ограничения с выжимкой каждого байта теперь даже не в каждой SIMке, а если не сохранять тупое legacy, то 32-битный проц с полумегом оперативки идёт за 1$ в большом тираже (так что старперы-брюзжатели на 8051 уже даже не смешны).

<mode="капризный_блоггер">А что теперь, когда, говоря упрощённым языком, закон Мура останавливается? Куда повернётся ещё через 10 лет?</mode>
netch80: (finch)
2017-01-08 09:33 am

жуткая кривость в доке binutils

Это надо занести в хрестоматию как чистейший пример фатального неумения писать документацию.

     __asm__(".symver original_foo,foo@");
     __asm__(".symver old_foo,foo@VERS_1.1");
     __asm__(".symver old_foo1,foo@VERS_1.2");
     __asm__(".symver new_foo,foo@@VERS_2.0");
[...]


When you have multiple definitions of a given symbol, there needs to be some way to specify a default version to which external references to this symbol will be bound. You can do this with the `foo@@VERS_2.0' type of `.symver' directive. You can only declare one version of a symbol as the default in this manner; otherwise you would effectively have multiple definitions of the same symbol.

(источник)

Из такого объяснения в принципе непонятно, что играет роль признака "default version" - номер версии, порядок объявления, или два '@' вместо одного (правильно - последнее, но его тяжелее всего заметить). Автору данного пассажа из документации правильный ответ известен, но он просто не в состоянии догадаться, что тот, кто его не знает, не поймёт такого объяснения.

Сомневаюсь, что стоит посылать жалобу (пусть даже с патчем) - если рассматривать будут те же, они просто не поверят.
netch80: (finch)
2017-01-08 08:16 am

symbol versioning in main binary?

Пересобрал тут одну программку, а в ней main() видно не как main, а как main@@Base, и аналогично все прочие символы из основного кода.
Откуда это - в принципе понятно. Непонятно, чего хотят этим добиться.
netch80: (bird)
2016-12-20 01:02 pm

wrike suxx

У нас тут в качестве трекера wrike используется, так вот что я вам имею сказать: я такого аццкого, феерического дерьма не видел вообще. (Почти) любая другая система, даже богом проклятая JIRA, будет лучше.
Причём засада не в формальных возможностях, а в деталях реализации. Всё, что можно было сделать через зад, сделано именно через зад, причём ещё и с приподвывертом.
А ещё она страшно тормозит.

UPD: а рекламная джинса от Blogeratorʼа особенно позорна.
netch80: (bird)
2016-11-29 09:49 am

mobile: Skylake без AVX

На свежекупленном лаптопе

model name : Intel(R) Pentium(R) CPU 4405U @ 2.10GHz
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave rdrand lahf_lm abm 3dnowprefetch epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust erms invpcid rdseed smap clflushopt xsaveopt xsavec xgetbv1 dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp

я понимаю, что "мобилко" 13″, но на этом SkyLake даже простейшего AVX нету.
Зато зачем-то popcnt, movbe и rdrand.
netch80: (bird)
2016-11-28 10:21 pm

ЖЖ офейсбучивается

ЖЖ то ли сходит с ума, то ли намеренно офейсбучивается - френдлента у данного юзера показывает только одну последнюю страницу (до 50) записей, а дальше, видите ли, ничего нету. Никакие явные /?skip=N не помогают - нету, и всё тут.
Настроек на эту тему не нашёл.
netch80: (finch)
2016-11-24 09:30 pm

Размеры бинарников под разные ISA

Удобно, когда пачка кросс-компиляторов доступна из коробки без мучений.

$ ls -ld qmodo*_s
-rwxrwxr-x 1 netch netch 344456 лис 24 21:19 qmodo_aa64_s
-rwxrwxr-x 1 netch netch 340376 лис 24 21:10 qmodo_amd64_s
-rwxrwxr-x 1 netch netch 531552 лис 24 21:25 qmodo_mips64_s
-rwxrwxr-x 1 netch netch 466088 лис 24 21:17 qmodo_ppc64_s
-rwxrwxr-x 1 netch netch 355752 лис 26 14:43 qmodo_rv_s
-rwxrwxr-x 1 netch netch 408640 лис 24 21:11 qmodo_s390x_s
-rwxrwxr-x 1 netch netch 336776 лис 24 21:35 qmodo_sparc64_s


Сборка, потом --strip-all. Везде gcc5 (Ubuntu 16.04) (Risc-V - gcc6), -O.
x86 таки почти всех победил (по размеру, а вы о чём подумали?)
Результат MIPS удивляет.
netch80: (bird)
2016-11-17 03:40 pm

У гармошки два конца

address.sin_port = htons( ( port & 0xff )<<8 | (port & 0xff00) >> 8);


Смысл этой конструкции от меня ускользает. (Особенно, когда через несколько строк address.sin_port передаётся в функцию, которая ждёт значение в host order.)

А если в Java написать Integer.reverse(x) вместо Integer.reverseBytes(x), без привлечения утёнка проблема не решается.
netch80: (bird)
2016-11-13 12:05 pm

UB reasoning (копия)

Дискуссия прошла в Fido, пересмотрел - думаю, стоит сделать копию в чём-то индексируемом.

Read more... )
Смотря на более поздние языки (от Java и вплоть до Go, Rust и прочих) - там все описанные проблемы „урезают“ - видимо, считают неподъёмным основной массе?
netch80: (bird)
2016-11-11 10:43 pm

О вводе-выводе, скорость и корректность

Дочка сдаёт задачи по программированию, как это сейчас модно, через e-judge и аналогичные системы.

Первая задача: много вывода. Лимит времени работы в системе - 100 мс. На моём десктопе показывает 45 мс. Вывод через cout << val. Вспоминаю рассказы про тормознутость iostreams, подсказываю про stdio. Переписывает, сдаёт. Локально время сократилось до 2 мс. В целевой системе - прошло.

Вторая задача: очень много ввода (максимум теоретически возможного по условиям - 20 миллионов intʼов). fscanf даёт 1.2 секунды. Ручная замена на враппер вокруг getc() - ~0.2 секунды. Лимит в системе тот же - 100мс. Всё равно много. Вытаскивает вчерашний вариант на Паскале, исправляет ошибки, отправляет. Проходит. Сравниваю время после локального freepascal. 3 миллисекунды(!)

Сначала я подумал, что случилось чудо и паскалевцы сумели оптимизировать до предела. Но решил посмотреть внимательнее. Когда ktrace показывает, что из файла на 10M целых читается только 256 байт... мягко говоря, странно. Пропущу пляски с бубном, но результат раскопок: во FreePascal двухбайтный integer. Соответственно, 10000000 превратилось на чтении обычным read(n) в... -27008. Последующий цикл чтения for i:=1 to n тупо выполнился ноль раз. А тесты как раз сошлись так, чтобы повторить эту ошибку.
Посмотрел, что там longint - 4 байта, заменил все integer на него. Время работы на те же 20M целых поднялось до 1.7 секунды. Что ж, отсутствие чуда уже доказано.

Вот как можно на таких допотопных средствах детей учить?
netch80: (bird)
2016-10-24 08:59 am

Всякая всячина, ветчина и ржавчина

Что-то Rust начинает удивлять "не по-детски". 320MB итогового пакета компилятора. 1.9GB для сборки. ~40 минут компиляции на вполне современном процессоре. И это ещё с внешним LLVM. Боюсь, со встроенным это бы утроилось.
GCC умеет несколько языков и занимает меньше :)