Программирование

Postgresql HA Q

Апгрейдил тут постгрес с 8.4 на 9.1, типа давно пора.

Поднял в соседней виртуальной машине (jail-е, точнее) второй сервер БД, отнес все туда, запустил postgresql-relay, вроде все работает, стал постепенно апгрейдить.

Где-то через час заметил, что PHP-шные (друпальские) сайты - работают (медленно), а перловые - нет. Ну так, из общих соображений, PHP ходит через локальный сокет, а если не вышло - через localhost:5432 (а там у меня relay), а DBI::Pg, если hostname не указали, ходит только в /tmp/.s.PGSQL... и все.

Отсюда вопросы, раз уж всплыла тема:

  1. А есть ли такой постгресовый proxy, который и локальный сокет эмулирует тоже?
  2. А есть ли такой постгресовый proxy, который на psql -l нормально отзывался бы, показывая бы нечто, согласно своей конфигурации?
  3. А есть ли такой простой постгесовый proxy, который умеет делать fallback на запасной сервер? Ну вот был master-slave, мастер сдох, а жить то надо.
Я знаю про PL/proxy, но идея со stored procedures меня совершенно не радует, у меня написанные мной за 15 лет скрипты, у меня написанные совершенно не мной всякие штуки, это банальные 'select a from b where c' и переписывать их нет никаких возможностей.

Про HD7970

Договорился с жабой и купил новую грелку для ног.

Вкратце:

  • OpenCL 1.1, поддерживается, работает. Посмотреть что там за код не получается, Kernel Analyzer не умеет это место.
  • Драйвера: под винды есть, бета, в основной Catalyst не включены (и, похоже, войдут не раньше чем в 12.3 т.е. через два месяца т.к. даже в 12.2-preview поддержки 79xx нет). Драйвера под линукс поискал для проформы (мне не надо) - и не нашел.
  • Сцуко, быстрая. Один и тот же OpenCL-код (написанный с оглядкой на NVidia Fermi) работает в-среднем раза в полтора быстрее, чем на GTX480 (single precision). Предыдущая моя ATI-шная карта, HD5870 была в 1.5-2 раза медленнее 480-й нвидии.

    На примере MatrixMultiplication из AMD APP - быстрее в 4 раза (single).

    С double не все так радужно - нужно явно как-то иначе оптимизировать, а может просто драйвера кривые. На всем что попробовал, 7970 получается непринципиально быстрее GTX480, а на каких-то задачах и помедленнее.

  • Сцуко, холодная. Idle temp 44C, прогреть больше чем до 80 счетным кодом не удалось. Наверное, если получше пооптимизироваться, то удастся подогреть больше. Ноги, короче, не греет.
  • Сцуко, тихая. Ну то есть если вручную вентиляторы поставить на 100%, то громкая, как и любая современная видеокарта со штатным охлаждением, но вышеуказанные 80 градусов были при скорости вентилятора чуть больше 2500RPM, это меньше половины (100% - 5400) и на этой скорости она тихая.
Заодно выяснил, что за тот год, что я туда не заглядывал - AMD'шный гайд по OpenCL стал из вообще никакого - довольно интересным чтением. Сижу, читаю. Про Tahiti там пока мало и невнятно, но какой-то раздел по оптимизации уже есть.

P.S. В игры - не играю, ничего не проверял. С картой был купон на DiRT3, но годный до 31 декабря. Смешно, в продаже они появились за неделю до этого....

P.P.S. Lux Render отчего-то вторую карту не видит, как и 5870 не видел. Все прочие разумные тулзы, вроде clinfo и CPU-Z - видят. Прямо хоть в сорцы лезь....

О техническом писательстве

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

Нашел в самой задаче крупное логическое противоречие:

  1. С одной стороны: загружать разработчика такой работой - противоречит самой идее разделения труда. Архитекторы должны архитектить, кодеры - кодить, тестеры - тестить, технические писатели - писать мануалы, а специалисты по пуговицам - пришивать пуговицы.
  2. С другой стороны: технический писатель имеет дело с черным ящиком. Он не знает что там внутри, если в программе вдруг что-то нелогично, то не его (писательское) дело против этого протестовать. Ему что дали - про то он и споет.

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

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

У меня нет никакого конструктива, понятно что варез большого размера в одно рыло не разработать, а значит разделение труда - необходимо(е зло). Но все вместе наводит на меня тоску: найм техписателя для написания доки автоматически означает ухудшение качества продукта (в хорошем случае - с одновременным улучшением качества документации).

Qt: крик души

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

Представим себе какой-то обычный GUI(Windows)-диалог с настройками. Там галочки, пимпочки, выпадающие списки, общим числом с полсотни-сотню, например (5 табов по 10-15 параметров, так и получится).

Ну, понятно, по OK значения в программе апдейтятся, по Cancel - остаются как были, а значит нужен какой-то backing store и в Qt для этого есть, вроде как, Q_PROPERTY.

Сам диалог мы берем и рисуем за 5 минут (или больше, если 5 табов) в Qt Designer. И нам даже породят код для его генерации (главное в этот код не смотреть!) и будут этот код апдейтить если мы что-то передизайнили. Или даже возьмем QUILoader и код не нужен, нарисуем форму динамически, взяв ui-файл из ресурсов.

А вот дальше начинается сущее мучение:

  • Для каждого элемента надо написать Q_PROPERTY(..) (можно и без нее, но сохранение-чтение с пропертями проще).
  • Для каждой проперти - getter/setter ну и саму переменную для стораджа.
  • Значения надо проинициализировать (в конструкторе). Готового механизма "списком" (key-value) нет. Ну, есть полуготовый, можно QMap<QVariant>, но тоже ничего хорошего.
  • Нужно элемент диалога инициализировать из проперти перед показом диалога; нужно значение проперти обновлять, если в диалоге было нажато ОК.
  • Нужен какой-то механизм сохранения значений/восстановления (внешнее хранение настроек). Опять, детали механизма есть, а готового - нет.
И так - 75 (или сколько там настроек) раз. Ну то есть сериализацию/десериализацию можно циклом, затем и Q_PROPERTY, а все остальное - ручками.

Или не ручками, скажите мне, что я пропустил что-то в Qt!!!

Нет, я понимаю, что цивилизованный мир сажает на эту работу индуса (а нецивилизованный - студента), тот легко напишет 75 геттеров-сеттеров методом Copy-Paste, по 750 штук в день. Но ведь не может быть, чтобы это место не было уже автоматизировано в Qt?

Про UI

А вот, к примеру, есть такое вот окошко настроек у какой-то программы ([Preview] - это потому что в Qt Designer, не обращайте внимания):

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

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

  • На выходе - настройки не сохраняются (галка снята).
  • На новом запуске - поднимаются старые настройки.
  • В старых настройках галка "сохранять на выходе" - опять поставлена. Потому что только так, на выходе программы, настройки попадают в сохраненное место.

Кто виноват и что делать? Я вижу такой вот, не вполне тривиальный алгоритм:

  1. Если галка "сохранять на выходе" была снята, то по нажатию ОК мы идем в сохраненные настройки и сохраняем там только состояние этой галки, более ничего не меняем.
  2. Нужно добавить отдельную кнопку Save Settings, которая сохраняла бы текущее положение кнопок (т.е. можно поиграть настройками, нажать Save, потом Cancel - сохраненная копия обновится, а рабочая - нет)
  3. Поставить галку "сохранять на выходе", нажать Save, снять галку, нажать OK - приведет к тому, что в сохраненной копии настроек "сохранять на выходе" станет Off.
Конечно, есть еще вариант, когда галки этой нет, а настройки сохраняются всегда (прямо по нажатию кнопки OK), но он неинтересный.

Q: переносимые имена файлов в локальных кодировках (C++)

А вот, извиняюсь, вопрос.

Вот есть имя файла в национальной кодировке и я его хочу fopen(). На Винде и на Маке одним куском кода (хе-хе).

Насколько я сумел это изучить, ситуация такая:

  • Win32: или я отдаю в fopen() 8-битную кодировку (1251), или в _wfopen() в wchar_t (UCS-16?)
  • Mac: отдаем в fopen() UTF-8 и нам щастье
  • Linux: не знаю, пока руки не дошли.
Но это все с русским, который представим в виде 8-бит. А с китайским? Сдается мне, что в винде это только через _wfopen() получится.

Вопрос: есть какой-то совместимый способ, одинаковый на всех помянутых системах, или так и придется #ifdef WIN32...?

Об исключениях (C++)

Я не люблю C++-ные exceptions (за второй поток управления), как следствие - стараюсь их не использовать, а если использую, то перехватываю только те, которые порождает мой код. Как следствие, правил хорошего тона в этой области не знаю.

Возник вопрос, как правильно поступать. Вот есть такой примерно код:

int some_class::some_function(std::filebuf& buf)
 
  try {
      ....
      buf.sgetn(....);
      .....
      return 0; // OK
  }
  catch (my_own_exception_type t) {
        аккуратно_склеить_ласты();
        return errorcode;
   }
}
Вопрос: должен ли я в подобном коде ловить исключения, порожденные std::filebuf? Ну там не смог он ничего прочесть? А вообще все исключения? Как требуют понятия хорошего тона?

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

  • Этот самый std::filebuf - на самом деле хранится внутри класса, где-то раньше был создан/открыт и все такое. То есть это наш сукин сын.
  • Этот самый IO-хэндл (std::filebuf) передан нам снаружи т.е. это чужой сукин сын.
?

P.S. Нашелся йузер у которого для файлов с SD-читалки не работает std::filebuf IO. Linux, холст, масло....

О вычислениях

Понастраивал тут кластер, добился для 12 нодов эффективности около 70%, на чем (заказчик) и успокоился.

Но все эти дни не отпускала такая вот простая мысль:

  • Вот значит кластер, в нем 7U Blade-серверов (набивка неполная, мест на шасси 10) плюс еще 1U "управляющего фронтенда", OpenMPI, подбор топологии и размеров задачи, чтобы коммуникации и вычислительная моща были сбалнсированы (а уже для 12 нод, без опыта - пришлось повозиться, хотя конечно можно было бы просто оставить подбираться на месяц и помешивать).

    Ну и стоит - не знаю сколько, но так подозреваю, что заметно за $100k.

  • Но те же 1.7 терафлопса получаются на половинке юнита (а добив памяти и увеличив задачу - на той машине уже за 2 Tflop/s получили). Ну ладно, на целом юните, если не увлекаться и просто пихнуть две HD6990 в подходящий корпус. И, по ощущениям, гемороя с отладкой какбэ не меньше. Стоить будет - ну скажем $10k за сервер и еще $2k за две видеокарты.

    Ну хорошо, пусть даже mainstream-решение: 4-GPU-Tesla (1U) и два 1U-сервера. И даже IB (на две ноды - можно без свитча - будет несколько сотен за 40Gbit порт). Но сбалансировать две ноды сильно проще чем 12, я проверял.

    Такой мейнстрим стоить будет тоже не $100k+, а 30-40. Электричества жрать не 6 киловатт, а два. А на 4xTesla те же 1.7 GF

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

P.S. С удовольствием приму участие в настройке какого-то кластера с теслами. Чисто за интерес.

А вот кто хочет кластер понастраивать?

Граждане читатели!

У дружественной мне компании-интегратора есть задача: они поставили заказчику железо в виде blade-сервера, в каждом блейде есть infiniband, на шасси - infiniband-свитч. Все вместе - маленький вычислительный кластер, я так понял что 12 блейдов, наверное 24 процессора, всего ядер получается пара-тройка сотен. Никаких GPU нету, чистый CPU-кластер.

Нужно: провести какую-то настройку этого дела, взгромоздить туда MPI (не знаю какой), запустить HPL и продемонстрировать, что все работает и с какой-то разумной скоростью считает. Получать безумную эффективность не надо, работает, масштабируется как-то - и прекрасно.

Естественно, не бесплатно.

Если вы на практике имели дело с (начальной) настройкой чего-то подобного и имеете желание подработать день-другой (ну я не знаю сколько там надо на самом деле), пишите мне на lexa@lexa.ru и я вас дальше сконнекчу.

По датам это, ориентировочно, нужно в середине следующей недели, вторник-четверг.

P.S. Дефолт-сити.

P.P.S. Обратились, собственно, ко мне, но я не настоящий сварщик и вот прямо в данное время не хочу/не могу учиться за счет заказчика, не до того.

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

Q: InstallShield Limited Edition и вообще про инсталляторы.

Прошу прощения что я не о выборах, но вот такие вот практические вопросы.

Вопрос номер раз

  1. Visual Studio 2010, хочу сделать проект изготавливающий инсталлятор. Ну значит New Solution - и там есть пимпа "Enable InstallShield LE".
  2. Жму в пимпу, мне предлагают этот InstallShield скачать. Скачиваю, запускаю инсталлятор.
  3. Инсталлятор инсталлирует, говорит что надо Studio перезапустить.
  4. Перезапускаю. Одновременно прилетает письмо с серийником.
И вот теперь имею проблему:
  • Куда нужно сунуть серийник - просто не понимаю. Все меню облазил, не нашел.
  • InstallShield-проект создать нельзя. Не создается, failed и все.
Кто виноват и что делать?

Про существование NSIS знаю, но хотел попробовать с InstallShield, чтобы вообще понимать чего хотеть.

О memory bandwidth - 2

Алаверды к предыдущему посту, выношу отдельно, потому что важно.

Sisoft Sandra-й намеряли совсем другие цифирки по memory bandwidth:

  • Ocaholic.ch: 39-40Gb/sec у 3930k/3960x, против 27Gb/sec у i7 2600k (частоты штатные).
  • Overclockersclub.com: примерно то же на штатной частоте, 47 Gb/sec для overclocked-процессора (3960X @4.73Ghz).
А предыдущие цифры (3Dnews) были получены AIDA64.

Вероятнее всего фишка в том что в один поток или в несколько - большая разница.

О memory bandwidth

Вот картинка:

Взято с 3Dnews, но примерно такие же по смыслу цифирки в обзоре Ф-центра, там у них еще круче: в новых CPU использование 2 каналов памяти чуть быстрее чем 3-4-х каналов, а разница с 2600k поменьше.

Чувствую какую-то ерунду, трудно же должно быть сделать 4-канальный контроллер памяти медленнее 2-канального?

Вместе с тем, это избавляет от излишних терзаний, апгрейдить 2600K на домашней WS явно не надо (за исключением случаев упора в 4 ядра, но в память упереться всяко проще).

Update: продолжение тут: О memory bandwidth - 2.

Любви к Drupal7 псто!

Спасибо читателям, помогли разобраться с ненавистью к D7.

Докладываю

1. Кнопки 'Split summary at cursor'/галки 'Show summary at full view' - нету. Но жить можно с визуальным редактором: TinyMCE получает кнопку, аналогичную Split, галка 'Show summary' при этом какбэ по умолчанию, но если что-то написать в Summary, то в списках постов будет именно оно.

Логика чуть другая, но жить можно.

Со вставлением картинок тоже чуть иначе, но тоже жить можно:

Ненависти к Drupal7 псто!

Поигрался с тестовым сайтом, поапгрейженным из Drupal6 в Drupal7, испытал мучительное недоумение.

Снес нахрен, поставил D7 с нуля, недоумение не стало менее мучительным.

У меня, по большому счету, требований очень мало:

  • Мне нужно писать тексты, причем я готов их прямо в HTML фигачить. От визивигов яваскриптовых - тошнит, если честно.
  • Мне нужно управлять текстом аннотации, которая на глагне показывается. И средств D6 мне более чем хватает (а там можно, если не доверяешь автомату, разделить текст на аннотацию и хвост, аннотации поставить галку "входит в полный текст"), т.е. я могу сколько хочу абзацев сделать аннотацией, а могу ее отдельно написать).
  • Мне нужно просто вставлять картинки:
    • простой браузер того, что уже залито на сервер.
    • простая кнопка, позволяющая поаплоадить (и задать alt/title, чем я не пользуюсь, впрочем)
    • вставка с указанием размера (оригинал, какие-то стандартные, возможность задать свои), выравнивания и действия при клике на картинку (ничего, открыть полный размер в новом/том же окне, перейти по ссылке).
  • Ну теги-категории, понятно и прочие мелкие галки (кросспост в ЖЖ, режим комментариев, задание URL)
  • Все, больше ничего не надо. Если захочу клип с Youtube - руками вставлю, надо редко.

Всю эту функциональность умеет Drupal6 из коробки + image/image assist + чуть-чуть других модулей.

А вот D7 привычную картину D6 нарушает в куче мест:

Drupal6 -> Drupal7

В очередной раз подошел к снаряду по имени Drupal7. Имею сказать:

1. Если у вас PostgreSQL, то даже Drupal 7.9 (текущий) не сможет поапгрейдиться гладко. Оно пытается сконвертировать поля типа text в тип bytea, а в PostgreSQL 9.1 (другие не пробовал) автоматического преобразования этих типов нет.

Лечение (применяется к базе PostgreSQL до апгрейда):

CREATE OR REPLACE FUNCTION text2bytea(text) RETURNS bytea AS
$BODY$
begin
 return convert_to($1,'UTF-8');
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
CREATE CAST (text as bytea) with function text2bytea(text) as implicit;
Может я тут что и перепутал и as implicit не нужно, но работает и "базовый" сайт (core modules) переносит.

2. А вот в том, что касается contributed modules - счастья у меня нет:

Душераздирающее зрелище

Не могу молчать, хочу писать.

Случившийся давеча бунт гаджетов (и сервисов) наводит на меня тоску:

  1. Сюрпризом для меня оказалось количество мест, дублирующих TZ database: операционная система (про которую было известно заранее), PHP, PostgreSQL (в ветке 8.x база TZ старая), Java - это только то, про что я сам знаю. А реально мест - существенно больше.
  2. Таким же сюрпризом оказалось то, что сервисы надо перестартовывать, просто апдейта TZdb и /etc/localtime - недостаточно.
  3. Владельцам продвинутых гаджетов веселухи добавила продвинутая автоматика, вроде установки времени "от GSM-сети" (а сети все проэтосамое, а может просто побоялись свитчи обновлять ради такой мелочи) или, еще веселее, установки таймзоны по GPS-координатам, как это во многих навигаторах сделано (проверил, в моем Garmin 62s просто нельзя поставить offset в часах, только по имени города).
  4. На этом фоне сообщение РЖД о том, что в ж/д сообщении с Украиной будет бардак до 3 декабря, а дальше будет видно - уже не вызывает удивления, хоть и вызвано это не IT-бардаком, а законодательными инициативами у братского народа: сначала отменой перехода на зимнее время (в сентябре, по мне так безумно поздно), а затем отменой отмены (в октябре, еще веселее).

Про перевод часов, таймзону, PHP и Drupal

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

PHP:

  1. У PHP база данных таймзон вшита в пузо и, конечно, не обновляется регулярно.
  2. Но есть pecl-timezonedb, который ее оверрайдит, со свежей базой (последняя имеет номер версии 2011.13), с этим расширением с таймзонами все станет отлично и любимая всеми Europe/Moscow будет работать как полагается по новым правилам.
  3. Но если вы живете под FreeBSD, то там /usr/ports/misc/pecl-timezonedb не обновлялся очень давно, посему:
    • Меняем там в Makefile 2010.9 на 2011.13
    • удаляем distinfo
    • make && make install
  4. Добавляем timezonedb.so в список extensions.ini (на FreeBSD это сделает make install)
  5. Перестартовываем PHP-fastcgi или Apache или что у вас там работает процесс-сервером для PHP
  6. Ура, можно накатить первый стакан.

Drupal 6:

  1. Сам по себе сразу начинает жить правильно (ну, насколько мне показалось). Т.е. таймзона меняется после апдейта PHP-timezonedb с +0300 на +0400 сама.
  2. Но! В Administer-Date-and-time есть настройка про User Configurable time-zone. Если она включена, то пользователю будут показываться даты-времена в его таймзоне. И весь созданный им контент будет иметь время создания рассчитанное из юзерской таймзоны.
  3. Но. Юзерская таймзона специфицирована в секундах смещения от UTC.
  4. Выходов два: или для всех российских пользователей взять и поправить скриптом (по хорошему, с учетом даты регистрации), или просто отменить настройку пользовательских таймзон. Я пошел по второму пути.

"я не знаю, был ли я все еще воскресным или уже понедельничным"

Update: первое место на конкурсе известно кого занимает PHP, где таблица таймзон - вшитая, а не системная. Всех бы убил, да. pecl-timezonedb спасает.

Приз зрительских симпатий за перевод часов получает Яндекс-почта.

Рассказываю:

  • На часах 11:26 (правильного времени), вхожу в Я-почту, вижу там внизу "последний вход в 10:54"
  • Действительно, в 10:54 я туда заходил, написать сам себе письмо и посмотреть на даты в заголовках (и все было прилично).
  • Выхожу (на часах 11:26), вхожу, выхожу, вхожу.
  • Надпись внизу остается все та же, про 10:54.
  • Повторяю еще и еще раз, наконец в 11:55 добиваюсь, надпись меняется на 11:26 (время начала экспериментов). Хотя с 11:26 я входил и выходил раз 10 минимум (а в промежутке 10:54-11:26 - нет).
  • Подозреваю, что в следующий раз "время последнего входа" сменится в 12:26 MSK, через полчасика проверю. Yes! Теперь оно залипло на 11:56

О время-время, темпо-темпо

Ну что, сколько у кого серверов перевело время сегодня с утра?

О бульдозерах

Я редко анонсирую читаемые ссылки с веба (как бы, блин, автоматизировать выкладку закладок из Evernote в твиттыр, с удобным редактированием?), но тут - тот самый случай.

Читаю Арстехнику: Can AMD survive Bulldozer's disappointing debut?, много думаю:

  • Один FPU на два ALU мне изначально казались какой-то фиговой идеей, ибо аккуратно программируя этот самый SSE зачастую удается порядок прироста в хотспотах получить (раза три на SSE и еще столько же на 4x ядрах), не делая всю программу многопоточной. А тут выясняется еще, что старый FPU имел 3 одинаковых юнита и формально умел 3 операции на такт (ограничений я точно не знаю, но подозреваю что как у Интела - 1 load/store, 2 математики, во всяком случае всякие тесты вроде GEMM давали ~1.8 op/clock что похоже на 2 теоретических операции). А у нового - 4 юнита, но два из них целочисленные, а два - плавучка. Это что, 1 op/clock будет? Ну ладно, для GEMM спасемся FMA, а для всего остального?
  • Идея AMD в том, что вместо SSE-операций надо переползать на APU. Идея отличная, APU умеет scatter-gather, в отличие от SSE, но беспокоят такие вот мелочи:
    • Где, собственно, бульзозер с APU?
    • APU - это же OpenCL, со всеми прелестями двойной буферизации, прямо in-place не поработаешь.
    • Ну и переносимость тоже тревожит. Старый код будет работать плохо, да?
  • Порадовала мысль о том, что в "несколько-поточном" (threads меньше чем cores) приложении планировщик должен их раскидать так, чтобы часть модулей освободить от нагрузки, тогда можно у загруженных частоту поднять.
  • Вместе с тем, планировщик потоков должен еще знать, какие из threads жрут много FPU - чтобы раскидать по одному такому потоку на модуль. А откуда планировщику это знать? Должен быть какой-то API, позволяющий это сказать....
Короче, бардак какой-то с этими бульдозерами, августовские анонсы оставляли лучшее впечатление.

Pages

Subscribe to Программирование