LINUX.ORG.RU

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

Производительность; илитный запил оптимальных реализаций и основы матчасти.

Форум — Development

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

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

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

Начнём с простого - сумма елементов(float) массива. Как написать её быстро? Обычный крестопоц сделает так:

auto summ = accumulate(begin(vec), end(vec), 0.)

Этот код выдаёт 5.6GB/s(мы всё бенчим в л1д 32килобайта массив). Казалось бы, если бы мы слушали всяких «гуру», которые нам говорят: accumulate() - оптимизирован, «ты что умнее создатели stl"а?», «конпелятор умнее тебе - сам всё делает оптимально», «руками что-то делать слишком сложно и не нужно» - то мы бы там и остались с этими 5.6ГБ, но мы пойдём дальше и поймём почему так, и является ли это тем, что намн ужно.

Но посмотрев на код - он не векторизован:

	addq	$4, %rdx
	vcvtss2sd	-4(%rdx), %xmm2, %xmm2
	vaddsd	%xmm2, %xmm1, %xmm1

Почему? Патамучто это основная флоатпроблема: Он не ассоциативен - флоат не имеет в себе точных представлений всех чисел входящих в диапазон его «представления» т.е. порядкопроблемы.

Поэтому конпелятор НЕ ВЕКТОРИЗУЕТ флоат по умолчанию, ну никак. Даже такую банальщину.

Для решения этих проблем - есть ключик -funsafe-math-optimizations, который входит в -ffast-math, который кладёт на точность при вычислениях. Добавив его мы получаем уже 44.9GB/s.

Но теперь мы получаем ещё одну проблему - надо думать: «как бэ сунуть эту ключик не повредив там, где этот ключик не нужен».

Поэтому ноцанам, которые хотят быстро и не хоятт рандомных жоп из-за тупости конпелятора - пишут всё руками. Допустим на той же сишке это пишется так:

double memadd_autovec(buf_t buf) { //5.609465GB/s, либо 44.969652GB/s с ffast-math
  float * it = buf_begin(buf), * end = buf_end(buf), summ = 0.;
  do {
    summ += *it++;
  } while(it != end);
  return summ;
}

double hsumf(__v8sf v) {
  return (v[0] + v[1] + v[2] + v[3] + v[4] + v[5] + v[6] + v[7]);
}

double memadd_vec(buf_t buf) { //45.652002GB/s и класть на ffast-math
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = {};
  do {
    summ += *it++;
  } while(it != end);
  return hsumf(summ);
}

Т.е. разницы никакой нет, кроме нужной нам реализации горизантального сложение вектора. Когда я говорил пацану: «векторную сишку для написания быстрого кода юзать намного проще, чем плюсы» - поцан нипонимэ, да и любые пацаны скажут - ну дак с -ffast-math оба выдают по 45гигов - нахрен эта сишка нужна?

А вот зачем:

double memadd(buf_t buf) { //132.878440GB/s
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = {};
  do {
    summ += *it++;summ += *it++;summ += *it++;summ += *it++;
  } while(it != end);
  return hsumf(summ);
}

Это называется пацанский анролл копипастой, а вот заставить конпелятор нормально что-то разанролить очень сложно.

Если бы мы слушали всяких «гуру», которые нам вещают: «анрол говно и не нужен» - мы бы так и седели с 45-ю гигами, а так мы сидим с 132.878440GB/s. Т.е. анролл нам дал немного не мало ~300%.

Но основная мысль, которую толкают всякие «гуру» - это не надо следить за тактами/считать такты и прочее. Но мы о5 сделаем наоборот и посмотрим что будет.

Т.к. наш юзкейс упирается на 99% в throughput и дёргается одна инструкция, то нам достаточно просто считать теоретическую производительность для моего камня. 4.5(частота камня)*8(т.е. у нас камень с avx, то там вектор 32байта, либо 8флоатов.)*1(throughput нашей инструкции - в данном случае vpaddps из интел мануала). Т.е. 36гигафлопс, либо ~144гига. Т.е. мы сняли овер 90% теоретической производительности - остальные 10% у нас ушли в наши циклы, всякие горизонтальные суммы вектора и прочее, ну и конечно же чтение данных из кеша.

Но самое смешное - на моём хасвеле умножение имеет throughput 0.5 - т.е. на хасвеле умножение быстрее сложения. Это новая забористая трава у интела.

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

Поэтому очень смешно слушать, когда какие-то пацаны говорят: «float point имеет такую же производительность как и инты» - нет, оно имеет такоу же производительность лишь по причине того, что на штеуде инты тормазят так же, как и float.

И чтобы окончательно в этом убедится - мы взглянем на fma(вариации умножения со сложением/вычитанем), которые имеют throughput 0.5 - да, да - на хасвеле умножение+сложение в 2раза быстрее просто сложения. Это уже не просто трава - это что-то принципиально новое.

У целочисленного сложения же throughput 0.5 и казалось бы, если мы поменяем в нашей функции float на int - у нас будет сложение работать в 2раза быстрее, но это не так. Оно выдаёт те же 130гигов, а почему?

Вообще у камня есть такая фича, допустим у нас:

add $1, %reg0//вот тут инструкция add залочит регистр reg0
add $1, %reg0//а эта инструкция уйдёт в лок до особождения предыдущей инструкцией регистра reg0

Чтобы такой жопы небыло - есть специальная фича:

add $1, %reg0//lock reg0
add $1, %reg0//И тут вместо того, чтобы уйти в лок - камень вместо reg0 даёт инструкции любой свободный регистр.

Эта фича называется прееименование регистров, либо как-то так - мне лень гуглить.

Дак вот штука в том, что фича работает через жопу. Мне лень читать мануал и искать почему так, но штука в том, что она ограничивает throughput. На умножении и целочисленном сложении она огранивает throughput c 0.5 до 1.

И вот я решил заюзать сложении через fma:

__v8sf fmaadd(__v8sf a, __v8sf b) {
  return _mm256_fmadd_ps(_mm256_set1_ps(1.), a, b);// a + b * 1. == a + b.
}

double memadd_fma(buf_t buf) {
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = {};
  do {
    summ = fmaadd(summ, *it++);
  } while(it != end);
  return hsumf(summ);
}

Но меня ждала жопа: 27.347290GB/s, причем не анролл и ничего не помогал. Я уж подумал, что мануал наврал, но позже до меня допёрло: у неё latency 5тактов и ((4.5×8)÷5)×4 ~= 29гигов - т.е. я получаю производительность с её latency, но какой жопой оно так?

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

add $1, %reg0
add $1, %reg0
//а не
add $1, %reg0
add $1, %reg1

Т.е. на неё вообще не работает переименовывание регистров - и инструкции постоянно в локе. Я это проверил и оказался прав. Ну и я написал такой мемадд:


__v8sf fmaadd(__v8sf a, __v8sf b) {
  return _mm256_fmadd_ps(_mm256_set1_ps(1.), a, b);
}

inline void fma_10way_finality(__v8sf * cache, __v8sf * it, __v8sf * end) {
  switch(end - it) {
    case 8:
      *(cache + 7) = fmaadd(*(cache + 7), *(it + 7));
      *(cache + 6) = fmaadd(*(cache + 6), *(it + 6));
    case 6:
      *(cache + 5) = fmaadd(*(cache + 5), *(it + 5));
      *(cache + 4) = fmaadd(*(cache + 4), *(it + 4));
    case 4:
      *(cache + 3) = fmaadd(*(cache + 3), *(it + 3));
      *(cache + 2) = fmaadd(*(cache + 2), *(it + 2));
    case 2:
      *(cache + 1) = fmaadd(*(cache + 1), *(it + 1));
      *(cache + 0) = fmaadd(*(cache + 0), *(it + 0));
    case 0:
      break;
    default: error_at_line(-1, 0, __FILE__, __LINE__, "bad_aligned");
  }
}

double memaddfma_10way(buf_t buf) {
  __v8sf * it = buf_begin(buf), * end = buf_end(buf), summ = (__v8sf){};
  __v8sf * cache = (__v8sf[10]){{}};
  uint64_t i = 0;
  while((it += 10) <= end) {
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    *(cache + i) = fmaadd(*(cache + i), *(it - i - 1));++i;
    i = 0;
  }
  fma_10way_finality(cache, (it - 10), end);
  summ = (*(cache + 0) + *(cache + 1) + *(cache + 2) + *(cache + 3) +
	  *(cache + 4) + *(cache + 5) + *(cache + 6) + *(cache + 7) +
	  *(cache + 8) + *(cache + 9));
  return hsumf(summ);
}

Пришлось хреначить финалити, ибо тут «анролл» на 10, а почему на 10 - для максимального throughput"а - надо, чтобы каждый каждый регистр юзался через 5тактов - т.е. 10регистров.

И вся эта порятнка нужна для борьбы с тупостью конпелятора.

Это уже: 214.167252GB/s(раельно там в районе 250 - просто мой бенч говно). 107 гигафлопс на ведро. Из теоретических 144, но тут уже влияние кеша. Причем 50+ из которых выкидываются и просто бесплатные.

Теперь вопрос к пацанам - что нам дадут эти гагфлопсы, когда у нас будет массив не 32килобайта, а 32мегабайта? Зачем нужно выживать максимум, когда скорость памяти отсилы 20-30гигабайт и нам хватит даже С++ кода с ffast-math?

Ну и призываются упомянутые мною пацаны: mv - этот тот експерт, что вещал про «руками переименовывать регистры не надо» и «анрол ваще ненужен», emulek вещал про ненужность счёта тактов, и не понимал что такое «беслпатно», AIv - не понимал в чем проблема плюсов, ck114 - так же не понимал в чем проблема плюсов.

Бенчи: https://gist.github.com/superhackkiller1997/606be26fa158ef75501d - вроде я там ничего не напутал.

P.S. - не выпиливайте пж, пусть пацаны «нужно» или «не нужно». Мне интеерсно. Ну и там рекомендации пацанов.

 , , ,

Carb_blog
()

Устаревшие «фишки», вредные советы, бесполезные «оптимизации» и прочий карго-культ

Форум — Talks

На просторах интернетов полным полно всевозможных статей, постов и тем на форумах, где обсуждаются или «реквестируются» всякие «фишки» и советы по оптимизации «онтопика». Но многие из описываемых там вещей являются либо неактуальными, либо изначально не несут в себе никакой пользы, а иногда даже и вред. При этом сразу понять, является ли совет полезным или нет, зачастую не получается. Поэтму предлагаю в этой теме делиться примерами сабжа и объяснениями, почему они устарели/не работают/вредны.


Начну с того, что первым вспомнилось:

1. sudo make install.
Довольно часто в инструкциях по установке софта под «онтопик» говорят делать это. Не знаю, почему вообще кто-то считает это хорошей идеей (могут быть, наверное, исключения, но не советовать же это в качестве стандартного способа установки). Если пакета под ваш дистрибутив нет, используйте Flatpak, AppImage, AUR, PPA, Docker или хотя бы tar.gz, распакованный в пользовательскую директорию. (Snap не используйте, Snap — говно.)

2. sudo gedit.
В основном в «гайдах» по настройке чего-то на «бубунте». Ибо пишут эти такие же «бубунтята». Консольный текстовый редактор и то такая себе идея от рута запускать. Hint: man sudoedit.

3. «/ на SSD, $HOME на HDD».
Почему-то у линуксоидов так сложилось, что принадлежащие пользователю файлы хранятся в одной куче с данными, пренадлежищими программам. Из-за этого остаётся либо выключать в ФМ показ скрытых файлов (а потом снова вклюать, когда понадобится, после чего снова отключать), либо лицезреть помойку. Но самое страшное последствие данного маразма проявляется, когда у пользователя имеется SSD и HDD и он решает на первый поставить систему, а на второй вынести $HOME. В итоге данные, которые по назначению совпадают с содержимым / (только являются при этом специфичными для конкретного пользователя), которые программы постоянно читают и перезаписывают, оказываются на HDD. Храните свои пользовательские данные в /data/ (как в андроиде), /mnt/data/ или где-то ещё. А $HOME пусть остаётся на SSD, на том же разделе, что и /. (Хранить все данные исключительно на HDD тоже не обязательно.) Местоположение папок «Загрузки», «Документы», «Изображения» и т. д. можно настроить средствами DE либо через конфиг XDG User Directories.

4. @gremlin_the_red пишет по поводу CONFIG_HZ=1000 для плавности:

Ммм, карго культ он такой. Это очень много лет, как абсолютно ничего не даёт. […] В нашей реальности 2021го не осталось шедулеров, привязанных к config_hz, это дела давно минувших дней.

5. Отдельный раздел для swap.
Зачем лишний раз усложнять себе жизнь и плодить разделы, если можно сделать swap в виде файла? И нет, производительность от этого не упадёт. (Оказывается, что если HDD, то таки упадёт, но там, наверное, уже неважно (см. комментарии).)

 , ,

sudopacman
()

Раздача мобильного интернета по WiFI - Raspberry 3b+

Форум — Admin

Всем привет.

К малинке подключен USB-модем, настроен wvdial, мобильный интернет поднимается.

hostapd поднимает точку доступа, IP-адреса клиентам WiFi раздаются по DHCP c использованием isc-dhcp-server.

Для маршрутизации используется такой скрипт:

#!/bin/sh

Очищаем правила

iptables -v -F iptables -v -X

Определяем выходной интерфейс для которого будет применяться замена адресов (NAT)

iptables -v -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

Пересылаем все пакеты, пришедшие на модем из глобальной сети (0.0.0.0/0) в локальную сеть (192.168.2.0/24)

iptables -v -A FORWARD -i ppp0 -o wlan0 -s 0.0.0.0/0 -d 192.168.2.0/24 -j ACCEPT

Пересылаем все пакеты, пришедшие из локальной сети (192.168.2.0/24) в глобальную (0.0.0.0/0)

iptables -v -A FORWARD -i wlan0 -o ppp0 -s 192.168.2.0/24 -d 0.0.0.0/0 -j ACCEPT

На клиентах инета нет, пингуется малина (192.168.2.1), гугловский DNS не пингуется (8.8.8.8).

Что я делаю не так?

 

Ser33gus
()

Загрузка любого дистрибутива в RAM

Форум — Talks

Здравствуйте мои юные кали-хакеры и любители оставаться анонимными. С утра, ковыряя VDS (пользуюсь услугами ру-провайдера), [ДАННЫЕ УДАЛЕНЫ] запрос, и [ДАННЫЕ УДАЛЕНЫ] дамп диска [ДАННЫЕ УДАЛЕНЫ].

А теперь скрипт, который из кастомного, т.е. созданного и настроенного вами chroot'а создаёт initramfs образ, готовый к загрузке и работе в tmpfs.

С ним вы можете на любой системе прямо «на лету» свичнуться в tmpfs, хоть прямо сейчас, на своём компьютере. Предварительно установив в chroot любой дистрибутив по желанию и настроив его под себя. А потом скриптом упаковать его в initramfs образ и свичнуться, да.

Для создания минимального (от слова «маленький», а не «огрызок») образа потребуется squashfs-tools. Чтобы свичнуться «на лету» нужен kexec-tools. Установите их. В ядре должны быть включены опции: CONFIG_OVERLAY_FS=y, CONFIG_SQUASHFS=y и CONFIG_SQUASHFS_XZ=y. [личное мнение: ZSTD получается размером больше, чем XZ]

Например. Хотите генту?

# mkdir gentoo_chroot/
# cd gentoo_chroot/
# wget https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/20200519T155804Z/stage3-amd64-20200519T155804Z.tar.xz
# tar xf stage3-amd64-*.tar.xz
# rm stage3-amd64-*.tar.xz
# cd ..

На этом этапе мы получили ванильную генту в gentoo_chroot/. Рекомендую её настроить, хотя бы сделать chroot gentoo_chroot/ /bin/bash и установить passwd для root, иначе в систему вы не войдёте. Я не знаю, что это за особенность такая, не давать установить пароль если его нет. В моём CRUX когда пароль на root отсутствует и ты логинишься первый раз (в tty или в ssh по ключу), оно просто предлагает установить пароль. Какая тут может быть дыра в безопасности на свежеустановленной системе? Не знаю...

Предлагаю так же в gentoo_chroot/ скопировать модули и фирмварь для корректной работы текущего ядра и железа.

# cp -a /lib/modules gentoo_chroot/lib/modules
# cp -a /lib/firmware gentoo_chroot/lib/firmware

Ну и создадим образ наконец.

# ./mkchrootrd gentoo_chroot/ ~/gentoo_initrd

Усё. У нас теперь целая настоящая гента в gentoo_initrd файлике упакована. Давайте загрузимся же в неё скорее с текущим ядром.

# eval $(cat /proc/cmdline | cut -f 1 -d \ )
# kexec -l $BOOT_IMAGE --initrd=gentoo_initrd --reuse-cmdline
# kexec -e

Если вы не хотите делать kexec по каким-то причинам, то положите этот же образ в свой /boot, а в параметрах загрузки укажите initrd /gentoo_initrd. Перезагрузитесь и получите тот-же результат.

Ура! Гента загрузилась. Тоже самое можно проделать с любым дистрибутивом, просто установите его, настройте как вам угодно, а затем скриптом создайте initramfs образ. Я уж взял для примера Gentoo, не стал лишний раз приводить в пример CRUX.

Жмём Reset чтобы сбросить всё и загрузиться в свою систему с морально устаревшего M.2 NVMe накопителя обратно.

Перевёл свою VDS на работу в tmpfs. Диск /dev/vda отформатировал в NTFS. Рекомендую всем. 👍👍👍👍👍👍

Скрипт:

#!/bin/bash
#
# Author: Sp00f1ng <sp00f1ng@sp00f1ng.com>
# License: Public Domain
#
################################################################################
#
# mkchrootrd chroot_directory/ [initrd_image]
#
################################################################################
# 
# Depends on: squashfs-tools
# Optional:   kexec-tools
# Kernel:
#
# File systems  --->
#    <*> Overlay filesystem support
#    [*] Miscellaneous filesystems  --->
#       <*> SquashFS 4.0 - Squashed file system support
#          [*] Include support for XZ compressed file systems
#
################################################################################
#
# Example usage:
#
# mkdir gentoo_chroot/
# cd gentoo_chroot/
# wget https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/20200519T155804Z/stage3-amd64-20200519T155804Z.tar.xz
# tar xf stage3-amd64-*.tar.xz
# rm stage3-amd64-*.tar.xz
#
# [.. do something else with gentoo_chroot/ like additional configuration ...]
# [ cp -a /lib/modules ./lib/modules ]
# [ cp -a /lib/firmware ./lib/firmware ]
#
# cd ../
#
# ./mkchrootrd gentoo_chroot/ ~/gentoo_initrd
#
# eval $(cat /proc/cmdline | cut -f 1 -d \ )
# kexec -l $BOOT_IMAGE --initrd=gentoo_initrd --reuse-cmdline
# kexec -e
# 
# Have fun and happy hacking day 1 <3 <3 7 !

panic() {
	if [ -e "$TMP" ]; then
		rm -rf $TMP 2>/dev/null
	fi
	exit ${1:1}
}

got_help() {
	grep ^\# "$0"
}

got_cmdline() {
	while [ "$1" ]; do
		if [ ! -n "$CHROOT_DIR" ]; then
			CHROOT_DIR="$1"
			shift
			continue
		fi
		if [ ! -n "$INITRD_IMG" ]; then
			INITRD_IMG="$1"
			shift
			continue
		fi
		shift
	done
}

cp_bin() {
	local src="$1"
	local dst="$2"
	local dep=""

	if [ "$dst" = "" ]; then
		dst="$src"
	fi

	if [ -e "$TMP$dst" ]; then
		return
	fi

	install -D -m 0755 "$src" "$TMP$dst"

	for dep in $(ldd "$src" 2>/dev/null | grep -o '/.* '); do
		cp_bin "$dep"
	done
}

mk_env() {
	for dir in proc sys dev run mnt overlay; do
		install -d $TMP/$dir
	done

	for dev in console tty tty1 null; do
		cp -a "/dev/$dev" "$TMP/dev/$dev"
	done

	for bin in sh switch_root mount umount mkdir rmdir; do
		cp_bin "$(which $bin)"
	done

	touch $TMP/init
	chmod +x $TMP/init

	cat > $TMP/init << EOF
#!/bin/sh
mount -t proc none /proc
echo "0" > /proc/sys/kernel/printk
mount -t sysfs none /sys
mount -t devtmpfs devtmpfs /dev
mount -t tmpfs none /run
mount -t tmpfs tmpfs /overlay
lowerdir="/lower"
upperdir="/overlay/upper"
workdir="/overlay/work"
mkdir -p \$lowerdir
mkdir -p \$upperdir
mkdir -p \$workdir
mount -t squashfs -o ro /root.sqfs \$lowerdir
mount -t overlay -o ro,lowerdir="\$lowerdir",upperdir="\$upperdir",workdir="\$workdir" overlay /mnt
umount /proc
umount /sys
umount /dev
umount /run
exec switch_root /mnt /sbin/init
EOF
}

main() {
	CHROOT_DIR=""
	INITRD_IMG=""

	got_cmdline "$@"

	if [ ! -n "$CHROOT_DIR" ] || [ ! -n "$INITRD_IMG" ]; then
		got_help
		panic 0
	fi

	if [ ! -d "$CHROOT_DIR" ]; then
		echo "'$CHROOT_DIR' is not directory."
		panic 1
	fi

	if [ ! -x "$(which mksquashfs)" ]; then
		echo "'mksquashfs' squashfs-tools not found."
		panic 1
	fi

	mk_env

	mksquashfs $CHROOT_DIR $TMP/root.sqfs \
		-b 1048576 -comp xz -Xdict-size 100%

	cd $TMP
	echo "Building Initial RAM Disk [$INITRD_IMG]"
	find . -print0 | cpio --null --create --format=newc --verbose > "$INITRD_IMG"
	echo "Done [$INITRD_IMG]"
}

trap "panic" INT HUP QUIT TERM EXIT

readonly MKCHROOTRD_COMMAND="$0"
readonly MKCHROOTRD_VERSION="1.0"

TMP=$(mktemp -d)

main "$@"

# EOF

 mkchrootrd,

Spoofing
()

Посоветуйте учебник по теории музыки

Форум — Talks

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

Пришлось вместо чтения учебников написать свой учебник. Так как на русском я разучился говорить, учебник написан на TypeScript (это такой верификатор типов для JavaScript).

https://github.com/olegchir/sharpnumbers/blob/master/Tonspace.ts

Собираюсь продолжать изучать и писать :) Посоветуйте учебник музыки, который достаточно точен, чтобы переносить эту информацию в код, спасибо)

 ,

stevejobs
()

Полировка знаний о Си

Форум — Development

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

 

LancerRevX
()

Да бл persistence как сделать?

Форум — General

В общем пытаюсь сделать все как в инструкции на codeby, на флешке с образом создаю новый раздел persistence, с параметрами primary и ext4, вставляю загружаю Kali live, в консоли с помощью fdisk -l смотрю на диски. Далее

mkdir -p /mnt/USB

mount /dev/sda3 /mnt/USB

echo «/ union» >> /mnt/USB/persistence.conf

umount /dev/sda3

reboot

Kali с оф. сайта, еще если поможет, я еще когда в Окнах сидел, заметил что этот компьютер говорит что флешка 32G свободна на 27кб, а программа для разметки говорит что у меня 27G свободного места, и именно это место занимает созданный мною раздел sda3. Можно на кали без танцев с бубном поработать?

 

Ah_shit
()

Как определить снимок или его часть размыта или в фокусе?

Форум — Science & Engineering

Как определить программно, что изображение имеет ли размытие или не точности при текущем масштабе просмотра?

 

victor79
()

Книга по матану

Форум — General

Посоветуйте хорошую книгу по математике. Интересует мат. анализ и линейная алгебра. Чтоб нормы были, ряды, дифуры и т.д. Хочу чтобы формулы в документации к библиотекам для машинного обучения, шифрования или статистики выглядели знакомо. Математика в университете была, но если углубляться в определенные дисциплины, то чувствую, что не хватает. Например, ряды у нас, так получилось, вообще не преподавали. Несколько статей в интернете поправили ситуацию, но качество такого обучения оставляет желать лучшего. Книгу желательно на английском и написанную современным языком.

 , , , ,

Rot1
()

Не баньте царя, пожалуйста.

Форум — Linux-org-ru

Просто хотел поддержать предыдущего оратора.

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

 ,

Manhunt
()

Тестирование «C» кода.

Форум — Development

Всем привет ::) Господа, вы наверное будете в голос ржать, но я в жизни не занимался тестированием кода, вот прям сосем никогда, от того прошу советов как тестировать чем тестировать и что по теме почитать/поучить как это дело автоматизируется и прочее. Да есть google, но я как всегда иду туда в последнюю очередь. Ну и смею себе позволить позвать людей (кого с ходу вспомню) плотно работающий с «С». Cast DELIRIUM, i-rinat, beastie, ncrmnt, theNamelessOne, Murg, Iron_Bug. Всем добра и улыбашек ::)

По просьбе i-rinat пример кода (просто рандомный код из закромов откопанный/заброшенный/недописанный, в общем то что нужно)

#include <stddef.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

struct $struct_neuron
{
    size_t  id;
    struct  $struct_neuron ** sinapses_connections;
    size_t  sinapses_connections_size;
    float * sinapses_weight;
    struct  $struct_neuron ** acsons_connections;
    size_t  acsons_connections_size;
    float   acsons_result_signals;
    void   (*finp)();
    void   (*fmid)();
    void   (*fout)();
};typedef struct $struct_neuron struct_neuron;

struct $struct_network
{
    size_t id;
    size_t network_size;
    struct_neuron * neurons;
    struct $struct_network ** network_connections;
    size_t network_connections_size;;
};typedef struct $struct_network struct_network;


struct $struct_net_union
{
    size_t id;
    struct_network ** networks;
    size_t net_union_size;

};typedef struct $struct_net_union struct_net_union;


struct_neuron neuro_neuron_new(void);
void neuro_neuron_connect(struct_neuron* acson, struct_neuron * sinaps);

struct_network neuro_network_new(size_t neurons);
void neuro_network_connect(struct_network* net1, struct_network* net2);



#include "neuro.h"




struct_neuron neuro_neuron_new(void)
{
    static size_t id=0;
    struct_neuron neuron;
    neuron.id=id++;
    neuron.sinapses_connections      = NULL;
    neuron.sinapses_connections_size = 0;
    neuron.sinapses_weight           = NULL;
    neuron.acsons_connections        = NULL;
    neuron.acsons_connections_size   = 0;
    neuron.acsons_result_signals     = 0.0;
    return neuron;
}

void neuro_neuron_connect(struct_neuron * acson, struct_neuron * sinaps)
{
    sinaps->sinapses_weight = realloc(sinaps->sinapses_weight,sizeof(float)*sinaps->sinapses_connections_size+1);
    srand(clock());
    sinaps->sinapses_weight[sinaps->sinapses_connections_size] = (float)(rand()/100000009);
    sinaps->sinapses_connections = realloc(sinaps->sinapses_connections,sizeof(struct_neuron)*(sinaps->sinapses_connections_size+1));
    sinaps->sinapses_connections[sinaps->sinapses_connections_size++] = acson;
    acson->acsons_connections = realloc(acson->acsons_connections,sizeof(struct_neuron)*(acson->acsons_connections_size+1));
    acson->acsons_connections[acson->acsons_connections_size++] = sinaps;
}



struct_network neuro_network_new(size_t neurons)
{
    static size_t id = 0;
    struct_network network;
    network.id = id++;
    network.network_size = neurons;
    network.neurons = NULL;
    network.network_connections = NULL;
    network.network_connections_size = 0;
    network.neurons = malloc(sizeof(struct_neuron)*neurons);
    for(size_t i = 0; i < neurons; i++)
    {
        network.neurons[i] = neuro_neuron_new();
    };
    return network;
};

void neuro_network_connect(struct_network * net1, struct_network *net2)
{
    net1->network_connections = realloc(net1->network_connections,sizeof(struct_network)*(net1->network_connections_size+1));
    net1->network_connections[net1->network_connections_size++] = net2;
    net2->network_connections = realloc(net2->network_connections,sizeof(struct_network)*(net2->network_connections_size+1));
    net2->network_connections[net2->network_connections_size++] = net1;
    for(size_t i = 0; i < net1->network_size; i++)
    {
        for(size_t p = 0; p < net2->network_size; p++)
        {
            neuro_neuron_connect(&net1->neurons[i],&net2->neurons[p]);
        };
    };
};


struct_net_union neuro_net_union_new()
{
    static size_t id=0;
    struct_net_union net_union;
    net_union.id=id++;
    net_union.networks=NULL;
    net_union.net_union_size=0;
    return net_union;
}

void neuro_net_union_add(struct_net_union * net_union, struct_network * network)
{
    net_union->networks = realloc(net_union->networks,sizeof(struct_network)*(net_union->net_union_size+1));
    net_union->networks[net_union->net_union_size] = network;
    net_union->net_union_size++;
}




#include "neuro.h"


int main(int argc, char const *argv[])
{

	struct_network  net1 = neuro_network_new(100);

	struct_network  net2 = neuro_network_new(100);

	neuro_network_connect(&net1,&net2);

	
	return 0;
}
gcc -g neuro.c main.c -o neuro

 , , ,

Dron
()

Пиратское радио

Форум — Linux-hardware

Добрый день.
Попробовал вещать с RaspberryPi , PiFM , получилось , теперь хочу большего , хочу сигнал вместо антенны вывести на базу транзистора а на эмитер подать вольт триста постоянного тока(выпрямленные и сглаженные 220вольт)
Получится ли у меня так передатчик помощнее ?

 

bloodmeri
()

Какие свободные игры вам нравятся и вы в них играете?

Форум — Games

Сабж.

У меня вот teeworlds.

 

ados
()

Он говорит, что лучше много читать, но при этом не даёт рекомендации как запоминать такие объемы информации?

Форум — Talks

Вот я 2 года назад прочитал фундаментальный труд Бертрана Рассела «История Западной философии» (История западной философии и её связи с политическими и социальными условиями от античности до наших дней), мегаинтересный, просто супер, сплошное удовольствие, до слез.

Теперь почитай и ты.

Примерно через полгода я забыл половину содержания, имена 75% философов и все течения кроме стоиков и циников. Сегодня, спустя два года, я помню только, что Аристотель это ученик Платона, который в свою очередь ученик Сократа, что Диоген Синопский не жил в бочке, как думают большинство курильщиков спайсов, а в пифосе, неком подобии сосуда для промышленного изготовления вина размером с небольшой гараж, еще помню Ксенофонта и Антисфена, но на этом всё. Т.е. помню примерно 5% книги.

Ну конечно, ты умнейший человек, выделяешься четкостью и остротой ума, сразу скажешь, что тренируйся и ничего не будешь забывать, practice makes perfect. Какой ты умный, мне что, через каждые 2-3 месяца тренироваться в металловедении, если я решил узнать, чем низкоуглеродистые стали отличаются от чугуна, для чего и чем легируют стали, почему нержавеющие стали подвержены гальваническому ржавлению и т.п. Ванадий, хром, вольфрам, молибден, вот это всё я забуду через 2-3 месяца.

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

Как запоминать? Как не забывать? Как вы запоминаете? Как вы не забываете?

 , , ,

slon
()

Утрамбованный Firefox

Галерея — Скриншоты

Недавно решил перейти с Chrome на Firefox. Поскольку экран ноутбука маленький, решил ужать его по вертикали, благо в отличие от хромого ничего гвоздями не прибито. И ужал: вместе с парой расширений заставил все нужные элементы отображаться на всего одной аккуратной панельке толщиной в ~40px. И при этом Kwin все равно рисует красивую рамочку, тени и подсветку.

Kubuntu 16.10, KDE 5.8.4, Plasma+qt+gtk: Breeze, kwin - Oxygen-qt5.

Ждем kde 5.9 с обещанным возвращением appmenu. А пока довольствуемся тем, что плазма уже не падает.

>>> Просмотр (1920x1080, 302 Kb)

 , ,

Kor03d
()

Ваши любимые игры под Android ?

Форум — Talks

А накидайте, пожалуйста, ваших любимых игр для Android.
Пусть это будут любые категории: карточные (покер там, например, и т.д.), логические, головоломки, настольные и т.д. Только кроме всяких 3D-шутеров и бродилок. Такое не интересует.
Главные требования:
- поменьше рекламы
- удачная, красивая графика (без фанатизма только)
- занимали немного места
Знаете, когда запускаешь игру, а она тебя удивляет и завлекает. Поделитесь плиз.

Спасибо заранее.

 ,

Gonzo
()