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

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

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

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

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

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

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

В мультимедийных приложениях следует избегать операций с плавающей точкой, поскольку целочисленные преобразования выполняются быстрее.
Передавать данные в функции следует по ссылке, а не по значению. Кроме того, данные желательно выравнивать на границу двойного слова. Предпочтительно использовать глобальные переменные вместо локальных.
Улучшения производительности мультимедийных приложений можно добиться за счет оптимизации алгоритмов преобразования векторных данных и использования многопоточности.
Концепция многопоточности является очень важным аспектом написания мультимедийных приложений. Ни одно серьезное мультимедийное прило-
13 Зак. 243
382
Часть III. Встроенный ассемблер Visual C++ .NET 2003 и его использование
жение не обходится без потоков. Потоки обычно используются для решения следующих задач:
? создания управляющих элементов и меню;
? создания звуковых эффектов;
? обновления структур данных;
? обновления кадров анимации.
Этими задачами применение потоков не ограничивается, существуют и другие варианты их использования. Более подробно работа многопоточных приложений будет рассмотрена в главе 12, сейчас же я приведу пример программы с двумя потоками (основным и вспомогательным), в котором производится масштабирование трехмерного вектора с координатами в массиве al и коэффициентом масштабирования, равным 4. Кроме этого, вычисляется длина отрезка вектора. Вначале рассмотрим вариант программы с использованием обычных операторов C++ .NET (листинг 11.1).
и зычисления длины вектора (вариант на C++)
// MHTHREAD_GRAPHICS.срр : Defines the entry point for the console // application.
¦include "stdafx.h"
¦include <windows.h>
¦include <math.h>
int il;
// Координаты вектора (x, у, z) int al[4] = {4, 7, -3}; void myFunc(LPVOID kl)
{
for(il = 0;il < 4; il++) al[il] = (int)kl*al [il];
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE mythread;
Гпава 11. Оптимизация мультимедийных приложений с помощью ассемблера 383
DWORD mythread_id; double vec_len;
printf("CHANGING THE LENGTH OF VECTOR a = (aO, al, a2) (DirectX <? Optimizing Tips)\n");
printf("\nBefore scaling vector a = (%d, %d, %d)\n", al[0], al[l], <P al [2]);
vec_len - sqrt((double)(al[0]*al[0]+al[1]*al[1]+al[2]*al[2])); printf("\Length of al - %.2f\n", vec_len);
printf("\n\n Starting thread...\n\n");
mythread = CreateThread(NULL,0, (PTHREAD_START_ROUTINE)myFuncf
(LPVOID)(4), 0, &mythread_id);
while(true)
{
if(WaitForSingleObject(mythread, 0) == WAIT_OBJECT_0)
{
vec_len = sqrt((double)(al[0]*al[0]+al[1]*al[1]+al[2]*al[2])); break;
}
// Здесь выполняются какие-либо полезные действия }
CloseHandle(mythread);
printf("After scaling vector al = (%d, %d, %d)", al[0], al[l], al[2]); printf("\nLength of al = %.2f\n", vec_len); printf("\n Thread terminated...\n");
getchar(); return 0;
)
В этой программе основной процесс использует вспомогательный поток mythread. В этом потоке проводится вычисление новых координат трехмерного вектора. Основной поток ожидает завершения вычислений mythread для подсчета длины вектора с помощью оператора
vecJLen = sqrt((double)(al[0]*al[0]+al[1]*al[1]+al[2]*al[2]))
Окно работающего приложения показано на рис. 11.1.
384
Часть III. Встроенный ассемблер Visual C++ .NET2003 и его использование
ГР*
Serf'S:, d;:, 5 c'U ifc, ai-:(J <Ь 'VVf id « i ч\i ii'.'ii'SlUv j'i.?'':!!; s]
ii !:4;hJ.. ji.“. ¦ j i! J.! Ш t i -Ч:1 !¦ -»/!!? i Si; 1 V' S .!'¦ :;f liii. .(( r i -i 1 S;; >
::.... *;Ev,: - (4. Y1 .. '.b
nsrth of al = ШЛШ
fteF scaling weetep al.
Рис. 11.1. Окно приложения, демонстрирующего операции с векторами
Программу можно улучшить, если оптимизировать некоторые участки кода, связанные с математическими вычислениями. Прежде всего, можно упростить реализацию вычислений в функции потока, если использовать ассемблер. Функция
void myFunc(LPVOID kl)
{
for(il = 0;il < 4; il++) al[il] = (int)kl*al[il];
}
может быть переписана на ассемблере и представлена следующим образом:
void myFunc(LPVOID*)
{
_asm {
lea ESI, al
lea EDI, cl
mov ECX, 3
sub ESI, 4
next:
add ESI, 4
fild DWORD PTR [ESI] fimul DWORD PTR cl fistp DWORD PTR [ESI] dec ECX
jnz next
Глава 11. Оптимизация мультимедийных приложений с помощью ассемблера
385
Для оптимизации лучше всего использовать математический сопроцессор или одно из расширений (ММХ или SSE). Исходный текст модифицированного приложения представлен в листинге 11.2.
Листинг 11.2. Моджфицмроейкный вариант операции с иекторами
// OPTIMIZING_VECTOR_OPERATIONS.ерр : Defines the entry point for the // console application.
¦include "stdafx.h"
¦include <windows.h>
¦include <math.h>
int il;
int al[4] = {4, 7, -3}; // size of.vector = sqrt((al-aO)*(al-aO)+....) const int cl = 4;
void myFunc(LPVOID kl)
{
_asm {
lea ESI, al
lea EDI, cl
mov ECX, 3
sub ESI, 4
next:
add ESI, 4
fild DWORD PTR [ESI] fimul DWORD PTR cl fistp DWORD PTR [ESI] dec ECX
jnz next
)
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE mythread;
DWORD mythread_id; double vec len;
Предыдущая << 1 .. 96 97 98 99 100 101 < 102 > 103 104 105 106 107 108 .. 127 >> Следующая