Eso es realmente una locura. No sé qué podría causarlo y no pude reproducir en mi propia copia Matlab R2010a durante varias ejecuciones, invocadas por nombre o vía F5.
Aquí hay una idea para depurarlo.
Al usar tic/toc dentro de un script o función, use el formulario "tstart = tic" que captura el resultado. Esto hace que sea seguro usar llamadas anidadas de tic/toc (por ejemplo, dentro de las funciones llamadas), y le permite atenerse a múltiples tiempos de inicio y transcurridos y examinarlos mediante programación.
t0 = tic;
% ... do some work ...
te = toc(t0); % "te" for "time elapsed"
Se pueden utilizar diferentes sufijos "t0_label" para cada una de las tic y toc devoluciones, o almacenarlos en un vector, por lo que ellos conservar hasta el final de su script.
t0_uninit = tic;
% ... do the uninitialized-array test ...
te_uninit = toc(t0_uninit);
t0_prealloc = tic;
% ... test the preallocated array ...
te_prealloc = toc(t0_prealloc);
Haga que la secuencia de comandos entre en el depurador cuando encuentre uno de los valores grandes.
if any([te_uninit te_prealloc te_vector] > 5)
keyboard
end
Luego puede examinar el espacio de trabajo y los valores de retorno de tic, lo que podría proporcionar algunas pistas.
EDIT: También podría intentar probar tic() por sí solo para ver si hay algo extraño con el reloj del sistema, o lo que sea TIC/TOC está llamando. El valor de retorno de tic() parece una marca de tiempo nativa de algún tipo. Intente llamarlo muchas veces seguidas y comparando los valores subsiguientes. Si alguna vez retrocede, eso sería sorprendente.
function test_tic
t0 = tic;
for i = 1:1000000
t1 = tic;
if t1 <= t0
fprintf('tic went backwards: %s to %s\n', num2str(t0), num2str(t1));
end
t0 = t1;
end
En Matlab R2010b (preliminar), que tiene matemáticas Int64, puede reproducir un resultado similar por parte toc ridícula jiggering la referencia tic valor para que sea "en el futuro". Parece un efecto de rollover int, como lo sugiere gary comtois.
>> t0 = tic; toc(t0+999999)
Elapsed time is 6148914691.236258 seconds.
Esto sugiere que si había alguna fluctuación en el temporizador que toc estaban usando, es posible obtener antivuelco si ocurre mientras estás sincronización operaciones muy cortos. (Supongo que toc() internamente hace algo así como tic() para obtener un valor para comparar la entrada.) Aumentar el número de iteraciones podría hacer que el efecto desaparezca porque una pequeña cantidad de fluctuación del reloj sería menos significativa como parte de un período más largo. períodos tic/toc. También explicaría por qué no ve esto en su prueba no preasignada, que lleva más tiempo.
ACTUALIZACIÓN: Pude reproducir este comportamiento. Estaba trabajando en un código no relacionado y descubrí que en una computadora de escritorio en particular con un modelo de CPU que no habíamos utilizado anteriormente, un quad core Core 2 Q8400 2.66 GHz, tic estaba dando resultados inexactos. Parece un error dependiente del sistema en tic/toc.
En esta máquina en particular, tic/toc regularmente informará valores extrañamente altos como el suyo.
>> for i = 1:50000; t0 = tic; te = toc(t0); if te > 1; fprintf('elapsed: %.9f\n', te); end; end
elapsed: 6934787980.471930500
elapsed: 6934787980.471931500
elapsed: 6934787980.471899000
>> for i = 1:50000; t0 = tic; te = toc(t0); if te > 1; fprintf('elapsed: %.9f\n', te); end; end
>> for i = 1:50000; t0 = tic; te = toc(t0); if te > 1; fprintf('elapsed: %.9f\n', te); end; end
elapsed: 6934787980.471928600
elapsed: 6934787980.471913300
>>
Va más allá de eso. En esta máquina, tic/toc informará regularmente el tiempo transcurrido para las operaciones, especialmente para tareas de bajo uso de la CPU.
>> t0 = tic; c0 = clock; pause(4); toc(t0); fprintf('Wall time is %.6f seconds.\n', etime(clock, c0));
Elapsed time is 0.183467 seconds.
Wall time is 4.000000 seconds.
lo que parece que este es un error en TIC/TOC que se relaciona con determinados modelos de CPU (o algo más específico para la configuración del sistema). He informado el error a MathWorks.
Esto significa que tic/toc probablemente le da resultados inexactos, incluso cuando no produce esos números increíblemente grandes. Como solución alternativa, en esta máquina, use etime() y solo dedique tiempo a trozos de trabajo más largos para compensar la menor resolución de etime. Podría envolverlo en sus propias funciones tic/toc que usan la prueba i = 1: 50000 para detectar cuándo se rompe el tic en la máquina actual, usar tic/toc normalmente y hacer que lo adviertan y vuelvan a utilizar etime() en sistemas rotos-tic.
ACTUALIZACIÓN 2012-03-28: He visto esto en la naturaleza por un tiempo, y es muy probable debido a una interacción con el temporizador de alta resolución y escalado de velocidad de la CPU, y (en Windows) QueryPerformanceCounter, como se describe aquí: http://support.microsoft.com/kb/895980/. No es un error en tic/toc, el problema está en las características del sistema operativo que tic/toc está llamando. Establecer un parámetro de arranque puede solucionarlo.
¿Podría ser cuando el valor del reloj, almacenado en toc, se da la vuelta? – gary
¿Qué versión de MATLAB estás usando? – gnovice
@gnovice - 7.10.0.499 (2010a) – Rook