суббота, 26 июня 2010 г.

Частое обращение к полям класса может быть невыгодным

0 коммент.
Инкапсуляция данных - это, конечно, хорошо. В том смысле, что улучшает структурированность и расширяемость. Однако, прежде чем писать что-то высокопроизводительное, используя ООП, нужно узнать свой компилятор поближе.
Возьмем обычное умножение матриц. Их уже давно никто вручную не умножает, потому что умножение больших матриц нигде не используется, а умножение маленьких матриц - вообще не задача для высокопроизводительных вычислений. Однако именно перемножение больших матриц является своеобразным испытанием для компилятора, так как теоретически сложность алгоритма фиксирована, а на практике зависит от расположения матриц в памяти.
Возьмем простейший пример. Есть класс Child, в нем есть в качестве полей три матрицы и метод, который перемножает первые две и кладет результат в третью. Казалось бы, что тут может быть сложного для компилятора?


С компилятором MSVC2008 время перемножения multiply() примерно в два раза больше, чем outside_multiply. На форуме WDC мне ответили, что обращение к полям класса требует постоянного получения *this, и компилятор не может это оптимизировать. Странно, конечно. Ведь, во-первых, указатель *this постоянный по крайней мере в течение выполнения одного метода, а во-вторых, можно же расположить матрицы в памяти так, чтобы они шли хотя бы друг за другом?
Что интересно, компилятор GCC 3.4 для Windows справляется с этой задачей: время перемножения обоими методами одинаковое. GCC 4.1 дает результат похуже, но все равно не такой, как MSVC. Еще один плюс в копилку GCC. Хоть он и строго (иногда излишне строго) соблюдает Стандарт, его оптимизатор превосходит MSVC.

вторник, 22 июня 2010 г.

Преобразование dynamic-диска в basic

0 коммент.
Dynamic Disk - это проприетарный (Microsoft, Veritas/Symantec) формат логических разделов. Он хорош тем, что позволяет создавать любое количество разделов на диске, при этом разделы могут быть простыми, составными, чередующимися, зеркальными и др. Преобразование basic-диска в dynamic в Windows возможно одним кликом. Однако вот обратная операция доставляет огорчение, унижение и боль.
Собственно, зачем нужно преобразовывать из такого замечательного формата, как dynamic disk, обратно в basic? Проблема как раз в проприетарности. Хотя проприетарную файловую систему NTFS уже давно научились читать, писать и изменять, формат dynamic disk все еще остается либо неизвестен, либо в крайнем случае read-only для сторонних программ. Здесь надо отдать должное юниксовому NTFS-3G, который может монтировать разделы с dynamic-диска в режиме чтения и записи.
Утилит для операций с dynamic disk, кроме самой Windows, не существует. Любая сторонняя программа видит структуру dynamic-диска либо как огромную неразмеченную область, либо как область неизвестного формата. Линуксовый gparted определяет на диске размером 1 ТБ четыре primary-раздела, первый размером около 100 МБ, - второй около 32 ГБ, и дальше по увеличению. Даже утилиты от Symantec не умеют работать с dynamic-дисками. Это означает, во-первых, невозможность установки второй ОС, отличной от Windows, во-вторых - затруднение восстановления данных с диска в случае сбоя.
Для того, чтобы преобразовать dymaic-диск в basic, необходимо сохранить все данные на другой носитель, так как единственный безопасный способ преобразования - форматирование. Если переустановка системы не является проблемой, то на этом можно успокоиться. В противном случае необходимо создать точный образ системного раздела например с помощью Norton Ghost. Нужно помнить, что в отличие от предыдущих Windows, семерка обычно создает для себя два раздела: один размером 100 или 200 МБ, и второй, указанного пользователем размера. На первом разделе (System Reserved) хранится загрузчик и среда для восстановления системы. Поэтому придется создавать и его копию тоже, иначе загрузить Windows просто так не получится.
Итак, все данные с жесткого диска сохранены, образы системных разделов созданы. Осталось развернуть эти разделы на отформатированный жесткий диск. Если образы были созданы с помощью Norton Ghost, то понадобится Norton Ghost BootCD. Это что-то вроде Windows LiveCD с Norton Ghost на нем. Из-под него можно легко отформатировать диск и развернуть образы.
Теперь о боли и унижении. В современных SATA-дисках есть поддержка NCQ (Native Command Queing), которая в определенных условиях дает прирост производительности жесткого диска. Это не только серверные приложения, но и, к примеру, сборка/компиляция больших проектов. Для ее работы на материнской плате должен быть включен режим AHCI (Advanced Host Controller Interface). Если просто развернуть образы системных разделов Windows 7 на отформатированном жестком диске при включенном AHCI, на некоторых (возможно, даже на большинстве) материнских платах не получится даже загрузить экран настройки BIOS! Где-то здесь у оператора появляется ощущение, что его крыша начинает тихонько шуршать шифером, двигаясь по направлению к земле. Каким образом системный раздел Windows 7 может мешать загрузке BIOS?
Оказывается, тот самый раздел System Reserved размером 100 или 200 МБ заставляет AHCI BIOS неправильно определять геометрию диска. Это выяснил человек [RU] Ivan на Windows Client TechCenter. Вот его пост:
the problem is in disk geometry detection in AHCI mode. for example:
1. get empty disk. check didk geometry with system info. you will see Tracks/Cylinder = 255, Sectors/Track = 63. Create 100MB NTFS partition with Windows Disk Manager. Reboot. Check disk geometry - it changes!
2. Why disk geometry changed? because BIOS thinked that partition end is aligned to end of cylinder. So it uses END CHS value for first partition and LBA END for counting new geometry. In my case I saw the following
record in master boot record.
END CHS = DF 13 0C (END HEAD = 0xDF) Disk Geometry Tracks/Cylinder chaged after reboot from 255 to 224. 224 = 0xE0 = 0xDF + 1
As you can see DISK GEOMETRY IS DETERMINED BY END CHS VALUE FOR 1ST PARTITON
3. Now imaging the following you again get empty disk with geometry 255/63. Create partition with size 101MB or 352MB or 705MB or there are pretty much other sizes. These sizes are specific - after creating partition with this size you will get ZERO in end chs for 1st partition.
Reboot now - and you will see that bios hangs - cause disk must have positive Tracks/Cylinder.
How to fix this?
-DO NOT USE AHCI
or
-use large 1st partitions more than 8GB (end chs for such partition always FE FF FF).
Что интересно, "специалист" из Microsoft, похоже, не имеет понятия о данной проблеме:
Hi jtclh,
Before moving on, I would like to share the computer boot process for you.
When the computer's power is first turned on, the CPU initializes itself and look to the system's ROM BIOS for its first instruction in the startup program. Then, if the BIOS does not detect a battery failure, it then continues to initialize the CPU, checking the inventoried hardware devices. If all components are functioning properly, BIOS will look for an OS to load. The BIOS setting (Boot Sequence) tell computer where to find OS.
On the problem, computer hangs before loading OS (Windows 7), so it should not be a Windows 7 problem. It may be a hardware problem. Given the situation, I suggest you reset BIOS setting to test the issue. If the issue still persists, it is recommended to contact Manufacturer Support to address the issue.
Thank you for your understanding.
Вернемся же к разделу System Reserved, так как загрузке системы, как ни странно, мешает именно он. Если включен режим AHCI, то после перезагрузки систему будет невозможно загрузить. Если просто удалить раздел System Reserved, то не загрузится Windows 7. Вообще говоря, из-под Windows LiveCD типа Norton Ghost BootCD это исправляется легко, так как там доступна утилита diskpart. Но это обязательно нужно делать до первой перезагрузки, иначе не потом не получится войти в настройку BIOS, чтобы выключить AHCI. Либо, если AHCI выключен, можно это сделать уже из-под развернутой на жестком диске Windows. Делается данная операция следующим образом.
В консоли (желательно с правами администратора) запускается diskpart. Далее
list disk
select disk <номер нужного жесткого диска>
list volume
select volume <номер первого раздела размером 100 МБ, обычно 0>
inactive
В результате раздел System Reserved стал неактивным. Теперь нужно сделать раздел с установленной Windows 7 активным и загрузочным.
select volume <номер второго раздела, на котором стоит Windows, обычно 1>
active

Выходим из diskpart и пишем загрузочные файлы на теперь уже активный раздел:
bcdboot c:\windows /s C:
После перезагрузки раздел System Reserved можно удалить. Еще более подробно это описано здесь. Теперь, если все прошло нормально, можно включить режим AHCI.
Подобная ситуация с зависанием AHCI BIOS может произойти и при обычной установке Windows на жесткий диск. Для предотвращения необходимо предварительно создавать один раздел в начале диска, на который и устанавливать.

понедельник, 9 марта 2009 г.

Простой учет номера билда в MSVC++

0 коммент.
Казалось бы, такой удобный и наполненный фичам инструмент этот VS, а счетчика номера билда в нем нету. Есть для этого Add-in'ы, но они на Express-версию не ставятся. Задача -- сделать быстро и просто, и чтобы работало вне зависимости от версии MSVC. По аналогии можно потом прикрутить что-нибудь поинтереснее.
Итак, надо чтобы после каждого билда номер билда увеличивался на единицу. И этот номер пусть будет макросом BUILD_NUMBER в файле version.h. В настройках проекта, Build -> Post-build event пишется cscript incnum.js, а вот и сам incnum.js:

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

воскресенье, 25 января 2009 г.

Создание DVD из TS

0 коммент.
Записанные с спутника DVB-видео (формата TS), если их размер меньше, чем 720х576, можно легко преобразовать в DVD-совместимые MPG, и потом в DVD. Если в TS-файле нет никаких ошибок или пропусков, то можно его "перегнать напрямую", используя ffmpeg:
ffmpeg -i file.ts -acodec copy -vcodec copy file.vob
или MEncoder:
mencoder -oac copy -ovc copy -of mpeg -mpegopts \
format=dvd -o file.vob file.ts

Однако, если присутствуют ошибки в потоке, может произойти рассинхронизация, или еще что похуже. Для таких случаев существует ровно 3 инструмента:
VideoReDo [Win32]
Работает быстро и качественно. Имеет поддержку скриптования с помощью ActiveX. Платен.
replex
Работает быстро, но плохо. Режим Remux выдает DVD-совместимый MPEG, но при этом видео начинает как-то странно дергаться. Режим Demux выдает "битые" потоки. То есть либо звук, либо видео может кончиться на середине. Хорошо бы такие "битые" потоки как-то исправлять, т.е. находить, в каких местах поток кончается, и исправлять маркер конца на пустой кадр.
ProjectX
Очень странный инструмент, написанный на Java. Странный потому, что, во-первых, работает быстро, а во-вторых, может любой TS-файл разделить на видео и звук, попутно исправляя в них ошибки.
Чтобы получившиеся аудио- и видеопотоки свести вместе в один DVD-совместимый MPEG, лучше всего использовать mplex. И, чтобы не терять даром время, получившийся программный поток можно по конвейеру передавать dvdauthor:
mplex -f 8 -o - file.m2v file.m2a | dvdauthor -t - -o \
path_to_dvd

Только вот mplex не знает, что "-" - это stdout. Это легко исправить. Нужно в файле main.cpp (/mjpegtools-*/mplex) в функцию int FileOutputStream::Open() добавить:

Описанный выше вариант преобразования MPEG-TS в DVD - пока что единственный рабочий (с использованием фриварных и кроссплатформенных утилит).

четверг, 15 января 2009 г.

Массовый опрос сети

0 коммент.
Иногда бывает нужно найти все машины в сети, слушающие определенный порт TCP. Например, для того, чтобы запустить программу с MPICH (сам по себе MPICH не умеет находить машины). Все машины, на которых стоит и запущен MPICH, слушают один и тот же порт (8675 по умолчанию).
Для начала, нужно найти все машины в сети. Для этого рассылаются ICMP ECHO пакеты. Под *x это делается через сокеты, что требует прав рута. Одна из таких программ - fping. Она компилируется и под Win32 (cygwin, mingw), и тоже требует прав администратора.
Однако, под Win32 все намного проще. Есть специальный API для ICMP, не требующий особых прав. Можно написать что-то типа аналога fping. Вот кусок кода, взятый с АНТИЧАТ:


Вышеупомянутая утилита fping может принимать на вход список IP-адресов, и, сканируя их, выдавать только те, что доступны. Это удобно, и это стоит реализовать в нашем Win32-аналоге fping.
Кстати, Win32-вариант работает раз в 5 быстрее.

А теперь, когда есть список машин, можно к каждой пытаться соединиться на выбранный порт. Одновременно.


Данный скрипт под Win32 может выдать список адресов где-то за 5 секунд. И от ширины канала это особо не зависит.

Есть маленькое неудобство: адреса не сортированы. Если сортировать эти адреса как строки, то, например, адрес 192.168.1.11 будет идти раньше, чем 192.168.1.9. Чтобы не углубляться в преобразования адресов, можно просто сделать сортировку по числу после последней точки, то есть:


Очевидно, что если адреса будут отличаться на 2 разряда и больше, такой способ не пойдет.

четверг, 25 декабря 2008 г.

Christmas VLC

0 коммент.

Разработчики VLC не перестают радовать пользователей. И, вместе с тем, делать свое творение еще более популярным.
Где-то после 16го декабря (линуксоиды сообщают о 19м), иконка VLC в панели задач "оделась" по-новогоднему. По крайней мере, это первое, что бросилось в глаза. Естественное желание - посмотреть в Help->About - было тоже учтено. В общем, выходит, что все иконки vlc, включая полноразмерные, "переоделись". Веселенький такой [Easter] Christmas Egg :)

воскресенье, 14 декабря 2008 г.

Getopt и неGNU

0 коммент.

Многие спрашивают: а где же Getopt в Windows? Ответ прост: там же, где и libc. То есть нету. Портировать libc под Win никто не хочет, и не собирается. И если большинству функций в libc есть альтернативы в MSVC и др., то Getopt альтернативы нет. Разве что boost::program_options, но он не очень-то функционален или удобен.

Так вот, на FTP GNU можно взять исходник GNU hello, в котором будет Getopt, unistd.h и еще кое-что полезное. Getopt там полностью рабочий, а unistd.h идет как заглушка\обертка, но в любом случае полезная для портирования вещь. Эти фрагменты glibc туда включены для обеспечения совместимости с неGNU системами, и предполагается, что пишущие под GPL тоже будут их включать в свои исходники. К сожалению, почти никто так не делает (разве что в Apache был замечен Getopt.c). Иначе портировать было бы гораздо легче.

 
Design by BloggerThemes | This template is brought to you by : allblogtools.com