Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Использование ассемблера для оптимизации программ на С++ - Магда Ю.С.

Магда Ю.С. Использование ассемблера для оптимизации программ на С++ — БХВ-Петербург , 2004. — 496 c.
ISBN 5-94157-414-2
Скачать (прямая ссылка): ispolzovaniyaassemblera2004.djvu
Предыдущая << 1 .. 99 100 101 102 103 104 < 105 > 106 107 108 109 110 111 .. 127 >> Следующая

1. В потоке создается объект таймера ожидания с помощью функции CreateWaitableTimer. Через определенный интервал времени (например, когда поток завершил обработку данных) объект таймера ожидания переходит в сигнальное состояние.
2. Функция ожидания основного потока или процесса (в нашем случае waitForSingieObject) проверяет объект синхронизации (таймер ожидания). Если объект перешел в сигнальное состояние, функция ожидания возвращает значение wait object o. В случае получения этого значения основной процесс может считать вызываемый поток завершенным и
Гпава 12. Оптимизация многопоточных приложений с помощью ассемблера
395
приступить к обработке полученных данных. Кроме того, желательно удалить и сам объект синхронизации, который нам уже не понадобится, с помощью функции CancelWaitableTimer.
На практике указанная последовательность выглядит так. Создается объект таймера ожидания в каждом из потоков с помощью функции createwaitabieTimer. Функция возвращает дескриптор объекта, который в дальнейшем используется для обращения к объекту таймера ожидания. После этого с помощью функции setwaitabieTimer таймер активизируется. Одним из параметров вызова функции является указатель на переменную, содержащую значение интервала времени, через который объект таймера будет установлен в сигнальное состояние. В нашем случае этот интервал, единицей измерения которого является 0.1 микросекунды, записывается в переменную liDueTime. Величина интервала выбрана произвольно й равна 10 миллисекундам.
Фрагмент кода для любого из потоков приблизительно одинаков:
jnz next fwait };
yTimer = CreateWaitableTimer (NCJLL, TRUE, "yTimer");
SetWaitableTimer(yTimer, SliDueTime, 0, NULL, NULL, 0);
}
В нашей программе указан интервал времени, равный 10 миллисекундам, определяющий момент завершения функции поиска символа во вспомогательном потоке. Хотя это значение выбрано произвольно, следует помнить, что при разработке подобных приложений установка такого параметра определяется быстродействием потока. Может случиться так, что все необходимые операции не успеют завершиться до того, как будет установлен сигнал. Не случайно в таких задачах интенсивно используется язык ассемблера. Ассемблерный код, являясь очень быстрым, позволяет работать нескольким потокам с минимальным временем синхронизации!
Я не буду анализировать алгоритм поиска символа, реализованный в ассемблерном блоке — он довольно прост, и читатель сумеет без особого труда разобраться в нем.
Когда функция ожидания WaitForSingleObject ВЫЗЫВаеТСЯ ОСНОВНЫМ ПОТОКОМ или процессом, она проверяет условие установки сигнала. Если условие не выполнено, вызывающий поток или процесс переходит в состояние ожидания. Ресурсы центрального процессора в этом состоянии почти не используются. Возобновление работы приложения продолжается, если условие
396
Часть III. Встроенный ассемблер Visual C++ .NET2003 и его использование
выполнено. Сразу же после выполнения функции ожидания объект таймера ожидания уничтожается С ПОМОЩЬЮ вызова функции CancelWaitableTimer, принимающей в качестве параметра дескриптор объекта таймера. Вот фрагмент кода основной программы:
while (WaitForSingleObject(tTimer, INFINITE) != WAIT_0BJECT_O; CancelWaitableTimer(tTimer);
Эта программа требует включения библиотеки многопоточности. Например, если компиляция приложения с исходным файлом mythreads.cpp выполняется из командной строки, то это выглядит так:
cl /МТ /D "_Х86_" mythreads.cpp
Если компиляция выполняется в среде Visual C++ .NET 2003, то необходимо установить опцию /мт вручную. Вот последовательность шагов:
1. Выберите в меню Project опцию Properties.
2. Выберите страницу Configuration Properties / C/C++ / Code Generation / Runtime Library.
3. Установите опцию компилятора в /мт.
Окно работающего приложения показано на рис. 12.1.
'¦.'I j ¦' !-: [S" .-¦¦¦¦ ¦!]¦!\j\,i.. ';-v1 -I'!\-:iil;li,:'*!i¦ . -
SUHlI

Рис. 12.1. Окно приложения, демонстрирующего выполнение трех потоков
Рассмотрим еще один пример работы приложения с несколькими потоками. Приложение вычисляет частное от деления квадратного корня из одной переменной на квадратный корень из другой. Обе переменные находятся в
Гпава 12. Оптимизация многопоточных приложений с помощью ассемблера
397
двух равных по размеру массивах вещественных чисел на одних и тех же позициях.
Реализация вычислений происходит следующим образом:
? в одном потоке вычисляется квадратный корень переменной из первого массива (назовем его f 1);
? в другом потоке вычисляется квадратный корень переменной из второго массива (назовем его f2);
? основная программа после завершения работы потоков использует полученные данные для дальнейших вычислений (деления).
Этот пример во многом похож на предыдущий, но он демонстрирует, как можно обрабатывать числовые величины вещественного типа. Поскольку интенсивность вычислений для операций с плавающей точкой намного выше, чем для символов, то следует внимательно отнестись к выбору величины времени синхронизации объектов таймеров ожидания с основным процессом. Исходный текст консольного приложения приведен в листинге 12.2.
Предыдущая << 1 .. 99 100 101 102 103 104 < 105 > 106 107 108 109 110 111 .. 127 >> Следующая