Autor Tema: Complicando para simplificar  (Leído 16352 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Gonzalo_BlackHawk

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 519
Re: Complicando para simplificar
« Respuesta #30 en: 28 de Mayo de 2008, 00:21:17 »
Hola Palitroquez. Un gusto como siempre encontrar opiniones contigo.

Citar
no entiendo porque puntero es long ¿? Gonzalo el tamaño del puntero es independiente del tipo de datos que manejes.

Obviamente que es asi, estuve investigando bastante y al parecer tenia equivocado mis conceptos acerca de como CCS maneja los punteros. Paso a contar mi experiencia. Anteriormente y tal como se ve en el programa yo tomo el puntero como un tipo de datos de 2 bytes simplemente porque en el 18F2525 los registros se identifican con una dirección de 12 bits (desde el registro 0x000 hasta el 0xFFF) y con una variable int me quedaba corto.

Lo que no me cerraba era que cuando incrementaba el puntero  (y por lo tanto la dirección) saltaba dos registros por vez, pareceria ser que cada dirección en la memoria de datos contiene 2 bytes, pero estuve leyendo el datasheet medio rapidito y descarte esa hipotesis. Como no encontraba explicación como pueden darse cuenta en el programa, lo que hago es completar con '1' dos bytes consecutivos con cada pasada del bucle, por eso es que hago a *P = 0xFFFF; y asi coloco un parche a la situación. Como emparchar las cosas no es lo que mas me gusta hacer segui investigando.

Lo que yo pensaba (en forma equivocada) que cuando uno declara un puntero el tipo de datos que le asigna al mismo no esta realmente indicando el rango de direcciones a las que puede apuntar (Como uno puede llegar a suponer, me he fijado en el mapa de la memoria y P siempre se define en 2 bytes, sin importar el tipo de dato que le coloquemos) sino que indica el tamaño del segmento de memoria a la que señala el puntero. Definiendolo con un tipo de datos int el puntero cubre un solo registro que es la forma convencional de direccional la memoria, defiendolo en cambio con un tipo de datos long el puntero apunta de a dos registros, lo cual nos permitiria facilitar ciertas tareas como por ejemplo direccionar matrices con elementos de 16 bits de una manera muy sencilla. Puede extrapolarse este pensamiento al tipo de datos int32 y float, me he tomado el trabajo de probarlos. En CCS los punteros a bits no estan permitidos por lo tanto asignar un tipo de datos short a un puntero dara como resultado el correspondiente error al tratar de compilar el programa. Obviamente esto es un artilugio que realiza CCS para un direccionamiento indirecto mas amplio de la memoria, como muchas cosas la ayuda de CCS no indica nada sobre esto.

Otra cosita, aqui hay un error:

Código: [Seleccionar]
for(A=0;A<= Espacio;A++){
deberia colocarse:

Código: [Seleccionar]
for(A=0;A<Espacio;A++){
Si el tamaño de la matriz es de 4096 elementos, o sea 512 bytes, en el primer caso el bucle completará un byte de más porque A incrementará desde 0 a 512, o sea 513 veces. Por lo tanto el segundo bucle es el correcto.

Saludos a todos.
"Siempre piensa si el jugo vale la exprimida..."

"La muerte esta tan segura de vencer que nos da toda una vida de ventaja."

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Complicando para simplificar
« Respuesta #31 en: 28 de Mayo de 2008, 10:19:48 »
Muy buena la investigacion !!!, medio que no entendi nada, yo por suerte trabajo con micros lineales y mas ortogonales, y este tipo de cosas no me pasan.
Saludos !

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Complicando para simplificar
« Respuesta #32 en: 28 de Mayo de 2008, 16:15:32 »
Manolo:

a lo que yo llamo factor de multiplicación es lo que se usa en asm para hacer retardos ciclicos por software.

un ejemplo bien explicado lo tienes en http://micropic.wordpress.com/2007/02/09/retardos-por-software/



tomando en cuenta la primera rutina, tenemos que la línea goto CICLO tiene un factor de multiplicación de 2,porque tomará 2 ciclos de reloj por cada decremento de CONT.

Si continuas viendo los ejemplos posteriores, verás que a medida que se agregan registros anidados, ese factor aumenta y de allí se puede calcular con presición el tiempo consumido.

en el ejemplo anterior se usa a favor, en lo que refiere a este hilo está en contra y es perjudicial para nosotros. Por ello tratamos de cambiar las lineas que escribimos en c, para ver como lo traduce el compilador.

bueno, mas o menos es la relación que hago respecto al listado de los ejemplos que puso Gonzalo.

Lo que si tengo claro es que al manejar punteros o memset, el compilador usará direccionamiento indirecto, ahora bien, lo que uno tiene que analizar es como el compilador le hace las preguntas a INDF,POSTINCx,FSRx y para ello memset demostró ser el que lo hacía en menor tiempo.



Gonzalo:
Ante todo, cualquier ejemplo es válido siempre que cumpla su cometido, como en ccs no se puede manejar punteros a nivel de bits (al menos no se como y no he averiguado), entonces una forma corta que ví, fué trabajando por bytes. Una Matriz[32][128] -> 32x128=4096bits / 8bits = 512Bytes contiguos. Es mas rapido trabajar con int8 que con int16 (*)

*Con un pic con registros de 16bits, otro gallo cantaría

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Complicando para simplificar
« Respuesta #33 en: 28 de Mayo de 2008, 17:40:03 »

Gonzalo:
Ante todo, cualquier ejemplo es válido siempre que cumpla su cometido, como en ccs no se puede manejar punteros a nivel de bits (al menos no se como y no he averiguado), entonces una forma corta que ví, fué trabajando por bytes. Una Matriz[32][128] -> 32x128=4096bits / 8bits = 512Bytes contiguos. Es mas rapido trabajar con int8 que con int16 (*)

*Con un pic con registros de 16bits, otro gallo cantaría



Pali, hace más de un año platicamos aquí sobre como lograr apuntar variables de 1 bit...

Alternativa a arreglos de 1 bit
http://www.todopic.com.ar/foros/index.php?topic=15810.msg101438#msg101438

Tú estabas ahí,  :D

Desconectado Gonzalo_BlackHawk

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 519
Re: Complicando para simplificar
« Respuesta #34 en: 29 de Mayo de 2008, 01:03:54 »
Hola a todos.

Es mas rapido trabajar con int8 que con int16 (*)

Difiero contigo Pedro, en este caso trabajar con int16 para el llenado de la matriz es más rapido que utilizando int8. Y aun mejor, trabajar con int32 es todavia más rápido y dado que ocupamos la misma cantidad de memoria en los 3 casos, un 13 % del 18F2525 para ser más exactos, una mayor demanda de RAM no es un factor limitante para no trabajar apuntando a 2 registros o 4 (para el caso de int32) al mismo tiempo.
Obviamente, antes de tirar semejante refutación (y mas ha alguien con tu reputación Pedro) y no quedar en verguenza me he tomado el trabajo de comprobar que mi comentario realmente es válido. A continuación presento como de costumbre las ventanas de mplab que exponen tanto el código como el tiempo que demoro en ejecutarse el llenado de la matriz de 4096 elementos con punteros apuntando a 1, 2 y 4 registros a la vez, en ese orden.



Este es el caso expuesto por Palitroquez y como ya sabemos da casi 2 milisegundos. Ahora veamos cuando llenamos de a dos registros simultaneamente:



Vemos que el tiempo que demora en ejecutar todo es un poco mas de un milisegundo, fijense que la variable [A] ya no se incrementa 512 veces sino 256, por eso divido por dos el tamaño de la matriz. Veamos si utilizo un llenado de 4 registros simultaneamente:



Observen que el tiempo que tarda en llenar la matriz es de tan solo 647 microsegundos!!!!!. Es casi tan bajo como el tiempo obtenido por memset. Aqui tal como pueden deducir, el bucle de llenado solo se realiza 128 veces.

De estos tres casos se pueden sacar conclusiones interesantes. Primero, y tal como lo ha dicho Palitroquez, implementar un bucle origina demoras y cuanto mas ciclos debe realizar el bucle mas tarda en ejecutarse obviamente. Por eso cuantos mas registros llenamos a la vez menos cantidad de veces tenemos que realizar el bucle y por lo tanto menos tiempo demoramos.

Ahora bien, no es tan sencilla la cuestión, pues aunque para la matriz del ejemplo trabajar con un puntero en int8, int 16 o int32 nos supone solo un cambio de definicion del tipo de datos, no todas las matrices con las que trabajemos tendran un tamaño tan "adecuado" por decirlo de algun modo (Una matriz de 512 bytes es una ganga pues es multiplo de 1, 2 y 4 bytes) y por lo tanto si intentamos trabajamos con int32 en algunos casos nos encontraremos que nos faltan completar registros o bien que nos pasamos de dirección. Lo mismo puede ocurrir con int16 y una matriz, por ejemplo, que ocupa un numero de registros impares. La aplicación de estos metodos dependen mucho del tipo de dato que contiene la matriz y del tamaño de la misma. Por lo tanto yo creo que aqui el metodo con memset se lleva todos los premios y que los otros metodos son aplicables cuando el tiempo no es un factor crítico o bien vienen a titulo informativo.

Ahora me voy a dormir, veo punteros por todos lados. :D

Saludos desde Argentina.
"Siempre piensa si el jugo vale la exprimida..."

"La muerte esta tan segura de vencer que nos da toda una vida de ventaja."

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Complicando para simplificar
« Respuesta #35 en: 02 de Junio de 2008, 16:27:41 »
Ciertamente Gonzalo, Te doy la razón. Cambiando el tipo de datos a 16-32bits, aumenta la velocidad.

Cuando mencioné:

Citar
Es mas rapido trabajar con int8 que con int16 (*)

me basaba en la hecho de que, si tenemos un dato > 1 byte y trabajando con un pic cuyo bus de datos es de 8 bits, entonces el contador de programas tiene que hacer 2 operaciones en cada dato para completar su procesamiento (por ej: un long, sería 2 operaciones de 1 byte, un int32 serian 4 operaciones).

Obviamente el compilador de manera inteligente, juega con los registros de 8 bits para tardar menos en cada bucle. También cuenta otro hecho de que dado este ejemplo donde se puede tratar la matriz con los 3 tipos de datos e igual funciona y a medida que el tipo de dato es mayor, el número de iteraciones es mucho menor (con 32 bits son 128 repeticiones en comparación con int8 que son 512 veces)

Citar
...y mas ha alguien con tu reputación Pedro y no quedar en verguenza me he tomado el trabajo de comprobar que mi comentario realmente es válido.

jaja ¿cuál reputación?  :D, para nada. Si tu tienes un argumento válido; perfecto, entonces estas en el derecho de corregirme a mi o a cualquiera que tenga una idea/duda. De esto se trata los foros, de aclarar o corregir ideas.

Realmente "estaba" seguro que cambiando de int8 a int16 iba a tardar mas, es mas, imprimí los 3 programas que simulaste, y los asm generados son similares,



Mig, no me acordaba ese hilo  :8}


La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Complicando para simplificar
« Respuesta #36 en: 08 de Octubre de 2008, 15:20:21 »
Para el que no lo sepa:

Cuando se quiere leer un pin de un puerto, se usa input(PIN_puerto)

bien, deben saber que existe otro BUILT-IN: input_state(PIN_puerto), éste puede llegar a ser mas conveniente porque consume menos lineas en asm. La Razón: la dice la ayuda del ccs, con input_state NO se cambia el TRIS

Código: [Seleccionar]
....................    delay_cycles(1);
003A:  NOP
....................    a=input_state(PIN_B0);
003B:  CLRF   3B       
003C:  BTFSC  06.0     
003D:  INCF   3B,F
....................    delay_cycles(1);
003E:  NOP
....................    a=input(PIN_B0);
003F:  BSF    03.5
0040:  BSF    06.0
0041:  BCF    03.5
0042:  CLRF   3B
0043:  BTFSC  06.0
0044:  INCF   3B,F
....................    delay_cycles(1);
0045:  NOP

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Complicando para simplificar
« Respuesta #37 en: 31 de Marzo de 2010, 09:14:17 »
Estaba optimizando un programa en CCS para que quepa en un PIC 16F727 porque ya anda a tope, y para mi sorpresa, un array de bytes ocupa menos si lo dimensiono a 16 que si lo dimensiono a 12.

Esto ocupa menos
Código: C
  1. unsigned int8 Parametros[16];

que esto:
Código: C
  1. unsigned int8 Parametros[12];

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Complicando para simplificar
« Respuesta #38 en: 31 de Marzo de 2010, 10:46:34 »
Manolo deja de lado el ron !!!!

Saludos !

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Complicando para simplificar
« Respuesta #39 en: 31 de Marzo de 2010, 11:56:59 »
Estaba optimizando un programa en CCS para que quepa en un PIC 16F727 porque ya anda a tope, y para mi sorpresa, un array de bytes ocupa menos si lo dimensiono a 16 que si lo dimensiono a 12.

Hola Manolo, por favor danos más detalles para entender porqué pasa eso.  :huh:

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Complicando para simplificar
« Respuesta #40 en: 31 de Marzo de 2010, 12:10:28 »
Lo juro, aún no he llegado al punto de saturación de ron.

En mi programa, en estas dos compilaciones, lo único que cambio es el dimensionamiento de un array de int8 como indiqué antes. Podéis comprobar cómo el consumo de RAM sube 4 bytes en la parte de la derecha, pero a cambio el programa se reduce en 113 bytes (134 bytes si contamos los fragmentos no usados).



Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Complicando para simplificar
« Respuesta #41 en: 31 de Marzo de 2010, 12:18:51 »
Vale, te creemos. Pero entonces habría que analizar el código fuente y su volcado ASM.  ;-)

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Complicando para simplificar
« Respuesta #42 en: 31 de Marzo de 2010, 13:28:06 »
 :shock: Este CCS y sus cositas!  :?
No contesto mensajes privados, las consultas en el foro

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Complicando para simplificar
« Respuesta #43 en: 31 de Marzo de 2010, 13:33:53 »
Yo te creo mano, me ha pasado infinidad de veces eso.

Si estan ante un 18F o superior, siempre pueden poner #OPT 11 para intentar optimizar un poquito mas el codigo.

Por otro lado, cuidado con ese stack worst case, te estas pasando de los 8 niveles maximo para ese PIC en algun caso...Se te va a resetar el micro por overflow del STACK...;)
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Complicando para simplificar
« Respuesta #44 en: 31 de Marzo de 2010, 13:39:00 »
No sé de qué va eso del stack, ¿cómo puedo optimizar mi código para que utilice un nivel menos?, ¿qué tipo de funciones lo llenan?


 

anything