Diferencias en tiempo de ejecución entre modo embedded y modo tradicional

Pau Freixes pfreixes en milnou.net
Jue Mayo 29 23:23:31 CEST 2008


Buenas lista,

A raíz de uno de mis ultimos trabajos para la universidad con un software
muy parecido a lo que podría
ser mod_python, me he encontrado con un "problema" un tanto increible, a ver
si me pueden ayudar a entender que está pasando ? La situación es la
siguiente :

En una de las pruebas de rendimiento de el sotware, parecido a
apache+mod_python, que ejecuta processos batch escritos en python m'he
encontrado con la desagradable sorpresa que el mismo parograma exejutado en
consola es mucho mas lento.

Como muestra para corroborar esto he creado un programa llamado
md5challenge, que intenta calcular el numero máximo de llaves md5 en un
tiempo determinado. El programa es muy sencillo, es algo a esto :


def handler_alrm(signum, frame):
    global _signal
    global _nrdigest
    global _f


    _signal = True

def try_me():
    global _nrdigest
    global _f
    global _signal

    _f = open("/dev/urandom","r")
    buff = _f.read(_const_b)
    while _signal is not True:
        md5.md5(buff).hexdigest()
        _nrdigest = _nrdigest + 1

    if _f is not None :
        _f.close()

def main( req ):
    global _nrdigest


    signal.signal(signal.SIGALRM, handler_alrm)
    signal.alarm(req.input['time'])

    d1 = datetime.datetime.now()
    try_me()
    d2 = datetime.datetime.now()
    delta = d2 - d1
    print "Delta : %s:%s" % ( delta.seconds, delta.microseconds)

    req.output['count'] = _nrdigest

def handler_alrm(signum, frame):
    global _signal
    global _nrdigest
    global _f


    _signal = True

def try_me():
    global _nrdigest
    global _f
    global _signal

    _f = open("/dev/urandom","r")
    buff = _f.read(_const_b)
    while _signal is not True:
        md5.md5(buff).hexdigest()
        _nrdigest = _nrdigest + 1

    if _f is not None :
        _f.close()

def main( req ):
    global _nrdigest


    signal.signal(signal.SIGALRM, handler_alrm)
    signal.alarm(req.input['time'])

    d1 = datetime.datetime.now()
    try_me()
    d2 = datetime.datetime.now()
    delta = d2 - d1
    print "Delta : %s:%s" % ( delta.seconds, delta.microseconds)

    req.output['count'] = _nrdigest

Cuando el programa es ejecutado de forma tradicional con un "pytohn
md5challenge" crea de forma temporal un objecto Request y le añade un
conjunto de tipos, este request es que recibirá la funcion main. De la misma
forma cuando la ejecución es mediante el software similar a
apache+mod_python la función main es llamada des de un programa en C que ha
embebido Python. La llamada es algo similar a esto, y esta muy documentada
en la API de C de Python

                PyObject * pArgs;

                pArgs = PyTuple_New(1);
                PyTuple_SetItem(pArgs, 0, req);

                /* calling object */
                pvalue = PyObject_CallObject(pfunc, pArgs);
                if ( pvalue  )
                    fill_output(j, req, PyInt_AsLong(pvalue));

Lo cursioso del caso es que si intento calcular el numero máximo de llaves
md5 de una forma y en otra, en mi Pentium V Core duo me saca diferencias de
más del 10%.

Por ejemplo estos son dos ejecuciones del modelo "normal ",donde Delta es el
tiempo en minutos+segundos en expirar la alarma.

Delta : 10:499
Reached 986522 digests

Delta : 10:55
Reached 1007246 digests

Y esta debajo de el sistema embebido

Delta : 10:864
1253377

Delta : 10:642
1253377


No cabe duda que los numero son suficientemente dispares para creer que aquí
puede estar pasando alguna cosa. He probado de subir la lecutra del
dispositivo no bloqueante "/dev/urandom" fuera del bucle i intentar generar
el maximo de llaves con el mismo buffer, las diferencias són realmente
abismales.

normal

Delta : 10:49
Reached 2958537 digests

embebido

Delta : 10:56
Reached 5999019 digests

Mi pregunta es, como se justifica esto ?



-- 
Pau Freixes
Linux GNU/User
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes





Más información sobre la lista de distribución Python-es