LINUX.ORG.RU

Избранные сообщения Bad_ptr

Почему так по-разному работает COUNT(*) в MySQL?

Форум — General

Прекрасно знаю, что COUNT(*) в InnoDB не торт... Но не до такой же степени!

Есть две таблицы:

| ...               | tab1 | tab 2|
|-------------------|------|------|
| Число строк, млн  |  3.2 |  4.0 |
| Объём на диске,ГБ |  6.0 |  7.6 |
| Число полей       |    4 |   41 |
| Число индексов    |    1 |   27 |

Вроде как никаких чудес, таблицы почти идентичны (не считая сложности второй), работа с ними идёт равно активно (они, вообще, для двух частей одних и тех же данных и 99% обращений идёт к обеим таблицам сразу).

Так вот, COUNT(*) во второй выполняется за ожидаемые 0.47 сек на холоде. Первая же таблица выполняет COUNT(*) за 7-10 минут!

Дело не в дисках, не в фрагментации — недавно вся БД переносилась на другой раздел, ничего не меняется...

Остальная работа (извлечение записей по индексам, JOIN, сортировки) работает отлично.

Есть мысли с чем такое поведение может быть связано?

 ,

KRoN73
()

Озвучка видео в линуксе

Форум — Multimedia

ЭТО НЕ ВОПРОС! ЭТО ГОТОВОЕ РЕШЕНИЕ!

sudo cast AP, ist76. Чот больше и не могу вспомнить кому будет интересно.

В начале 2000-х под офтопиком у меня был опыт озвучки короткометражки (не столько в микрофонном смысле, сколько в комплексном, наложение звуков взрывов, ударов, криков, музыки, автоматизация, эффекты, мастеринг). И теперь вот понадобилось сделать то же самое в онтопике.

Конечно, мое решение не единственное. Но я опишу здесь то, что взлетит в 99.999% случаев, т.к. состоит из проверенного временем минимального набора ПО. Решение дающее реально качественный результат на выходе.

Сейчас будет о том, как удобно и правильно озвучить абсолютно любое видео, в том числе, с возможностью переозвучить (ревер комнаты, шум, тихие фразы) диалоги из видеоряда.

Сначала теория.

Главные комплексные вопросы: Как синхронизировать начитку синхронного перевода или озвучки с исходным звуком и видеорядом? Как применить аудиоэффекты и чтобы каждый был в свое время, место и с определенными настройками? Как сделать 5.1 или вклиниться в исходный 5.1 или просто сделать 2.0 но на уровне профессионального качества?

Обычно начитывают в микрофон в отдельной программе и потом импортируют кусками в видеоредактор в дополнительную дорожку, подгоняя расположение фраз во времени с видеорядом. Или начитывают прямо в видеоредакторе. Но видеоредактор, он на то и видео, что не аудио и не имеет возможности полноценно работать со звуком. А если нужно добавить звук очень синхронно как в клипах? Или накидать синхронных шумов (пердежь, бьющееся стекло, выстрелы, скрип шагов по снегу, etc..)?

Выводы:

1) Нам нужна DAW (многодорожка, VST(i), LADSPA, automation и прочее).
2) DAW должна уметь мониторинг видео!

Для себя я выбрал Ardour.

Но тут есть нюанс. Ardour поддерживает видеодорожку, но с какой-то там конкретной версии. К тому же, эта шляпа поставляется в качестве отдельной фичи, и нужно конпелять с этим патчем (возможно я и плохо смотрел, тем не менее, зачем искать конкретные версии, возможно этой не будет в репозитории вашей системы или не будет готового пакета). Да и сам патч стартует сервер слушающий сокет и реализует какой-то свой протокол синхронизации. Это как удаление зубов через задний проход. А еще в этом патче есть php (по-ха-пэ!) — ну его нахер этот патч. Так что просто берем тот Ardour который есть в вашей системе.

ГЛАВНОЕ:

Не нужно искать DAW которая умеет видеомониторинг из коробки!
Любая нормальная DAW в линуксе умеет в jack!
Т.е. вы можете взять другую DAW вместо Ardour, я же рассказываю про Ardour.


Вот оно: jack, Ardour, xjadeo. Эти компоненты работают так, как нам нужно. Ardour и xjadeo синкуются через jack.

Описываю по шагам ваши действия:

1) Заканчиваем работу над видеороликом в видеоредакторе не обращая внимания на качество звука — тут главное качество видео.
2) Пережимаем с помощью ffmpeg видеоролик в *.avi (без аудио) говняного качества и/или без сжатия (для того чтобы воспроизведение видео не жрало ресурсы).
3) С помощью ffmpeg вычленяем исходное аудио из качественного видеоролика.
4) Стартуем jack (ставим желаемый samplerate, например 48000гц).
5) Создаем в Ardour проект (внимание на samplerate и fps!).
6) Импортируем в проект исходное аудио, вычленненое ранее с помощью ffmpeg (2.0, 5.1, какое оно там у вас было не важно).
7) Устанавливаем в Ardour опшн «Positional sync source» в значение «JACK».
8) Стартуем xjadeo: $ xjadeo -i 3 /path/do/govno-quality.avi

Картинко

Теперь можно полноценно работать над звуком! Можете начитывать в микрофон прямо просматривая видео. Делать дубли. Двигать, резать, клеить начитанное прямо в DAW и проверять в реальном времени как оно сходится с тем что происходит в видеоряде или соотносится с оригинальным аудио. Добавлять любое кол-во дорожек. Микшировать так как хочется. Применять эффекты и автоматизацию.

После того как вы завершили работу с звуковой частью вашего фильма — рендерите готовый проект в *.wav (умеет и 5.1 например) и склеиваете через ffmpeg старое видео и новое аудио в результирующий видеофайл. Все!

 , , ,

deep-purple
()

Альтернативы штатному препроцессору Си

Форум — Development

Собственно, сабж. Си, в отличии от многих других языков, обладает весьма скудным встроенным макроязыком (и С++ тоже, но там хотя бы есть куча штатного сахара из коробки + шаблоны). Возможно, существуют какие-то проекты по исправлению этого недоразумения?

Мне нравится концепция Vala. «Компилятор» этого языка по сути конвертирует ООП-код в plain C. Но, увы, он гвоздями прибит к glib, что очень плохо. Нет ли подобных проектов, но без привязки к каким-либо библиотекам?

Мои хотелки - некоторый уровень синтаксического сахара. Хотя бы наследование структур. В идеале, конечно, классы с виртуальными методами. Всяких исключений, множественного наследования, RTTI и т. д. не нужно.

Нужна конвертируемость в Си и отсутствие лишнего кода, ибо хочется это использовать с микроконтроллерами.

 ,

KivApple
()

Фильмы ужасов

Форум — Talks

Лор, а знаешь какие-нибудь реально страшные фильмы?

Все топы что я находил содержат фильмы столетней давности и всякие экшн/мелодраммы/etc типа 28 дней спустя.

 , ,

holuiitipun
()

Где взять энтропию для /dev/random и как её протестировать?

Форум — Talks

Наличие качественной энтропии крайне необходимо для ОС и критически влияет непосредственно на её безопасность, при использовании техник «случайное выравнивание адресного пространства» (ASLR)! Очень много случайных чисел также необходимо для криптографических операций: шифрования трафика, создания ключей и прочего.

Откуда брать случайные числа:

В системе одновременно можно запускать сразу несколько сервисов для создания энтропии.

Для безопасной работы необходимо >200бит/с энтропии!

$ cat /dev/random
$ reset

Если не секрет, откуда берёте энтропию Вы?

 , , , ,

multihead
()

Интересные аудио-подкасты

Форум — Talks

Надоело слушать на плеере музыку. Посоветуйте каких-нибудь аудиоподкастов по теме Linux'a и что вообще слушаете. На русском.

 

Centrin0
()

Сервер для кооперативного прохождения Brutal Doom

Форум — Games

Привет, ЛОР.

Мне нечем заняться, и я решил поднять сервер для кооперативного прохождения DOOM с модом Brutal Doom.

У каждого игрока есть две жизни на уровень, когда его убивают второй раз, он отправляется в режим наблюдателя до тех пор, пока кто-нибудь не активирует выход в конце уровня. Если все игроки израсходуют свои жизни на уровне, уровень придется проходить сначала.

Адрес сервера: doom.somestuff.org.ru:10666
Сайт: https://doom.somestuff.org.ru
Конференция в джаббере для обсуждения работы сервера: doom@conference.somestuff.org.ru

Пока всё работает в тестовом режиме, и не понятно, насколько оно будет стабильно, играбельно, весело и востребовано.

Для игры необходимо:

Первые два WAD'а с кампаниями распространяются свободно. Остальные четыре являются коммерческими продуктами, и вам придется самостоятельно приобретать их где-то на просторах Интернета, если по какой-то причине у вас их еще нет. На момент написания этого сообщения сервер запущен с freedoom1.wad, но в будущем он может потребовать любой из перечисленных выше WAD'ов.

Инструкция по установке:

# Создаем рабочую директорию:
mkdir -p ~/games/zandronum
cd ~/games/zandronum

# Качаем и распаковываем бинарники с движком:
[ `uname -m` == "x86_64" ] && \
    wget https://zandronum.com/downloads/zandronum2.1.2-linux-x86_64.tar.bz2 || \
    wget https://zandronum.com/downloads/zandronum2.1.2-linux-x86.tar.bz2
tar xvjf zandronum2.1.2-linux-*.tar.bz2
#Если у вас в репозиториях есть zandronum нужной версии, то можно поставить его оттуда, или собрать из исходников.

#Качаем мод Brutal Doom:
wget https://doom.somestuff.org.ru/brutalv20b.pk3
wget https://doom.somestuff.org.ru/DoomMetalVol4.wad

#Качаем WAD'ы с кампаниями:
wget https://doom.somestuff.org.ru/freedoom1.wad
wget https://doom.somestuff.org.ru/freedoom2.wad

#Переносим в рабочую директорию свои копии коммерческих WAD'ов:
cp /path/to/your/wads/*.wad ./

#Делаем первый тестовый запуск, настраиваем графику, управление, ник для сетевой игры:
./zandronum -file DoomMetalVol4.wad -file brutalv20b.pk3 -iwad freedoom1.wad

#Создаем скрипт для подключения к серверу:
echo 'connect doom.somestuff.org.ru:10666' > somestuff.autoconnect

#Подключаемся и играем:
./zandronum -file DoomMetalVol4.wad -file brutalv20b.pk3 -iwad freedoom1.wad +exec somestuff.autoconnect

 

Deleted
()

Не работает перемотка видео после кодирования с flv на mp4

Форум — Multimedia

Всем доброго времени суток. Конвертирую видео с помощью ffmpeg из flv в mp4 . После этого на сервере перестает работать стиминг(перемотка). Поискал по форумам и понял что не передаются мета данные, поэтому якобы и не работает перемотка. Можно ли это решить путем самого ffmpeg?

Конвертирую вот так ffmpeg -i video.flv video.mp4 -y

 

web163
()

Написание свободной(Free as in Freedom) книги-самоучителя по программированию: планы, цели, задачи

Форум — Development

Итак, я решил написать(или как вариант, собрать из кусочков) книгу-самоучилель по программированию, в которой бы не было глупых и нелепых ограничений на распространение. Однако копилефт я все же считаю приемлемым в данном случае. Общественным достоянием это не будет т.к. вполне могут найтись желающие использовать результат в своих проприетарных книгах, а проприетарные книги — плохо. Лицензия самого текста книги-учебника будет или Creative Commons Attribution-ShareAlike (что позволит без каких-либо проблем переиспользовать текст из википедии) или что-то вроде GNU Free Documentation License (без неизменяемых разделов естественно).

Лицензии всяких примитивных программок, написанных мной лично, будут вообще выложены под общественным достоянием, WTFPL или аналогичной лицензией т.к. являются тривиальными. Примерно вот так. Если я буду использовать чужие исходные тексты, они будут как включения, лицензируемые отдельно от всего остального. Проблем тут быть не должно.

Теперь к теме того, на кого книга ориентирована, какие начальные знания предполагаются, чему книга будет учить, какой первый ЯП взять и каков будет авторский самысел: С этим моментом я пока что не определился окончательно, и тут есть что обсудить. В частности, я не вижу особого смысла объяснять какие-то базовые понятия комбинаторики, об этом можно доступным языком прочитать из школьных учебников. Системы счисления(СС), перевод из одной СС в другую - вот это еще можно. One's и two's complement представления знаковых чисел — про это тоже можно написать. Если же человек не понимает комбинаторику, он ее быстро поймет на примере кода, который будет достаточно наглядно это показывать, и который всенепременно будет.
Пока что в качестве первого языка я склоняюсь к Си, и тому есть причины. Все прочие распространенные языки (кроме ассемблера, хотя его трудно назвать распространенным) не настолько близки к аппаратному уровню. Про нужность понимания на низком уровне написано тут http://russian.joelonsoftware.com/Articles/BacktoBasics.html https://habrahabr.ru/company/piter/blog/271347/ , не вижу смысла повторяться. Приведу лишь цитату:

«Просто плохой воркшоп попался», — скажете вы. Но на этом примере я хочу подчеркнуть более масштабную проблему: не изучив для начала C, программист оказывается лишен необходимых орудий, позволяющих понять, что именно происходит в используемой системе. Если вы — умный и пытливый питонщик, то вскоре докопаетесь до плотных пород языка C. Под этими горизонтами, скажут вам, «бойся драконов, костей и отладчиков». Соответственно, если вы не будете достаточно отважны и не проигнорируете предупреждений «да не берись ты за этот C», вы никогда не исследуете глубин, на которые можно забраться просто из любопытства.

Притом еще один важный момент: Си будет изучаться параллельно с ассемблером. Если речь идет об изучении ассемблера, необходимо четко зафиксировать то, на какой архитектуре это все происходит и в какой ОС. Так вот, ОС будет GNU/Linux а архитектура x86-64. Будут постоянно проводиться параллели между тем, что из себя представляет код на Си в текстовом виде, и тем, в какой текст на ассемблере его превращает компилятор. В связи с этим, первым делом будет рассказано о goto и конструкции if(условие) goto метка;. Про конструкции вида

if(условие)
{
  что-то_делаем;
}
else
{
  что-то_другое_делаем;
}
Будет рассказано немного позже, притом это будет рассказано и словами, и через написание эквивалентного кода через if(условие) goto метка;. Циклы, for(){} while{}, do{}while(), конструкция switch-case и break continue внутри них будут так же объясняться через все тот же if(условие) goto метка; притом будет делаться явный акцент на том, что намного лучше использовать нормальные циклы, чем лепить всюду этот условный goto. Кроме того, будет так же рассказано про Labels as Values. Почему так важна эта странная штука, if(условие) goto метка;? Потому что она имеет наипрямейшее отношение к тому, как работают ЭВМ, а всякие циклы СКРЫВАЮТ это. Рекурсия в Си будет объясняться только после того, как будет объяснено, что такое стекфрейм и соглашения вызова, будет сказано про оптимизацию хвостовой рекурсии, и о проблеме забивания стека, если такая оптимизация не происходит, притом это будет наглядно показано в ассемблере. Учиться отлаживать код надо будет тоже «с пеленок», притом отлаживать и ассемблер, и всякие там Си. Будет и про асм-вставки в Си, clobber list. В качестве ассемблера будет рассматриваться GAS, а никакой не NASM т.к. GCC умеет выплевывать ассемблер именно в GAS синтаксисе. Насчет выбора Intel или AT&T синтаксиса - тут я склонюсь пожалуй к тому, что надо ЗНАТЬ И УМЕТЬ ПОНИМАТЬ ОБА. Кроме того, GAS давно уже умеет в оба синтаксиса, так что проблем с этим не будет. Единственная проблема с GAS в том, что это однопроходной ассемблер, так что можно освоить и какой-нибудь NASM, YASM.

Первые хеллоуворды будут написаны вообще в особом стиле, без использования printf() и вообще без библиотеки Си; Будут использованы куски на ассемблере, которые делают системный вызов write и read, и с ними можно(нужно) будет линковаться, чтоб что-то вывести на экран. Будет рассказано и про printf естественно, но только когда будет совершенно четко ясно, что такое вообще va_list. Будет куча отсылок к драфту стандарта Си (недрафт почему-то платный). Будет так же рассказано про устройство ОС. В конце скорее всего будет дано задание сделать свою игрушечную ОС так что предполагается что человек к тому моменту должен уже отлично понимать всякие там связные списки, графы, очереди, спинлоки-аллокаторы свои уметь делать на асме при желании. Алгоритмы сортировки, обхода графов, хеш-таблицы, все это будет объяснено на языке Си, и плюсов вообще касаться я не буду.

Насчет графики: работу с протоколом иксов тоже можно будет рассказать, обработку нажатий клавиши. Правда там надо дофига писать про кучу всего, например что есть сокеты, есть AF_LOCAL... Тогда это можно еще и сетевому программированию учить на каких-нибудь беркли-сокетах.

Кроме того, после моей книги предполагается, что человек должен уметь заниматься такими ненужными (в GNU/Linux) на первый взгляд вещами, как крякинг, реверсинг, исправление ошибок в бинарниках, не обладая исходным текстом. Восстановление логики работы программы по дизасму. Ну и программирование в машинных кодах (без ассемблера, одним HEX редактором).

Как-то уж слишком дофига, не находите? Может быть не надо так глубоко во все это нырять? Жду предложений и критики по поводу того, что нужно, а чего не нужно писать. Возможно что я слишком много хочу.

cast ASM be_nt_all mister_VA

UPD: Программирование и отладка на C/ASM - Первые программы. Знакомство с C и ассемблером. Компиляция, линковка, код возврата. Вывод текста.

 , , ,

SZT
()

Видеолекции по математике для школьников

Форум — Science & Engineering

Собственно посоветуйте интересные видеолекций по математике для школьников. Ну или хорошие учебники.

 , ,

Solonix
()

Помогите составить SQL-запрос для вывода дерева комментариев.

Форум — Web-development

Самый простой и вместе с тем гениальный способ построения дерева, это не использовать никакие id, parent_id, не использовать никакие id_left, id_right смещения, какие там ещё виды дерева бывают...

Самый верный, ИМХО, способ, — сохранять полный путь, который проходит каждое сообщение.

Написали сообщение с ID = 1, затем на него ответили, ответ с ID = 2, а его путь, коли оно является ответом на первое сообщение, будет: «1 2».

Таблица вида

comment_id | thread_path
------------------------
         1 |           1
         2 |         1.2
         3 |         1.3

Где количеством отсутступов «вправо» в дереве является количество ответов в thread_path, и всего один SQL-запрос для вывода всего, с группировкой по дереву.

<?php $try = $dbh->query('SELECT * FROM forum GROUP BY thread_path'); ?>
<?php while ($row = $try->fetchArray()): extract($row); unset($row); ?>
<?php echo str_repeat('&nbsp; ', substr_count($thread_path, '.')); ?>
<?php echo $comment_text; ?>
<?php endwhile; ?>

Рабочий пример: http://spfng.com/forum/

Теперь вопрос. Я не знаю как сделать, чтобы выводить сообщения в обратном порядке, но при этом целиком сохранялось дерево ответов.

Подскажите? Как сделать, чтобы все корневые сообщения, у которых thread_path = comment_id, выводились в обратном порядке, ORDER BY comment_id DESC, но при этом все другие сообщения, которые являются ответами на корневые (которые начинаются как thread_path LIKE comment_id || ".%"), не меняли свой порядок вывода, а оставались как есть сейчас, ORDER BY comment_id ASC. Как-то так...

Это реально в один SQL-запрос уместить?

 ,

Spoofing
()

Генерация ID как на YouTube: зачем это надо и как это сделать?

Форум — Web-development

youtube.com/watch?v=xxxxx...

Первое что приходит в голову, это если мы используем файло-хостинг, то чтобы кто угодно не мог пройтись циклом по всем загруженным файлам от 1 до 10000000 и зная наших нерадивых пользователей, не скачать их секретные документы, которые они по наивности своей доверили нашему хостингу.

Второе, - сорт сокращения URL, можно заменить каждое 10-ое число буквой a, каждое 28 буквой z, ну и так далее, вплоть до спец символов. Вместо длинющего 10000000 получить грубо говоря AAAZ==.

Но не смотря на все эти ухищрения, не все сайты делают правильно, они делают ID из набора букв, но... заменив букву «a» на следующую по алфавиту «b» мы получаем по сути тот-же инкремент +1, и по можно зайти по любому адресу, запросив любой ID объекта. Вот например Reddit: https://www.reddit.com/comments/3xp8s2. От ID тут одно название. Можно делать инкремент букв руками.

Немножко погуглив нашёл такую функцию, alphaID: http://kvz.io/blog/2009/06/10/create-short-ids-with-php-like-youtube-or-tinyurl/

alphaID() генерирует из числа — слово, и наоборот, превращает слово — в число. Для сокращения нормально, но проблему безопасности, защиты от брутфорса оно не решает. Буквы просто заменяются на следующие по таблице ASCII и таким образом инкрементом перебираются все объекты.

Каким же образом генерировать псевдо-случайные ID? И надо ли это делать?

Не хочу использовать рандом, потому что рано или поздно такой рандом упрётся в бесконечный цикл, когда все возможные варианты N-значных ID уже сгенерированы и записаны в БД, а для новых осталось совсем немного свободных вариантов. В общем, плохо.

Нужно, если генерировать, то реально псевдо-рандом как на YouTube, а не просто инкрементальные a -> b делать.

Кто-нибудь может поделиться рецептом?

 ,

Spoofing
()

REST - ограничение доступа к публичному API

Форум — Development

День добрый.

Занесло меня на разработку серверной части достаточно крупного REST сервиса. Проект на Spring + Hibernate + Swagger. С социальным логином через Google и Facebook уже яснее. Но еще предполагается, что некоторая часть методов API будет доступна третьим лицам возможно с собственными клиентскими приложениями по подпискам или вроде того. То есть встал серьезный технический вопрос как это сделать. Кто-нибудь сталкивался с подобной задачей?

Сейчас рассматриваются варианты: через HTTP Basic аутентификацию , сертификаты и собственная реализация пересылки ключа через header или cookie. Первый вроде как подходит, там вообще обязательно использовать пару логин плюс пароль или можно свое что-то слать? Использование сертификатов показалось чересчур усложненным.

Еще вопрос: если генерировать ключ на подписчика, то какой алгоритм использовать? Какой-нибудь хэш? Или прокатит и случайный UUID?

 , , , ,

spoilt
()

набор не юного мастера паяльника 1 лвла

Форум — Talks

В связи с тем, что в ближайшее время появится возможность организовать свое пространство в соответствии со своими вкусами и интересами реквестирую список штучек, которые точно понадобятся начинающему «быдлоэмбедщику», учащемуся паять )))

есть кучка разных ланчпадов от Техаса, «бридборд» и проводочки

посоветуйте что именно понадобится из всякой рассыпухи и какой паяльничек и прочий «припой» брать? Также буду рад ссылочкам на гайды для обучаемых дебилов

ЗЫ Насколько кстати полезны видео от Ben Hack ? Вроде понятно объясняет

 ,

nerfur
()

Распределённая социальная система. Продолжение изысканий. Мысли вслух.

Форум — Talks

В продолжение тем, типа Распределёные форумы/блоги. Продолжаем разговор. Нужен совет. и подобных :)

Понимание того, как должна выглядеть и работать наша социальная система всё чётче кристаллизуется. Чую, скоро приступлю к практическим экспериментам :) Хотя в отсутствии коммьюнити, при наличии только собственных нод и одного источника данных, работать будет не так интересно.

...

Ознакомился я тут с относительно популярными в наше время готовыми решениями. Diaspora, Identica, GNU Social.

Основная проблема, не дающая им (ИМХО) нормально стартовать — отсутствие гейтов к имеющимся данным классических систем что сразу снижает интерес и малая польза от распределённости. Пользователь всё равно остаётся привязан к собственной ноде. Пусть даже в некоторых реализациях и возможен ручной перенос данных на другие ноды. Нет прямого обмена контентом между нодами. Только по подписке пользователей.

Думаю, более востребованная система, в отличие нынешних, должна предоставлять:

— Гейт-доступ к имеющимся материалам классических форумов и блогов. Тут понятно и без комментариев. Есть информация — есть пользователи.

— Автоматический обмен контентом не по подписке пользователя, а в рамках категории. Сейчас пользователь, ищущий что-то интересное, должен предварительно обыскивать остальные ноды сам. И только найдя нужное, может подписаться на потоки. Нужно, чтобы всё актуальное можно было найти на одной текущей ноде.

— Обмен пользовательскими данными. Пользователь должен уметь размножать свой идентификатор на более чем одну ноду. Чтобы при потере одной из нод из сети, он мог продолжить работу через другие ноды не перерегистрируясь и не перенося данные.

...

— Кстати, замечание — основной контент обязан быть публичным. Чтобы гости имели возможность читать статьи и обсуждения без предварительной регистрации.

Ну и проблема подобных систем — очень узкая трактовка материалов. Нужны не только блоги/микроблоги, но и публикация статей (в т.ч. Wiki), форумы/обсуждения, фотогалереи и т.п. Писал на этот счёт мысли в http://www.balancer.ru/g/p3864467

...

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

Зато довольно чёткие начальные представления по обмену данными.

Для хранения больших объёмов данных, картинок и аттачей, пока наиболее интересным вариантом выглядит IPFS. Основные плюсы:

— Файлы идентифицируются по хешу содержимого. Можно залить на разных нодах одни и те же файлы, у них останутся одни и те же идентификаторы.
— Система работает достаточно быстро. Я бы сказал, вполне на уровне нынешнего Web'а. Речь, конечно, о первой межнодовой передаче файла, потом он кешируется и отдаётся шустро.
— Система легко расширяется, софт на Golang прост в установке.
— Готовая прозрачная система гейтования. Можно использовать выдачу данных с гейтов сразу, не имея привязки к ним.

Минусы:

— Нет(?) вменяемого контроля наличия файлов в сети. Если все ноды-хранилища с файлом исчезнут, то никто не гарантирует доступность файла со временем
— Похоже, система разрабатывается одним человеком, что не очень хорошо гарантирует её будущее.

Для хранения, собственно, архива сообщений думаю попробовать Gittorrent. Не выгорит с ним (хотя почему нет?) можно будет прозрачно использовать обычный Git, хотя это снизит гибкость привязкой к серверам репозиториев.

Перемещено JB из general

 , , ,

KRoN73
()

Пользуясь моментом, хочу передать привет 178.248.233.6

Форум — Talks

Утилита ping доступна в любой системе, всегда можно отправить ICMP-запрос на любой хост, поэтому самый простой вариант «общения» между хостами — использовать протокол ICMP, в том числе и для получения звуковых уведомлений о важных системных событиях.

Отлавливать пакеты ICMP можно при помощи iptables.

# iptables -A INPUT -p icmp --icmp-type echo-request \
  -m conntrack --ctstate NEW \
  -m limit --limit 1/day --limit-burst 1 \
  -m length --length $((31337 + 28)) \
  -j LOG --log-prefix "PING? PONG! "

Теперь все ICMP-запросы размером 31337 байт (плюс 28 байт на заголовок) будут сохраняться в логах системы и о них можно узнать при помощи утилиты dmesg, далее нужно следить за лог-файлом /var/log/kernel и при наличии PING? PONG! и воспроизводить звуковое уведомление.

Скрипт одной командой.

#!/bin/bash

(
tail -f /var/log/kernel | awk '/PING\? PONG!/ { system("aplay -q \"/var/tmp/EVE Online - Notification Ping.wav\" &") }'
) &

Скачать EVE Online - Notification Ping.wav (0.6M)

Параметры ICMP-запроса, такие как размер пакета, можно использовать как своеобразный PIN-код, известный только владельцу хоста, и изменяя подобные параметры при ICMP-запросах можно сообщать о различных событиях, установив на каждое отдельное звуковое уведомление.

Передать привет:

# ping -c 1 -s 31337 spfng.com

Здесь не идёт речи о безопасности, её здесь нет и быть не должно: во-первых, установлен лимит на количество запросов, во-вторых на успешность запроса влияют заданные параметры пакета — перебрать все возможные варианты затратно и не принесёт никакого результата, в третьих, даже если и пройдет десяток-другой звуковых уведомлений от посторонних хостов — нет ничего страшного, но ICMP это пожалуй самый «естественный» способ создания подобных уведомлений.

Аналогичный способ для оповещения при подключении к SSH.

Спасибо, извините.

 , ,

Spoofing
()

Оптимизация nginx: 200k... 150k... 5k... 1k... wordpress... :D

Форум — Web-development

ощщем, ЛОР, пилю очередной тупняк, проходи мимо.

бенчмарк

ab -n 100000 -c 100 -k -H "Accept-Encoding: gzip, deflate" localhost/ 2>&1 | egrep "^(Failed|Requests)"

процессор Pentium G3258 с разгоном до 3.9GHz, остальное не важно. хотите пофапать на хай-лоад?

значит к делу. вот такой конфиг, (сервер _) отлавливает все запросы, которые не подходят под другие хосты.

server {
  listen 80;
  server_name _;

  location = /_.gif {
    empty_gif;
  }
}

ab localhost/_.gif выдаст вам результат в 200000 (двести тысяч!) запросов в секунду. empty_gif это модуль, поэтому такой быстрый.

к сожалению, со статикой картина чуть более печальна. ab localhost/index.html (файлик, что идет вместе с nginx'ом), сообщает о выполнении 125000 тире 150000 запросов в секунду, что тоже не так плохо. то есть, берете свой проект, оборачиваете всю динамику в fastcgi_cache, дабы nginx кэшировал запросы в статику и получаете очень быстрый сайт, мягко говоря.

рецепт успеха

worker_processes 4;
worker_priority -5;

worker_rlimit_nofile 9000;

timer_resolution 100ms;

events {
  use epoll;

  worker_connections 9000;
  multi_accept on;
}

чтобы не расходовать ресурс жесткого диска, I/O, желательно отключить логи, ну или, указать buffer=, да побольше.

error_log /var/log/nginx/error.log warn;

access_log /var/log/nginx/access.log main buffer=64k;
access_log off;
log_not_found off;

очень ресурсоемкая директива

ssi on;

с ней производительность просядет до копеечных 40000 тысяч на статике и на 20% на динамике, что лучше откажитесь от нее вообще. забудьте.

gzip on;

баллада о двух стульях и матери. придется выбирать между процессорным временем и линком. ресурсоемкая операция, производительность сервера страдает на 20%, но зато пропускная способность сети может быть увеличена в 3 раза за счет сжатия трафика.

open_file_cache max=9000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

с этим думаю ясно, кэш дескрипторов файлов. нужен.

забудьте о существовании if в nginx, не злоупотребляйте location, каждый отнимает много ресурсов.

любой другой ара-тюнинг по вкусу, на самом деле получится что-то вроде экономии на спичках, так например, tcp_nodelay дает разницу всего в 1000 запросов при 200000 к _.gif (empty_gif). посему смотреть нужно строго по ситуации, конкретных советов уже не дам.

теперь от статики к динамике. обязательно установить php opcache.

# curl http://php.net/distributions/php-5.5.23.tar.xz | tar -xJ -v
# cd php-5.5.23
# ./configure --disable-all --enable-opcache
# make build-modules
# install -m 755 modules/*.so /usr/lib/php/extensions
# echo "zend_extension=opcache.so" > /etc/php/conf.d/opcache.ini

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

upstream php-fpm {
  server unix:/var/run/php5-fpm.sock0 weight=100 max_fails=5 fail_timeout=5;
  server unix:/var/run/php5-fpm.sock1 weight=100 max_fails=5 fail_timeout=5;
}
location ~ \.php$ {
  try_files $uri =404;

  fastcgi_pass php-fpm;
  fastcgi_index index.php;

  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  include fastcgi_params;
}

настройка php-fpm'ов /etc/php/pool{0,1}.conf

[global]
log_level = notice
emergency_restart_threshold = 0
emergency_restart_interval = 0
process_control_timeout = 0
daemonize = yes

[pool0]
listen = /var/run/php5-fpm.sock0
listen.owner = www
listen.group = www
listen.mode = 0660

user = www
group = www

pm = static
pm.max_children = 8
pm.max_requests = 500

второй точно такой же

:%s/pool0/pool1

:%s/sock0/sock1

# /usr/sbin/php-fpm --fpm-config /etc/php/pool0.conf
# /usr/sbin/php-fpm --fpm-config /etc/php/pool1.conf
# /usr/sbin/nginx -t && /usr/sbin/nginx -s reload

а теперь получите пятикратный прирост производительности php. вот.

 , ,

Spoofing
()

Хороший учебник по схемотехнике

Форум — Linux-hardware

Посоветуйте сабж плиз.

Хотя даже не знаю правильно ли я это называю.
Интересует учебник радиолюбителя, какие делали для чего нужны, как их правильно применять, как правильно рассчитывать схемы...

Две основные просьбы:
- нужно для абсолютного нуба
- чтоб покрывались и современные темы, а не только то что было в 60-70х прошлого века

q11q11
()

Хочу научиться паять

Форум — Talks

Доброго времени суток, ЛОР.

Тема такая здесь наверняка была, но сейчас какой-то бум всяких микроконтроллеров, поэтому я решил, что в мои практически уже 20 лет как-то негоже не уметь паять, раз даже школьники могут.

В связи с чем вопрос: а какой паяльник-то покупать или как его хотя бы выбирать? Ни разу в руках его не держал, о процессе имею весьма смутное представление.
Для чего он мне нужен? А чёрт его знает, может, из ардуин всё тех же вундервафли лепить, может, технику какую дома починить. Просто хочу научиться хотя бы. Чего посоветуете?

UPD Важное уточнение: желательно, чтобы продавалось в мск и можно было взять буквально на днях; подарок же мне, любимому, а днюха совсем скоро.

 

Deleted
()

Научите правильно готовить монады через CPS

Форум — Development

Тут будет много букв, я морально готовился месяц, поэтому за объем заранее извиняйте. Сразу скажу - на ассемблерах я не писатель, и цель треда - не обсуждение дизайнерских решений, а производительность монад. Суть всплывёт ближе к концу (я надеюсь).

Представим, что мы моделируем некий процессор, у которого есть простой набор инструкций. С инструкций и начнем:

data Register = R1 | R2 | R3 | R4 | R5 | R6
                deriving (Show)
     
data Operator = ADD | SUB | MUL | DIV
              | LESS | EQUAL | AND | OR | NOT
              | MOV
              | JMT | JMF | JMP
              | PRN | NOP
                deriving (Show)

class OperandClass a where
   toOperand :: a -> Operand

instance OperandClass Register where
   toOperand = R

instance OperandClass Operand where
   toOperand = id

instance OperandClass () where
   toOperand _ = N

data Operand = R !Register | V !Double | I !Int | N
               deriving (Show)

type Instruction = (Operator, Operand, Operand) 

Иными словами, всё очень просто: инструкция - это кортеж оператора и операндов, операндом могут быть регистр, значение, или ничего.

Чтобы кодить на нашем псевдоассемблере, потребуется таки простенький компилятор. Цель его - записать все инструкции в списочек.

-- | Monad for programming instructions 

type ASM a = State [Instruction] a

compile :: ASM a -> [Instruction]
compile c = execState c []

op :: (OperandClass s, OperandClass d) => Operator -> s -> d -> ASM ()
op cmd src dst = modify $ \s -> s ++ [(cmd, toOperand src, toOperand dst)]

pos :: ASM Int
pos = liftM length get

nop :: ASM Int
nop = do { p <- pos; op NOP () (); return p}

putOp :: (OperandClass s, OperandClass d) => Int -> Operator -> s -> d -> ASM ()
putOp p cmd src dst = do
    let instr = (cmd, toOperand src, toOperand dst)
    (before,after) <- liftM (splitAt p) get 
    put $ before ++ instr : tail after

Тут, опять же, ничего сложного. Для наглядности, немного забегая вперед, приведу пример кода на этом «ассемблере». Данный код считает квадратный корень заданного числа методом Герона с заданным приближением (числом шагов):

-- | Heron's method to calculate square root
-- Inputs:  r1 - value to calculate square root from
--          r2 - number of iterations
-- Outputs: r6 - output value
heron :: ASM ()
heron = do
   op MOV (V 1) R5
   op MOV (V 0) R3
   iterStart <- pos
   op MOV R3 R4
   op EQUAL R2 R4
   ifFalse <- nop
   op MOV R1 R6
   op DIV R5 R6
   op ADD R5 R6
   op MUL (V 0.5) R6
   op MOV R6 R5
   op ADD (V 1) R3
   op JMP (I iterStart) ()
   loopEnd <- pos
   putOp ifFalse JMT R4 (I loopEnd)
   op PRN R6 ()

Надеюсь, тут становится ясна необходимость в действиях pos, nop, и putOp, описанных ранее - их суть в расстановке меток и замене пустышек на инструкции, привязанные к меткам. Не самое элегантное, но, как по мне, вполне решение для организации циклических конструкций.

Идём дальше. Чтобы это всё выполнять, нужна ещё одна монада:

-- | Monad for executing instructions

data Registers = Registers
               { r1 :: !Double
               , r2 :: !Double
               , r3 :: !Double
               , r4 :: !Double
               , r5 :: !Double
               , r6 :: !Double
               } deriving (Show)

initialRs :: Registers
{-# INLINE initialRs #-}
initialRs = Registers
            { r1 = 0
            , r2 = 0
            , r3 = 0
            , r4 = 0
            , r5 = 0
            , r6 = 0
            }

type CPU a = StateT Registers IO a

execute ::Registers -> [Instruction] -> IO Registers
execute rs code = execStateT (exec code) rs
  where
   {-# INLINE exec #-}
   exec ((JMP, I pos, _    ):is) = {-# SCC "JMP" #-} exec $! drop pos code
   exec ((JMF,   reg, I pos):is) = {-# SCC "JMF" #-} readVal reg >>= \v ->
                                                     exec $! if toBool v
                                                             then is
                                                             else drop pos code
   exec ((JMT,   reg, I pos):is) = {-# SCC "JMT" #-} readVal reg >>= \v ->
                                                     exec $! if toBool v
                                                             then drop pos code
                                                             else is
   exec ((ins,   src,   dst):is) = {-# SCC "OP"  #-} execOP ins src dst >> exec is
   exec []                       = return ()

execOP :: Operator -> Operand -> Operand -> CPU ()
{-# INLINE execOP #-}
execOP ADD   src dst = {-# SCC "ADD"   #-} arith ADD   src dst
execOP SUB   src dst = {-# SCC "SUB"   #-} arith SUB   src dst
execOP MUL   src dst = {-# SCC "MUL"   #-} arith MUL   src dst
execOP DIV   src dst = {-# SCC "DIV"   #-} arith DIV   src dst
execOP LESS  src dst = {-# SCC "LESS"  #-} logic LESS  src dst
execOP EQUAL src dst = {-# SCC "EQUAL" #-} logic EQUAL src dst
execOP AND   src dst = {-# SCC "AND"   #-} logic AND   src dst
execOP OR    src dst = {-# SCC "OR"    #-} logic OR    src dst
execOP NOT   src dst = {-# SCC "NOT"   #-} logic NOT   src dst
execOP MOV   src dst = {-# SCC "MOV"   #-} readVal src >>= \v -> putVal dst $! v
execOP PRN   src _   = {-# SCC "PRN"   #-} readVal src >>= \v -> liftIO $ print v 

arith :: Operator -> Operand -> Operand -> CPU ()
{-# INLINE arith #-}
arith op src dst = do
    v1 <- readVal src
    v2 <- readVal dst
    case op of
       ADD -> putVal dst $! v2 + v1
       SUB -> putVal dst $! v2 - v1
       MUL -> putVal dst $! v2 * v1
       DIV -> putVal dst $! v2 / v1

logic :: Operator -> Operand -> Operand -> CPU ()
{-# INLINE logic #-}
logic op src dst = do
     v1 <- readVal src
     v2 <- readVal dst
     case op of
        LESS  -> putVal dst $! fromBool $ v2 <  v1
        EQUAL -> putVal dst $! fromBool $ v2 == v1
        AND   -> putVal dst $! fromBool $ toBool v1 && toBool v2
        OR    -> putVal dst $! fromBool $ toBool v1 && toBool v2
        NOT   -> putVal dst $! fromBool . not . toBool $ v1

fromBool :: Bool -> Double
{-# INLINE fromBool #-}
fromBool True  = 1
fromBool False = 0

toBool :: Double -> Bool
{-# INLINE toBool #-}
toBool 0 = False
toBool _ = True

readVal :: Operand -> CPU Double
{-# INLINE readVal #-}
readVal (R R1) = gets r1
readVal (R R2) = gets r2
readVal (R R3) = gets r3
readVal (R R4) = gets r4
readVal (R R5) = gets r5
readVal (R R6) = gets r6
readVal (V v)  = return v

putVal :: Operand -> Double -> CPU ()
{-# INLINE putVal #-}
putVal (R R1) v = modify $ \s -> s { r1 = v }
putVal (R R2) v = modify $ \s -> s { r2 = v }
putVal (R R3) v = modify $ \s -> s { r3 = v }
putVal (R R4) v = modify $ \s -> s { r4 = v }
putVal (R R5) v = modify $ \s -> s { r5 = v }
putVal (R R6) v = modify $ \s -> s { r6 = v }

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

Вот и всё!

Полная версия кода доступна на Гитхабе.

С файликом, загруженным в ghci, можно поиграться, например, так:

let h = compile heron
execute (initialRs {r1 = 25, r2 = 4}) h

5.015247601944898 Registers {r1 = 25.0, r2 = 4.0, r3 = 4.0, r4 = 1.0, r5 = 5.015247601944898, r6 = 5.015247601944898}

Но самое важное для меня в данной ситуации - это время, за которое наш компьютер посчитает 10 000 корней. Входные данные и скрипт для запуска есть в репозитории:

$ ghc --make -O3 Asm.hs
$ ./measure.sh

Судя по результатам профайлера, основное время мы таки проводим в нашем процессоре:

COST CENTRE MODULE    %time %alloc

OP          Main       33.6   34.2
PRN         Main       21.4   23.0
READ        Main       16.4   12.8
MOV         Main        8.8   13.2
ADD         Main        5.4    6.7
DIV         Main        3.3    3.7
EQUAL       Main        3.1    3.4
MUL         Main        2.7    3.0
JMT         Main        2.3    0.0
JMP         Main        1.9    0.0


                                                                  individual     inherited
COST CENTRE  MODULE                             no.     entries  %time %alloc   %time %alloc

MAIN         MAIN                                52           0    0.7    0.0   100.0  100.0
 JMT         Main                               113      200000    2.3    0.0    80.7   85.4
  OP         Main                               114     1610000   32.8   33.3    78.3   85.4
   PRN       Main                               121       10000   21.4   23.0    21.4   23.0
   EQUAL     Main                               120      200000    2.7    3.2     2.7    3.2
   JMP       Main                               119      200000    1.9    0.0     1.9    0.0
   MUL       Main                               118      200000    2.7    3.0     2.7    3.0
   ADD       Main                               117      400000    5.4    6.7     5.4    6.7
   DIV       Main                               116      200000    3.3    3.7     3.3    3.7
   MOV       Main                               115      600000    8.2   12.6     8.2   12.6
 EQUAL       Main                               111           0    0.4    0.2     0.4    0.2
 MOV         Main                               108           0    0.6    0.6     0.6    0.6
 OP          Main                               106       40000    0.8    0.9     0.8    0.9
  JMT        Main                               112       10000    0.0    0.0     0.0    0.0
  EQUAL      Main                               110       10000    0.0    0.0     0.0    0.0
  MOV        Main                               107       30000    0.0    0.0     0.0    0.0
 ITER        Main                               105       10000    0.4    0.1     0.4    0.1
 READ        Main                               104           1   16.4   12.8    16.4   12.8
 CAF         Main                               103           0    0.0    0.0     0.0    0.0
  READ       Main                               109           0    0.0    0.0     0.0    0.0

Т.о., исполнение собственно операций (кроме ввода-вывода) занимает около 70% всего времени.

Внимание, суть!. Интересно, как зависит время выполнения от способа организации (или, если хотите, реализации) главной монады в тесте - CPU. Самое простое для начала - попробовать готовые реализации.

Мои результаты:

  • 0.37с - для монады CPU, реализованной поверх пакета transformers
  • 0.39c - для mtl
  • 0.42c - для contstuff

ХаскельВики рекомендует путь джедаев - ручной анроллинг стэков трансформеров и(ли) переход на CPS. Переход на CPS - вообще вещь легендарная, в иных историях успеха оно ускоряет код раз так в 4-8. Проверим:

newtype CPU a = CPU { runCPU :: forall r. Registers -> (a -> Registers -> IO r) -> IO r }

instance Monad CPU where
   return = retCPU
   (>>=)  = bindCPU

instance MonadIO CPU where
   liftIO = lioCPU

retCPU :: a -> CPU a
{-# INLINE retCPU #-}
retCPU x = CPU $ \s k -> k x s

bindCPU :: CPU a -> (a -> CPU b) -> CPU b
{-# INLINE bindCPU #-}
bindCPU (CPU m) f = CPU $ \s0 k -> m s0 $ \a s1 -> runCPU (f a) s1 k

lioCPU :: IO a -> CPU a
{-# INLINE lioCPU #-}
lioCPU f = CPU $ \s k -> f >>= \x -> k x s

get :: CPU Registers
{-# INLINE get #-}
get = CPU $ \s k -> k s s

gets :: (Registers -> a) -> CPU a
{-# INLINE gets #-}
gets f = get >>= \s -> return $! f s

put :: Registers -> CPU ()
{-# INLINE put #-}
put s = CPU $ \_ k -> k () s

modify :: (Registers -> Registers) -> CPU ()
{-# INLINE modify #-}
modify f = get >>= \s -> let s' = f s in put $! s'

Хотите верьте, хотите нет - такой вариант показал результат в 0.41c. Я в печали.

При ручном анроллинге (без CPS):

newtype CPU a = CPU { runCPU :: Registers -> IO (Registers, a) }

instance Monad CPU where
   return = retCPU
   (>>=)  = bindCPU

instance MonadIO CPU where
   liftIO f = CPU $ \s -> f >>= \x -> return (s, x)

retCPU :: a -> CPU a
{-# INLINE retCPU #-}
retCPU x = CPU $ \s -> return (s, x)

bindCPU :: CPU a -> (a -> CPU b) -> CPU b
{-# INLINE bindCPU #-}
bindCPU m f = CPU $ \s -> do (s', a) <- runCPU m s
                             runCPU (f a) s'

get :: CPU Registers
{-# INLINE get #-}
get = CPU $ \s -> return $! (s, s)

gets :: (Registers -> a) -> CPU a
{-# INLINE gets #-}
gets f = get >>= \s -> return $! f s

put :: Registers -> CPU ()
{-# INLINE put #-}
put s = CPU $ \_ -> return (s, ())

modify :: (Registers -> Registers) -> CPU ()
{-# INLINE modify #-}
modify f = get >>= \s -> let s' = f s in put $! s'

...всё несколько лучше, удалось получить 0.34с, но это всё равно не тот прирост, который я ожидал.

Данные эксперименты и опыт коллег, которые-делали-почти-то-же-самое-и-у-них-получилось, наталкивают на мысли, что что-то где-то пошло не так. Поэтому мой вопрос светлейшим умам форума сего - как воспроизвести те впечатляющие результаты с анроллингом и CPS? Какую деталь я мог упустить?

Для вашего удобства, весь код в его текущем состоянии выложен на Гитхабе, каждый вариант в своей ветке.

Простите ещё раз за такую простыню и неровный почерк. Всем любви!

 ,

yoghurt
()