Yuriy Nazarov
Люблю machine learning
Меня всегда интересовал вопрос: «В чём основная сложность разработки плагинов для IDE для динамических языков?». Посмотрев код плагина поддержки Perl для Eclipse и почитав форумы, я обнаружил что порой программа может быть правильно разобрана на лексемы только самим интерпретатором, например в случае, когда порядок разбора зависит от уже произведённых действий при разборе. Наглядный пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/usr/bin/perl BEGIN { if(0.5 < rand(1)){ require Mod1; Mod1->import( 'one' ); } else{ require Mod2; Mod2->import( 'one' ); } } $_ = ''; print one / 25 ; # / ; die "this dies!"; |
В котором последняя строка может содержать как регэксп так и деление в зависимости от прототипа загруженной функции. Читать далее
Не отпускает меня эта[1][2] вычислительная задачка. Нафигачил её теперь на js. С блэкджеком и шлюхами Web workers. В итоге получилось около 40 секунд(в Chrome) — быстрее чем нативный код (сгенерированный gcc-4.4 с -O3) в один поток! Выложена на GitHub Pages. Файл с исходными данными.
Читать далее
В этой записи я попытаюсь рассказать о реализации части процессорного ядра, использующего подмножество команд, используемых микроконтроллерами с архитектурой AVR. Проект далёк от завершения, но помигать светодиодом уже можно ;-) Например так:
Здесь правые 8 светодиодов показывают значение регистра R20, а левые 8 — значение IP(PC). Немного описания далее. Читать далее
Идея относительно анонимной публикации данных.
Окружение: наличие каких-нибудь сервисов вроде голосовалок, большое количество слабо контролируемых машин для массовки и на пару порядков меньшее число полностью контрорлируемых машин.
Заранее определяется список голосовалок и передаётся всем машинам, после чего все голосуют в одной(хотя можно и в нескольких) случайной голосовалке. Массовка голосует за случайный пункт, а полностью контролируемая за нужный. В итоге результаты сваливаются в нужную сторону, а для определения источника данных необходимо подробно рассмотреть десятки-сотни машин.
Доступность данных низкая, но если обеспечить контроль целостности, они или будут валидные или их не будет.
В ходе всех этих развлечений с оптимизациями обнаружился интересный, но очень неприятный эффект. Результат вычислений для разных компиляторов и разных флагов оптимизации порой значительно менялся.
Для более удобного наблюдения этого эффекта был выбран простой пример(полный код на github):
1 2 3 4 5 |
int i; long double res; for(i=0;i<100000000;i++){ res += cos(i); } |
В этом маленьком тесте изменение результата от изменения флагов обнаружить не удалось, но всё равно обилие результатов удивляет — 5 различных, с 13 совпадающими знаками из 15-17 возможных для double.
Исходник и компилятор | Результат | Время выполнения, с |
Assembler | 1.53436944477410652787 | 3.81 |
gcc long | 1.53436944477462278158 | 4.4 |
gcc double | 1.53436944477389380914 | 4.4 |
icc long | 1.53436944477397574360 | 6.88 |
icc double | 1.53436944477334602510 | 1.50 |
*результаты по одному измерению, по этому совсем серьёзно воспринимать их не стоит. Время указано для процессора FX-8120
p.s. ну и обнаружилось, что написание кода на ассемблере пока ещё не абсолютно потеряло смысл — получился до 15% быстрее, чем на C.
Сразу извиняюсь за название — взято с потолка.
Неудержался и нафигачил вычислительную задачу, которую уже упоминал в прошлых топиках на CUDA. Ничего хитрого не делал — просто расставил директивы __device__.
В итоге получилось даже медленнее чем на CPU раз в 5 :’-(
Сей ужас можно увидеть здесь.
Каким бы тёплым и ламповым старый софт не был, но рано или поздно от него приходится отказываться, и сейчас я покажу это на примере компиляторов.
Допустим у нас есть приложение, которое выполняет некоторые вычисления.
Попробуем скомпилировать его различными версиями gcc и icc. И измерим время выполнения. Опции компиляции следующие:
1 2 |
gcc-4.X -std=c99 -O3 Puncare_Map_ADgyro_v.1.1_win.c time_measurement.c -lm -o linear_4.X icc -std=c99 -O2 Puncare_Map_ADgyro_v.1.1_win.c time_measurement.c -lm -o linear_icc -static |
Версия компилятора | Время выполнения,c | Во сколько раз медленнее лидера |
gcc-4.1 | 70.0 | 3.68 |
gcc-4.3 | 45.3 | 2.38 |
gcc-4.4 | 45.9 | 2.42 |
gcc-4.5 | 34.9 | 1.84 |
gcc-4.6 | 34.7 | 1.83 |
gcc-4.7 | 34.9 | 1.84 |
icc-13.1.1 | 19.0 | 1.0 |
Спасибо ребятам из StartSSL за бесплатные сертификаты. :-)
Достаточно: зарегаться у них, поднять у себя почтовый сервер для валидации домена, пройти валидацию и сертификат у вас в кармане.
Добавляем его в конфиг HTTP-сервера и получаем что-то вроде: https://8052.ru
Одним из возможных вариантов мне видится:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/usr/bin/perl use strict; use warnings; use MyExceptions; use MyTry; try { MyExceptions::SomeError2->throw(); } catch {MyExceptions::SomeError1->test || MyExceptions::SomeError2->test} by { print "Catched\n"; print $_->description; } catch {MyExceptions::SomeError0->n} by { print "Catched exception 0\n"; }; #<-- semicolon must be here |
Допустим вам нужно предоставить доступ себе к какому-нибудь файлу/папке как члену группы владельца файла, так как самого владельца, в данном случае, изменить нет возможности. Например разрешить просмотр общих папок в VirtualBox в гостевой ОС на базе линукс. Казалось бы, что может быть проще?
1 |
usermod -a -G vboxsf <username> |
Но это изменение не повлияет на уже открытые сессии(если честно, я не понимаю что именно понимать под сессией). Хотя для обхода этого есть хак.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# How to add user into group, and make changes take effect *without logout/login*: the *newgrp* command # # Do note that this method will only update the groups, in the current shell session (and its child-processes). # New shell sessions will not have the groups updated - either use this method to update the groups in each shell # session, or logout/login to make the group update permanent by default # # In short: # $ sudo adduser user_x my_grp # $ newgrp my_grp && newgrp # # Here is the rundown annotated: #Add user_x into group sambashare user_x@stest:~$ sudo adduser user_x sambashare user_x@stest:~$ id uid=1001(user_x) gid=1002(user_x) groups=1002(user_x),20(dialout) #changes did not take effect user_x@stest:~$ newgrp user_x@stest:~$ id uid=1001(user_x) gid=1002(user_x) groups=1002(user_x),20(dialout) #changes still did not take effect user_x@stest:~$ newgrp sambashare user_x@stest:~$ id uid=1001(user_x) gid=115(sambashare) groups=1002(user_x),20(dialout),115(sambashare) #changes *did* take effect now: # - changed 'gid=115(sambashare)' # - appended '115(sambashare)' user_x@stest:~$ newgrp user_x@stest:~$ id uid=1001(user_x) gid=1002(user_x) groups=1002(user_x),20(dialout),115(sambashare) #reestablished 'gid=1002(user_x)' # all done now |
P.S. и да, я не понимаю, из-за чего (софт/ядро/принципы *nix) так, но по крайней мере в Ubuntu 10.04/12.04 поведение такое.