Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Veamos qué es lo más óptimo...

Iniciado por Drácula, 01 de Enero de 1970, 01:00:00 AM

« anterior - próximo »

Drácula

                                Método 1:

Para cada esfera:

Procesar los vértices multiplicando por las matrices(esto lo hago para que se utilice la CPU)
Mandar el resultado a la tarjeta

Método 2:

Para cada esfera:

Anexar a una lista todos los vértices, también procesando los vértices haciendo uso intensivo de la CPU.

Y una vez terminado el proceso para cada esfera...

Para cada textura:

Mandar ese paquete enorme a la tarjeta.


Pensad que aunque procese vértices esto NO ES SIGNIFICATIVO, porque la GPU tiene que volverlos a procesar para hallar sus valores XYZRHW.

En el 2º método, es EVIDENTE que la CPU está a la espera todo el tiempo, porque sólo espera a que la tarjeta le permita seguir. Y los resultados son claros. Si no tengo GPU no me afecta para nada, pero si tengo, no la utilizo en paralelo, porque está siempre esperando...                                
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

_Grey

                                Creo.... creo que ya se el por que de esto, en el Metodo2...
Tienes un vertexbuffer por cada esfera??haces Lock() y UnLock() por todas los vertexbuffer de las esferas??
y lo haces en cada cuadro de animacion??

Lo digo por que no es la manera adecuada de trabajar con los vertexbuffer... ni con los indexbuffers, pero como no se como funciona tu motor, igual no es eso.....

Pero diria que posiblemente sea por eso, o no?                                

Emotion

                                Bueno Dracula, tal y como te prometi, he aqui los resultados con mi equipo de casa. te remito ahora los detalles de la configuracion:

Equipo
CPU - PentiumIII 600MHz
RAM - 256 MB SDRAM PC133 (2x128)
GPU - NVIDIA TNT2 M64/M64Pro 32MB AGP2X
SO  - Windows98 SE
API - OpenGL 1.3.0/DirectX 8.1

Optimizaciones
PreBuffer 4MB IRQ11 (VGA+TVTuner+ACPI)
Cache Virtual 512MB Fija separada del Sistema

Version de los Drivers
Detonator4 28.32 OFICIAL

Bueno, pues las pruebas han arrojado un total de 26.33 FPS en el metodo 1 y un total de 29.33 FPS usando el metodo 2, con lo que, como ya te comente con el equipo de oficina, no hay demasiada diferencia, si bien aqui obtengo una tasa de animacion plenamente interactiva... muy buen trabajo :sonriendo:

Ah, casi se me olvidaba... el escritorio lo tengo a 1024x768 en 16bits y el formato de pixel escogido por windows ha sido 16bits en formato RGB 5:6:5

Espero que estos datos te puedan ayudar en algo
                               
G3: Get the Power!

Ithaqua

                                Drácula, no entiendo, transformas por software todos los vértices en ambos métodos?

                               
thaqua^Stravaganza
http://ithaqua.stravaganza.org

Drácula

                                Transformo para hacer algo con la CPU. Fijaos en esto:

Método 1:

CPU Trabajando(Aquí funcionamos en paralelo)
Volcar datos a la tarjeta
continuar con otra esfera

Método 2:

Para cada esfera:
CPU Trabajando

Al terminar:
Para cada textura:
Renderizar el Vertexbuffer(sin usar Locks!!)
continuar con otra textura


Para mi es evidente, que el método 2 hace que la CPU esté esperando porque primero tiene que esperar a que la tarjeta le diga que está libre antes de poder seguir trabajando. Sin embargo en el método 1, después de lanzar los triángulos a la tarjeta, hace muchas más cosas y cuando vuelve a mandar los siguientes, la tarjeta todavía no ha terminado, pero la espera es mínima.

                               
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

Ithaqua

                                No es paralelizable eso. Para renderizar una esfera ésta primero debe ser transformada. O eso al menos entiendo según la explicación del proceso que haces.
Es como aquello de paralelizar instrucciones de procesador que actúan en escritura+lectura sobre un mismo registro.

mov eax, 10
mov ebx, eax

No pueden ejecutarse en paralelo porque para que se pueda mover a ebx el contenido del registro eax, primero debe de terminar de ejecutarse la anterior instrucción.

mov eax, 10
mov ebx, 10

Sí que podría ejecutarse en paralelo.

Prueba a hacer algo parecido.

                               
thaqua^Stravaganza
http://ithaqua.stravaganza.org

mallrat

                                Buenas! sin saber exactamente que operaciones (y sobre todo, como y donde bloqueas los vertex buffers) es dificil saber donde se produce el cuello de botella en cada metodo. Por ejemplo, quiza no estes usando DISCARD al hacer lock de los vertex buffers "gordos" del segundo método, y si lo usas puede que de un subidon porque entonces el proceso de transformar todas las esferas si se podría hacer en paralelo con el de pintarlas. Si ya hacias el "d3dlock_discard" entonces habría que seguir analizando uno y otro metodo, de todas formas piensa que lo mas rapido con diferencia es cargar las mallas en memoria de video y usar al 100% el T&L y dejar la cpu para la ia

[ Este Mensaje fue editado por: mallrat el 2002-05-04 19:04 ]                                

Ithaqua

                                Me respondo a mi mismo :sonriendo:

Lo que he dicho no es cierto, sí que podrían ejecutarse en paralelo si el driver guarda las operaciones a realizar en una cola interna, lo que suele hacer en la mayoría de los casos.

Mea culpa.

                               
thaqua^Stravaganza
http://ithaqua.stravaganza.org

Emotion

                                Para mallrat:

Pero si no mal recuerdo, Dracula dijo que no tenia GPU, con lo cual el T&L no lo hace por hardware... a no ser que estes hablando de T&L por software

Para Ithaqua:

Es posible paralelizar los comandos al driver? es decir, podria implementar Multithreading para el render con OpenGL??? yo habia oido que no se podia hacer... o sea que si soporta multiples instancias de render usando una cola?? jurrll... me he quedado mas liado que la pata de un romano... explicate :sonriendo:
                               
G3: Get the Power!

mallrat

                                Emotion:
pues... si, me referia a T&L por HW, aunque él no tenga, supongo que estará haciendo el motor pensando en los que si tenemos (joé que para eso me he gastao la pasta!) :ojo:
en cualquier caso el futuro (bueno, prácticamente el presente) es T&L por HW, así que mejor hacerlo pensando en ello, no?

supongo que Ithaqua se refiere al hecho de que el driver (por lo menos el de DX) va guardando las operaciones que le mandas hacer en una especie de "cola de comandos" por ejemplo si le dices que pinte una cosa de 1000 triangulos, va a volver al instante, el driver realmente lo hará en cuanto termine con la operación anterior.
(este paralelismo se puede estropear de muchas maneras, y eso es lo que hay que tratar de evitar para sacar el maximo de fps)

[ Este Mensaje fue editado por: mallrat el 2002-05-04 21:59 ]                                

Ithaqua

                                Sí, me refiero al buffer interno de comandos del driver. El propósito es precisamente ese, poder paralelizar al máximo CPU/tarjeta.
De hecho puede darse el caso de que estés operando a nivel de CPU en el frame n, y los resultados en pantalla ser los del n-1, quedando por ejecutarse en la cola todos los comandos de render de un frame entero.
En OpenGL puedes forzar el vaciado de ese buffer (= ejecución de todos los comandos pendientes) con glFlush() o glFinish(). La diferencia es que el último no retorna hasta que se haya ejecutado la última instrucción pendiente.

                               
thaqua^Stravaganza
http://ithaqua.stravaganza.org

Drácula

                                Creo que hablais de unas cosas que realmente NO son fundamentales. A fin de cuentas, tengamos cachés parelelas o cualquier cosa que querais llamarle, el problema es localizar DONDE debe esperar el proceso. Y es en ses DONDE, cuando debes intentar realizar el paralelismo.

Al más bajo nivel, una tarjeta funciona así:

Esperar si la tarjeta ha terminado de procesar el último paquete
Mandar otro paquete

El cuello está en el trozo de espera. Por ello, si mandamos 2 paquetes seguidos, el 2º paquete tendrá que esperar a que el primero termine. Es evidente que se puede utilizar un sistema caché y tantas cosas que se dicen, pero recordemos que un caché provoca movimiento de memoria, y seguro que será memoria de sistema, por lo que yo PREFIERO QUE NO HAYA CACHE DE ESTE TIPO.

Y ya está, por que la tarjeta POR MUY BUENA QUE SEA, no procesará los triángulos en paralelo, y como primero tiene que terminar uno para que empiece el otro, no debemos mandar paquetes seguidos porque desperdiciamos CPU, como se ha visto claramente en los tests que vosotros mismos habeis realizado.

De todas formas, me gustaría que alguno de los que decís que esto no es así, hicierais lo mismo que yo:un pequeño test. Quizás yo esté equivocado, pero creo que ahora ya no basta la teoría, necesitamos demostraciones prácticas.

Un saludo a todos.                                
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

Ithaqua

                                Sigo sin ver cual es la diferencia exacta entre el primero y el segundo. ¿Puedes concretar un poco mas en qué hace cada método? ¿Ambos envían los mismos datos no?
Lo de que la CPU esté en espera, hoy día en la gran mayoría de los casos no es así. Las tarjetas actuales son devoradoras de polígonos, y en motores mal programados (= mayoría) suelen estar bostezando casi todo el tiempo. Lo que está en la espera es la tarjeta, no la CPU.
Lo de la cache que tu dices que no quieres, es precisamente lo que hace que tu tarjeta funcione en paralelo con la CPU si las cosas van bien. Es necesaria.

La diferencia de FPS en tu ejemplo puede deberse principalmente al modo en el que se envían los datos a la tarjeta. Es mucha geometría, y dado que ocupa mucho ancho de banda el método de envío es crítico.
Si en el segundo ejemplo se alcanzan muy pocos FPS, no tiene por qué significar que la CPU esta en espera. Si la tarjeta es capaz de llegar en el primer caso a 130fps, por qué iba a costarle tanto esfuerzo renderizar en el segundo caso lo mismo?
Si esta renderizando a la sexta parte de la velocidad del primer caso los mismos datos, algún problema debe haber en el envío, o mucho proceso esta haciendo la CPU.

Explícame un poco mas a fondo el proceso si puedes :sonriendo:

                               
thaqua^Stravaganza
http://ithaqua.stravaganza.org

mallrat

                                Drácula, nadie ha hablado de cachés de memoria, los drivers de DX lo que tienen es una cola de comandos enviados a la tarjeta, cuando tu le mandas el segundo paquete no espera a terminar con el primero, básicamente almacena la operación a realizar y vuelve. Algunas tarjetas tienen una cola de comandos bastante grande y pueden llegar a almacenar los comandos para pintar un frame entero (es decir, las llamadas a Draw*Primitive, los cambios de estado, etc) pero por ejemplo si le pides hacer un Lock (y no usas discard o nooverwrite) de algo que está en la cola, entonces si que hace esa espera que tu dices, y precisamente ese es un posible cuello de botella a evitar.


[ Este Mensaje fue editado por: mallrat el 2002-05-05 16:23 ]                                

mallrat

                                Drácula, pedias una prueba:

escenario de 7200 tris y 14000 vert. (aprox)
resolucion 800x600x32
fps: 282 (3.55 mseg)
tiempo de "render": 0.85 mseg.
tiempo de "present": 2.66 mseg

el tiempo de render es el tiempo gastado en llamadas a Draw(*)Primitive / SetTexture / etc.

el tiempo de "present" es lo que ha tardado la llamada a "Present()"

                               






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.