|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июл 10, 2004 18:20:27 Встала необходимость сделать очень быстрый алгоритм вращения. Получилось нечто вроде: int dwS = s*1024; int dwC = c*1024; _asm { mov ecx, dst.bottom sub ecx, dst.top //dec ecx movd mm0, dst.right psubusw mm0, dst.left Y: dec ecx js endY //{ //(y-yc)*sin mov eax, ecx sub eax, cntr.y imul eax, dwS movd mm1, eax // (y-yc)*c mov eax, ecx sub eax, cntr.y imul eax, dwC movd mm2, eax //lpDst mov edi, lpDst mov eax, stepDst imul eax, ecx add edi, eax sub edi, 2 movd edx, mm0 X: dec edx jz endX //{ add edi, 2 movd eax, mm1 //(x-xc)*cos mov ebx, edx sub ebx, cntr.x imul ebx, dwC // s-c + xc sub eax, ebx sar eax, 10 add eax, cntr.x // if x cmp eax, src.right jnl X cmp eax, src.left jl X //lpSrc for x mov esi, lpSrc lea esi,[esi+eax*2] movd eax, mm2 //(x-xc)*s mov ebx, edx sub ebx, cntr.x imul ebx, dwS //s+c+yc add eax, ebx sar eax, 10 add eax, cntr.y //if y cmp eax, src.bottom jnl X cmp eax, src.top jl X //lpSrc for y imul eax, stepSrc add esi, eax //moving mov ax, [esi] mov [edi], ax //} jmp X endX: //} // dec ecx // jnz y jmp y endY: emms }; Вопрос в следующем. Может быть кто-нибудь из уважаемых гуру не вникая в алгоритм даст хоть какие-нибудь рекомнедации по дальнейшей оптимизации. Целевая машина Celeron 600. |
|
|
Дата: Июл 10, 2004 21:29:57 Вот пример того, как это можно сделать без умножений: //xd= (xs-xc)*c+(ys-yc)*s+xc
//yd=-(xs-xc)*s+(ys-yc)*c+yc
//xd-xc=(xs-xc)*c+(ys-yc)*s
//yd-yc=-(xs-xc)*s+(ys-yc)*c
//xs-xc=(xd-xc)*c-(yd-yc)*s
//ys-yc=(xd-xc)*s+(yd-yc)*c
//xs=xd*c-yd*s+(xc-xc*c+yc*s)
//ys=xd*s+yd*c+(yc-xc*s-yc*c)
dword xs,ys,yd,xd,signx,signy //челые числа
dword dx,dy,sumx,sumy //только дробная часть
qword a,b //число с фиксированной точкой формата 32:32
a=xc-xc*c+yc*s
b=yc-xc*s-yc*c
signdx=sign(c)
signdy=sign(s)
dx=abs(c)*maxuint
dy=abs(s)*maxuint
//на самом деле границы этого цикла должны быть такими,
//чтобы мы не вышли за пределы исходной картинки
for(yd=0;yd<height;yd++)
{
sumx=(-yd*s+a)*(maxdword+1)
sumy=(+yd*c+b)*(maxdword+1)
if(c<0)
sumx = ~sumx
if(s<0)
sumy = ~sumy
//здесь тоже нужно определять границы
xs=-yd*s+a//+xd*c прибавляется если мы определяем гнаницы
ys=+yd*c+b//+xd*s
for(xd=0;xd<width;xd++)
{
sumx+=dx
if(cf==1) // на самом деле вместо этого if'а должно быть sbb или adc в зависимости от знака c
xs+=signdx
sumy+=dy
if(cf=1) // sbb или adc в зависимости от знака s
ys+=signdy
[dest]=src[ys][ys]
dest++
}
dest+=width
}
|
|
|
Дата: Июл 10, 2004 21:32:19 не вникая в алгоритм Ну... У тебя внешний цикл по Y, внутренний по X. Оптимизировать внутренний в первую очередь. Там есть imul ...,COS. Возможно, имеет смысл держать его в регистре (хотя это сильно не поможет). Я не пользовал MMX, может, там есть и умножение ? Вообще ты вычисляешь во внтуреннем цикле фактически координаты линии. Может, проще строить линию, определив крайние точки ? Линии можно строить по известным алгоритмам... |
|
|
Дата: Июл 11, 2004 01:08:06 Shurka Ты бы хоть написал что вокруг чего вращать надо. Асм это конечно круто, но хотелось бы для начало по-русски :) Кватернионы не покатят? |
|
|
Дата: Июл 11, 2004 10:11:27 Shurka Раз уж тут про косинусы заговорили) Есть такая штука от Intel, называется AMath. Вот цитата из ридми: What Is AM Library? =================== Ever missed a sine or arctangent instruction among Intel Streaming SIMD Extensions? Ever wished there were a way to calculate logarithm or exponent in about a dozen cycles? Here is a new release of Approximate Math Library (AM Library) -- a set of fast routines to calculate math functions using Intel(R) Streaming SIMD Extensions (SSE) and Streaming SIMD Extensions 2 (SSE2). The Library offers trigonometric, reverse trigonometric, logarithmic, and exponential functions for packed and scalar arguments. The processing speed is many times faster than that of x87 instructions and even of table lookups. The accuracy of AM Library routines can be adequate for many applications. It is comparable with that of reciprocal SSE instructions, and is hundreds times better than what is achievable with lookup tables. The AM Library is provided along with the full source code and a usage sample. Так вот, я не вникал насколько тяжело эту штуку будет подружить с Celeronом, но ежели нужно -- скажи, кину. Хотя либа должна быть где-то в дебрях developer.intel.com |
|
|
Дата: Июл 11, 2004 10:28:31 _DEN_ вращать надо поверхность(DirectDraw) вокруг центарльной точки. А что такое кватернионы? |
|
|
Дата: Июл 11, 2004 10:32:15 flankerx Может быть я не совсем тебя понял, но внутри цилков я не использую тригонометрчиеских функций. Поэтмоу их скорость не критична. |
|
|
Дата: Июл 11, 2004 19:58:04 Shurka Всмысле крутить экран вокруг нормали к плоскости экрана монитора? :-) На сколько я понял тебя софтварная реализация интересует? Может быть радикалы помогут? Кватернионы это гиперкомплексные числа 4-го измерения. Довольно удобны для расчетов поворотов. Удобнее по сравнению с матрицами. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.054 |