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

[header]

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

Боевой сдвоенный походный оксиморон, 1 экз.

Некая спека говорит о типах данных

String: Alpha-numeric free format strings, can include any character or punctuation except the delimiter. All char fields are case sensitive (i.e. morstatt ≠ Morstatt).

Так всё-таки alpha-numeric или оно can include punctuation? Или вообще except the delimiter?
netch80: (Default)
2017-08-08 04:11 pm

О разуме компиляторов

Исходник:

bool FixMessage::isResendable() const
{
    unsigned type = getType();
    return type != FIX_MT_LOGON && type != FIX_MT_HEARTBEAT &&
           type != FIX_MT_TEST_REQUEST && type != FIX_MT_RESEND_REQUEST &&
           type != FIX_MT_SEQ_RESET && type != FIX_MT_LOGOUT;
}


Выхлоп gcc:

0000000000438570 <_ZNK10FixMessage12isResendableEv>:
  438570:       8b 4f 0c                mov    0xc(%rdi),%ecx
  438573:       b8 01 00 00 00          mov    $0x1,%eax
  438578:       83 e9 30                sub    $0x30,%ecx
  43857b:       83 f9 11                cmp    $0x11,%ecx
  43857e:       77 12                   ja     438592 <_ZNK10FixMessage12isResendableEv+0x22>
  438580:       b8 37 00 02 00          mov    $0x20037,%eax
  438585:       48 d3 e8                shr    %cl,%rax
  438588:       83 e0 01                and    $0x1,%eax
  43858b:       48 83 f0 01             xor    $0x1,%rax
  43858f:       83 e0 01                and    $0x1,%eax
  438592:       f3 c3                   repz retq 


Кто-то догадался, что сократить проверку диапазона близких значений вычитанием базы - отлично.
Беззнаковое сравнение результата вычитания - очень остроумно.
xor с rax, когда достаточно с eax - чего пытаются добиться?
Финальный and с константой - разве из предыдущих команд не ясно, что там останется один бит?

Считаем контрольную сумму:

unsigned checksum(const char *m_begin, const char *m_before_csum)
{
    unsigned csum = 0;
    for (const char *p = m_begin; p != m_before_csum; ++p) {
        csum += *p;
    }
    csum &= 0xff;
    return csum;
}


Генерируем с векторизацией. Не буду приводить всю сумасшедшую простыню, только основной цикл:

        pxor    %xmm0, %xmm0
        addq    %rdi, %r9
        xorl    %edi, %edi
        pxor    %xmm6, %xmm6
        pxor    %xmm4, %xmm4
.L9:
        movdqa  (%r9), %xmm3
        movdqa  %xmm6, %xmm1
        movdqa  %xmm4, %xmm5
        addq    $1, %rdi
        pcmpgtb %xmm3, %xmm1
        movdqa  %xmm3, %xmm2
        addq    $16, %r9
        cmpq    %rdi, %rdx
        punpcklbw       %xmm1, %xmm2
        punpckhbw       %xmm1, %xmm3
        pcmpgtw %xmm2, %xmm5
        movdqa  %xmm2, %xmm1
        punpckhwd       %xmm5, %xmm2
        punpcklwd       %xmm5, %xmm1
        movdqa  %xmm4, %xmm5
        pcmpgtw %xmm3, %xmm5
        paddd   %xmm1, %xmm0
        paddd   %xmm2, %xmm0
        movdqa  %xmm3, %xmm2
        punpcklwd       %xmm5, %xmm2
        paddd   %xmm2, %xmm0
        movdqa  %xmm0, %xmm1
        movdqa  %xmm3, %xmm0
        punpckhwd       %xmm5, %xmm0
        paddd   %xmm1, %xmm0
        ja      .L9


Кто может объяснить, чем нуль в xmm4 принципиально отличается от нуля в xmm6, и почему их нельзя было объединить?

В пропущенной части: до начальной границы 16 байт - короткий простой цикл по байту, но после последней такой границы - цикл развёрнут в 15 отдельных групп со сравнением в каждой на достижение конца входного массива.

Замена char на unsigned char убирает только сравнения (pcmpgt*). Два разных нуля остаются.

За окном шёл снег и два нулевых регистра.
netch80: (Default)
2017-08-08 04:05 pm

^? под иксами

Вот XKB весь из себя такой конфигурируемый в 10 слоёв абстракции, но что происходит при отработке Ctrl - зашито в код намертво:

char
XkbToControl(char ch)
{
    register char c = ch;

    if ((c >= '@' && c < '\177') || c == ' ')
        c &= 0x1F;
    else if (c == '2')
        c = '\000';
    else if (c >= '3' && c <= '7')
        c -= ('3' - '\033');
    else if (c == '8')
        c = '\177';
    else if (c == '/')
        c = '_' & 0x1F;
    return c;
}


и в этом есть несколько совершенно неожиданных вещей (например, почему "забой", который 0x7f и традиционно передаётся как ^?, они сделали ^8, а ^? даёт то же, что ^_ ?)

Похоже, это очередное место типа "40 лет назад сделали на 'отцепись', а теперь фиг поменяешь".

Да, и место, где эта функция, совершенно "ожидаемо" - XKBBind.c в libX11 (что в этой трансляции от слова bind?)
netch80: (Default)
2017-07-05 07:13 am

pip upgrade issues

После апгрейда убунты 14.04 -> 16.04, оказалось, залип pip2 в состоянии "я не знаю, что тут у вас, но я хочу версию 1.5.4, и идите к лешему".
После ручной замены на актуальную (8.1.1) в его стартовом скрипте - он даже дал себя проапгрейдить реально и заменил этот скрипт на такой, где версия не вшита.

Что полечилось - хорошо, но такой стиль бутстрапинга как-то смущает задним числом.
netch80: (Default)
2017-07-04 10:19 am

Go, init, go

Я понял, какой программе переписка на Go безусловно на пользу: это systemd-init.

Вторым должно пойти /rescue/* из FreeBSD. И, в принципе, на этом список кончается :)
netch80: (Default)
2017-07-02 09:57 pm

FreeBSD libm и точность функций

Программа:

#include <math.h>
#include <mpfr.h>
#include <stdio.h>

double fpu_sin(double x) {
  double r;
  r = sin(x);
  return r;
}

int main() 
{
  int i;
  int cd = 0;
  for (i = 0; i < 3000000; ++i) {
    double x = i * 1.0e-6;
    double r1 = fpu_sin(x);
    double r2;
    mpfr_t mx, mr2;
    mpfr_init2(mx, 53);
    mpfr_init2(mr2, 53);
    mpfr_set_d(mx, x, MPFR_RNDN);
    mpfr_sin(mr2, mx, MPFR_RNDN);
    r2 = mpfr_get_d(mr2, MPFR_RNDN);
    mpfr_clear(mr2);
    if (r1 != r2) {
      printf("Mismatched: x=%.20lg(%a)", x, x);
      printf(" r1=%.18lg(%a)", r1, r1);
      printf(" r2=%.18lg(%a)", r2, r2);
      printf("\n");
      if (++cd > 10) {
        break;
      }
    }
  }
  return cd ? 1 : 0;
}


На glibc 2.23 расхождений нет, программа выдаёт пустой выхлоп.

На FreeBSD (10.3, amd64) их много, вот первые несколько:

Mismatched: x=0.00260599999999999981(0x1.5592d98bf7f06p-9) r1=0.00260599705034083228(0x1.5592c0359972bp-9) r2=0.00260599705034083185(0x1.5592c0359972ap-9)
Mismatched: x=0.0098189999999999996(0x1.41bfbdf090f73p-7) r1=0.00981884222127722001(0x1.41be6b1ccbce4p-7) r2=0.00981884222127721827(0x1.41be6b1ccbce3p-7)
Mismatched: x=0.0187539999999999998(0x1.3343fa2ad3e92p-6) r1=0.0187529006832448421(0x1.333f5dc8f0659p-6) r2=0.0187529006832448386(0x1.333f5dc8f0658p-6)
Mismatched: x=0.0191819999999999977(0x1.3a4723aafff36p-6) r1=0.0191808236882919231(0x1.3a42349ce64acp-6) r2=0.0191808236882919196(0x1.3a42349ce64abp-6)


везде на 1 бит, но заметно.

Хм, я думал, что уж требования IEEE754 будут выполнять.
Или не верить MPFR? Это, кажется, уже перебор будет.
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.

Процитирую, чтобы была копия.

Edit (or create) the file:

~/.config/gtk-3.0/settings.ini

And add the following:

[Settings]
gtk-primary-button-warps-slider = false

Идеального лечения всё равно не даёт (например, нажатие в любом месте длинной полосы текущей позиции - игнорируется, воспринимается только нажатие за её пределами), но уже кое-что.
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.