Hatred's Log Place

DON'T PANIC!

Aug 20, 2014 - 2 minute read - programming

hex ↔ bin в уме

Однажды писал про двоичные литералы в GCC: /post/2009-10-02_13.44_0b00100100, новый стандарт C++14 закрепил их в C++.

Но тут я хотел бы рассмотреть лёгкий способ перехода в уме между hex и bin представлениями.

Aug 19, 2014 - 1 minute read - programming c++

C++14: Done

Стандарт отправился в печать: https://isocpp.org/blog/2014/08/we-have-cpp14

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

May 30, 2014 - 2 minute read - programming c++ туризм maps

erase_if

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

May 28, 2014 - 1 minute read - programming c++

Const correctness

Ничего нового, просто ссылки:

  1. http://www.parashift.com/c++-faq/const-correctness.html - разные аспекты
  2. http://www.cprogramming.com/tutorial/const_correctness.html - для чего нужно и почему, а так же логическая и побитовая константность.

Если коротко, то что даёт применение ключевого слова const везде, где это уместно: <WRAP center round tip 60%>

  1. Уберегает вас от некоторых ошибок, связанных с внезапным изменением данных в каких-то вызовых. Т.е. добавляет безопасности.
  2. Автодокументирование кода: вы выдите const => вы знаете, что данные не меняются ни в этом вызове, ни далее по иерархии.

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

Логическая константность - когда при вызове какие-то поля могут меняться, но данные, отвечающие за логику класса не изменяются.

Обычно последнее связано с полями, которые имеют спецификатор mutable. Для чего они нужны? Самый простой пример: экземпляр класса может использоваться из разных потоков. Писать может один поток, а читать другой. Логично, что метод для чтения будет константным. Так же логично, что чтение и запись следует защитить мьютексом. Но если мы попробуем заблокировать мьютекс в константном методе, получис ошибку компиляции. Понятно, что изменение мьютекса никак не влияет на логическую константность класса, поэтому его можно объявить mutable и спокойно защищать им данные.

Из примера выше можно сделать такое неформальное заключение: <WRAP center round tip 60%> Побитовая константностью - неиболее сильная. Логическая - более слабая.

May 22, 2014 - 2 minute read - programming c++

Qt Creator и C++11

Небольшая заметка о том, как форсировать поддержку C++11 в парсере для различных билд-систем. Заметки касаются master-снапшота QTC (брать тут: http://download.qt-project.org/snapshots/qtcreator/master/latest/ или собирать из исходников).

Нужно отметить, что синтаксис нового стандарта поддерживается сейчас по-умолчанию. Проблемы касаются правильного определения констант компилятора, подключения частей стандартной библиотеки и т.п.

May 22, 2014 - 1 minute read - programming c++

std::begin() и std::end()

С приходом нового стандарта эти две свободные функции появились в STL, в библиотеке итераторов (#include <iterator>). Кроме того, в примерах кода часто можно увидеть, что они используются на STL контейнерах вместо собственных методов .begin() и .end():

#include <iostream>
#include <vector>
#include <iterators>

using namespace std;

int main()
{
  vector<int> v{1, 2, 3, 4, 5};
  
  for (auto it = begin(v); it != end(v); ++it)
  {
    cout << "Number: " << *it << endl;
  }
  
  return 0;
}

Мне хорошо понятно, что эти функции отлично подходят для RAW-массивов, т.е. если в примере выше заменить:

vector<int> v{1, 2, 3, 4, 5};

на

int v[] = {1, 2, 3, 4, 5};

или даже

int v[]{1, 2, 3, 4, 5};

То весь остальной код менять не нужно. Удобно, причём мы защищены от подсовывания указателя вместо массива. Но почему они применяются для STL контейнеров?

Поиск по интернету дал только один ответ: для унификации. И только.

Т.е. ни по “кошерности” ни по скорости два этих подхода не отличаются. Чисто для единства вида.

Если у кого есть другие предположения - милости просим в дискуссию.

Ссылки

  1. std::begin()
  2. std::end()
  3. std::next()
  4. std::prev()

May 15, 2014 - 1 minute read - linux

Nvidia Optimus

Дошли руки до включения данной фичи на моём ноутбуке. Всё оказалось не просто, а очень просто, в случае Linux Mint 16, всё делаем по инструкции: http://help.ubuntu.ru/wiki/bumblebee для Linux Mint 16 смотрим на версии убунты 13.10, для будущего Linux Mint 17 - 14.04.

За более детальными настройками: https://wiki.archlinux.org/index.php/Bumblebee_%28%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%29

Если коротко:

  1. Включаем в биосе Nvidia Optimus, у меня стоит предупреждение, что тема только для Windows 7 и 8, тупо игнорим
  2. После перезагрузке в выводеlspci -nn | grep VGA наблюдаем две строки, а не одну, как обычно.
  3. Ставим дрова nvidia (проприетарные): sudo apt-get install nvidia-319-updates nvidia-settings-319-updates
  4. Ставим бамблбее: sudo apt-get install bumblebee bumblebee-nvidia primus primus-libs-ia32
  5. Ребутимся (а может и не нужно, но у меня на этом шаге Optimus был выключен в биосе, так что один фиг нужно было включить, но перелогиниться нужно точно, так как текущий пользователь был включён в группу bumblebee, что бы иметь возможность вызывать optirun).
  6. Профит!

После загрузки смотрим вывод optirun --status видим, что всё ок. А приложения запускаем: optirun [аргументы] <приложение> [аргументы приложения]

Для самых нетерпеливых, можно сравнить вывод двух команд: glxinfo optirun glxinfo

Apr 26, 2014 - 1 minute read - linux

Quake IV в Linux

Если при старте вылазит такое:

...using GL_NV_blend_square
...using GL_ARB_texture_compression
X..GL_EXT_texture_compression_s3tc not found
Fatal Error: Texture compression unavailable
Shutting down SDL subsystem
--------------- BSE Shutdown ----------------
---------------------------------------------
idRenderSystem::Shutdown()
Sys_Error: Texture compression unavailable

Нужно сделать следующее:

  1. Устанавливаем driconf, для deb-based: apt-get install driconf
  2. Запускаем его от простого пользователя
  3. На вкладке “Image Quality” включаем параметр “Enable S3TC texture compression even if software support is not available”

Всё, радуемся игре.

Apr 25, 2014 - 3 minute read - туризм

Газ, газовые смеси и холод

Часто вижу непонимание того, как и почему должен работать газ на холоде. Была задумка скомпоновать всю полученную информацию воедино, но так сложилось, что все уже сделано за нас. Итак, подборка:

Дома дополню про вес баллонов, в т.ч. для “экспедиционных” 5 и 12л пропановых.

Но если кратко:

  1. Все смеси делаются из двух или более газов, обычно: пропан, бутан, изобутан.
  2. Пропан кипит при температуре -42 градуса по цельсию.
  3. Бутан кипит при температуре -1 градус цельсия.
  4. Изобутан кипит при температуре -12 градусов цельсия.

Отсюда видно, что чем в смеси больше пропана и меньше бутана, тем газ лучше будет работать в холодную погоду. Наиболее оптимальными на холода будут пропан-изобутановые смеси, где не меньше 20-25% пропана.

Чисто пропановые баллоны не делают по двум трём (на основании комментариев) причинам:

  1. опасность взрыва от перегрева в тёплое/жаркое время года;
  2. стоимость изобутана и бутана значительно меньше стоимости пропана.
  3. пропан не имеет запаха, поэтому бутан, как сильно вонючий, добавляют для контроля утечек газа.

Т.е. теперь, глядя на баллон, хотя бы примерно можно представлять как он будет вести себя на холоде. По субъективным наблюдениям: “новая” ковеевская смесь (изобутан 72%, пропан 22%, бутан 6%) работает хорошо до -20 градусов. Будет больше пропана и меньше бутана - на меньшую температуру можно рассчитывать.

Ну и сразу же по расходу или сколько планировать газа на маршрут, взято отсюда: http://kovea.ru/articles/information/portativnye-gazovye-ballony-i-gazovye-kartridzhi/, но, в целом, отражает суть (хотя по оценка на высоте + топление снега как раз получалось около 160 грамм):

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

  1. 50 гр./чел в день – эконом..
  2. 80 гр./чел в день - оптимальный вариант
  3. 100 гр./чел в день – комфортные условия.
  4. 100-300 гр./чел в день – альпинизм (растопить снег, обычно берется в 2е больше примерно 160-200 гр./чел в день).

Интегрированные системы могут сэкономить расход газа на 20-30%.

Есть ещё варианты котлов под обычные горелки, но с радиатором. Судя по тестам, радиатор даёт выигрыш по времени около 40%, по расходу газа 15-20%.

Мои наблюдения и компоновка знаний по расходу газа в походах отражена в заметке: Расход газа в походе. Там же рекомендации, на какое количество газа ориентироваться под конкретную ситуацию.

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

  1. http://www.germes-gas.ru/gazovye-ballony/propan/5 - баллон 5л
  2. http://www.germes-gas.ru/gazovye-ballony/propan/12 - баллон 12л
  3. http://wikimassa.org/skolko_vesit_gazovyj_ballon - баллоны 5-50л
  4. http://tourist.kharkov.ua/phpbb/viewtopic.php?t=7492 - мегаподборка по весу разных туристических баллонов газа (вес пустого баллона, вес полного)

Apr 7, 2014 - 3 minute read - programming c++

C++ и копирование перекрывающихся областей

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

В мире С++ никто не запрещает пользоваться этими функциями (часто эти функции используют различные механизмы оптимизации и могут статься быстрее своих собратьев из мира C++), но есть и более родное средство, работающее через итераторы: std::copy. Это средство применимо не только к POD типам, а к любым сущностям, поддерживающим итераторы. О деталях реализации в стандарте ничего не сказано, но можно предположить, что разработчики библиотеки не настолько глупы, что бы не использовать, оптимизированные memcpy()/memmove() когда это возможно.

Но по наитию, хочется посмотреть, а что там с пересекающимися областями (overlapping memory blocks)? Ведь задача, на самом деле, не такая уж редкая. К примеру, хотим мы читать MPEG-TS пакеты (размер каждого 188 байт, каждый пакет начинается с 0x47 /sync byte/) из какого-то потока, и есть вероятность, что первое (а может и последующее, либо имеем дело с M2TS контейнером, размер блока которого 192 байта и лишние 4 байта в большинстве случаем мы можем игнорировать) чтение может попасть на середину пакета. В таких случаях обычно делается так: вычитываем блок 188 байт, далее ищем байт синхронизации, если он в нулевой позиции - всё отлично, если нет, то данные от него и до конца, нужно переместить в начало блока, в освободившееся место нужно дочитать недостающу порцию, после чего пакет считается вычитанным и можно отдавать его на обработку.

Наглядно процесс копирования данных в начало блока можно показать этой картинкой:

std::copy

Т.е. видим, что есть перекрытие. Логично, было бы применить какой-то аналог memmove(), но в стандартной библиотеке есть только std::move который делает совершенно не то. Но при этом, читая описание для std::copy ( http://www.cplusplus.com/reference/algorithm/copy) видим следующую строчку:

The ranges shall not overlap in such a way that result points to an element in the range [first,last).

т.е. на самом деле, если начало области (result) куда копировать, лежит вне области [first,last), то всё должно быть ок. И это реально так.

Но посмотрим такую схему копирования с перекрытием:

std::copy_backward

пока не обращаем внимание на то, что result тут в конце. Смысл картинки в том, что блок памяти нужно сдвинуть с начала на какое-то смещение вперёд, соответственно если это смещение меньше размера сдвигаемого блока, то адрес назначения у нас будет лежать в пределах [first,last), таким образом условие применимости std::copy не соблюдаются. И если применить его, мы просто затрём данным в перекрывающейся области.

Но тут на помощь нам приходит его собрат, как раз решающий эту проблему: std::copy_backward, всё отличие этой функции в том, что он осуществляет копирование с конца. Т.е. для случая изображённой на второй картинке, он возьмёт (далее очень грубо, т.е. на самом деле last и result это указатели на конец блока, а ближайшие данные находятся по last-1 и result-1) элемент из last и ложится в result, далее из last-1 в result-1, далее из last-2 в result-2 и так далее.

Видно, что при такой схеме копирования, когда мы начнём писать в перекрывающуюся область, данные в ней уже будут обработаны. Т.е. для нас всё хорошо. Забавно, что условие применимости при перекрывающийся областях для std::copy_backward слово в слово повторяет данное условие для std::copy.

Итак, резюмируя, простое правило:

  • Если result < first (“сдвиг блока к началу /или влево/”), то применяем std::copy, в качестве result указываем НАЧАЛО блока-назначения.
  • Если result > first (“сдвиг блока к концу /или вправо/”), то применяем std::copy_backward, в качестве result указываем КОНЕЦ блока-назначения.

Текст является творческим переосмыслением англоязычной статьи: http://www.trilithium.com/johan/2006/02/copy-confusion, картинки взяты от туда же, пример из собственного опыта.

Референс:

PS Статья была опубликована на Habrahabr: http://habrahabr.ru/post/218451

Mar 26, 2014 - 2 minute read - linux

Калькулятор X11 Modeline

Да, времена, когда нужно было считать модлайны, дабы выжать из своего монитора и видюхи максимум уже прошли (вздох, вспомнив пару ADI Microscan 4V и S3 Trio 64V+). Но если вас настигла проблема или вдруг, как мне, для тестов, потребовалось нестандартное разрешение экрана, то вот простой калькулятор: http://www.arachnoid.com/modelines/

Ниже по тексту идёт теория, а так же информация о том, куда нужно вставлять полученный модлайн.

Про калькулятор написал, что простой. Не хороший, а простой. Почему так? А потому, что очень много тонких настроек скрыто, по сути, вы задаёте жалемое разрешение и частоту обновления. Ну а для более тонкой настройки есть и другие, типа: http://xtiming.sourceforge.net/cgi-bin/xtiming.pl

В оффлайне, аналогами этих калькуляторов, пожалуй будут: gtf и xvidtune

Первая прячется в пакете (debian-based) xserver-xorg-core, вторая в пакете x11-xserver-utils.

Пользоватся gtf так же просто как первым описанным калькулятором, просто передаём ей разрешение и частоту на вход, получаем результат:

$ gtf 800 480 60

    # 800x480 @ 60.00 Hz (GTF) hsync: 29.82 kHz; pclk: 29.58 MHz
    Modeline "800x480_60.00"  29.58  800 816 896 992  480 481 484 497  -HSync +Vsync

xvidtune своим названием говорит: запускам и тюним в интерактивном режиме.

Для добавления сгенерированного ModeLine нужно добавить его в секцию “Monitor” в /etc/X11/xorg.conf или создать файл /etc/X11/xorg.conf.d/00-modeline.conf примерно следующего содержимого:

Section "Monitor"
    ModeLine "800x480_60.00"  29.58  800 816 896 992  480 481 484 497  -hsync +vsync
EndSection

Можно добавить параметр Identifier что бы указать к какому монитору добавлять.

Второй вариант: использовать xrandr.

Выглядит это примерно так:

xrandr --newmode "800x480_60.00"  29.58  800 816 896 992  480 481 484 497  -HSync +Vsync
xrandr --addmode HDMI1 "800x480_60.00"
xrandr --output HDMI1 --mode "800x480_60.00"

Больше теории о ModeLine:

Если возникнет вопрос, что мол, скоро Wayland закопает XOrg, то ответ простой:

  1. если и закопает, то не скоро
  2. и подобные знания могут потребоваться внезапно, к примеру, генератор Marshall V-SG4K-HDI позволяет задать кастомный сигнал, и тут как раз пригодится mode line
  3. может потребовать для конфигурирования Frame Buffer без иксов и Wayland вообще

Jan 29, 2014 - 6 minute read - туризм

Китайская мультитопливная горелка BRS-8 и запчасти от Kovea

Итак, буквально перед новым годом стал обладателем горелки китайского производства BRS-8

Плюс этой горелки - её цена. Мне она обошлась в 2200 рублей в местном магазине во Владивостоке. Естественно встал вопрос надёжности отдельных частей, всё же “китай” в России уже термин нарицательный, описывающий определённое качество товаров, крайне далеко отстоящее от положительного.

Гугление особо ничего не дало, многократных подтверждений и особых болезней тоже не было выявлено, но получилось выделить следующее (наиболее собрано получилось тут: http://www.youtube.com/watch?v=jEds1uRhWkI):

  1. Износ шланга, травление в районе крепления к штуцеру со стороны регулятора и крепления к самой горелки
  2. Износ регулятора, начинает сифонить, при этом изнашивается не резиновые прокладки, а металл (!!!)
  3. Насос, точнее резьба, которая вкручивается в баллон, из-за своей пластиковой природы изнашивается. У некоторых сифонит по периметру, в месте вхождения насоса в пробку.

Логичным путём было поискать возможные замены для отдельных узлов и агрегатов. И тут… у меня родилась мысль…

В названии этой горелки в разных каталогах встречается приписка “Booster +1”, что как бы намекает на отношение этой горелки к Kovea KB-0603 Booster +1. Действительно, визуальное сравнение по фотографиям приводит только к следующим различиям:

  1. форма ног самой печки;
  2. наличие бутылки в комплекте BRS-8
  3. более скудный ремкомплект у BRS-8
  4. отсутствие переходника на цанговый баллон у BRS-8

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

Соответственно было решено попытаться заказать комплектующие от оригинального бустера, примерить на китайский BRS-8 и посчитать результирующую стоимость полученного мутанта.

Насос, пока, было решено не покупать, а когда потребуется, взять в местном магазине (ровно как и ремкомплект и переходник на цанговый баллон). Шланг, регулятор и рассекатель пламени брались на http://kovea.ru. При этом, в каталоге их нет, поэтому нужно писать на eshop@kovea.ru или service@kovea.ru. Стоимость этих позиций узнаётся в этом разделе: http://kovea.ru/page/service/. Жителям Москвы будет проще лично забрать необходимые позиции там, для удалёнки, оплата через робокассу (почти все возможные методы оплаты) и доставка EMS или другой курьерской службой.

Подкатом много картинок. Здесь и далее все изображение кликабельны.

Jan 27, 2014 - 1 minute read -

PlantUML: параллельное выполнение в Sequence Diagram

Давно хотелось иметь в PlantUML возможно в Sequence диаграмме рисовать две параллельные ветки выполнения (на самом деле иногда больше, но хотя бы…).

И вот, случайно в последней версии нащупал такую команду:

par2
  ...
else
  ...
end

Т.е. при примерно таком коде:

@startuml
hide footbox

A++
par2
    A -> B ++
    B -> B ++
    return
    return
else
    A -> C ++
    C -> C ++
end
A--

@enduml

мы получим следующую картинку:

в общем, чего и хотелось.

Правда при таком подходе, если, допустим, A, B и C - разные потоки, то операции с A нужно корректно вставлять в одну из веток par2

PS в примере можно видеть различные операции типа ++ и -- найти их описание можно здесь: http://plantuml.sourceforge.net/incubation.html