Это действительно безумие. Не знаю, что могло вызвать это, и не смог воспроизвести на моем собственном экземпляре Matlab R2010a несколько прогонов, вызванных по имени или через F5.
Вот идея отладки.
При использовании tic / toc внутри скрипта или функции используйте форму "tstart = tic", которая захватывает выходные данные. Это позволяет безопасно использовать вложенные вызовы tic / toc (например, внутри вызываемых функций) и позволяет удерживать несколько начальных и истекших периодов времени и исследовать их программно.
t0 = tic;
% ... do some work ...
te = toc(t0); % "te" for "time elapsed"
Вы можете использовать разные суффиксы "t0_label" для каждого из возвращений tic и toc или сохранять их в векторе, чтобы сохранить их до конца вашего сценария.
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);
Попросите скрипт взломать отладчик, когда он найдет одно из больших значений.
if any([te_uninit te_prealloc te_vector] > 5)
keyboard
end
Затем вы можете проверить рабочее пространство и возвращаемые значения из tic, что может дать некоторые подсказки.
РЕДАКТИРОВАТЬ: Вы также можете попробовать протестировать tic () самостоятельно, чтобы увидеть, есть ли что-то странное с вашими системными часами или что-то вызываемое tic / toc. Возвращаемое значение tic () выглядит как родная временная метка. Попробуйте вызвать его много раз подряд и сравнить последующие значения. Если это когда-нибудь пойдет вспять, это было бы удивительно.
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
На Matlab R2010b (предварительной), который имеет int64 математику, вы можете воспроизвести подобный нелепый результат ТОС по перетасовывают ссылочный крестики значение, чтобы быть «в будущем». Похоже, что эффект от ролловера, как предложил Гэри Комтуа.
>> t0 = tic; toc(t0+999999)
Elapsed time is 6148914691.236258 seconds.
Это говорит о том, что если в таймере, который использовал toc, было какое-то дрожание, вы можете получить опрокидывание, если оно произойдет, пока вы выполняете очень короткие операции. (Я предполагаю, что toc () внутренне делает что-то вроде tic (), чтобы получить значение для сравнения входных данных.) Увеличение количества итераций может привести к тому, что эффект исчезнет, потому что небольшое количество дрожания тактового импульса будет менее значительным как часть более длинного периоды tic / toc. Также объяснил бы, почему вы не видите этого в вашем нераспределенном тесте, который занимает больше времени.
ОБНОВЛЕНИЕ: я смог воспроизвести это поведение. Я работал над некоторым несвязанным кодом и обнаружил, что на одном конкретном десктопе с моделью процессора, которую мы не использовали ранее, четырехъядерным процессором Core 2 Q8400 с частотой 2,66 ГГц, тик давал неточные результаты. Выглядит как системно-зависимая ошибка в tic / toc.
На этой конкретной машине Tic / Toc будет регулярно сообщать о странно высоких значениях, как у вас.
>> 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
>>
Это проходит мимо этого. На этом компьютере tic / toc будет регулярно занижать затраченное время для операций, особенно для задач с низкой загрузкой ЦП.
>> 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.
Таким образом, похоже, что это ошибка в Tic / Toc, связанная с определенными моделями процессоров (или что-то еще, специфичное для конфигурации системы). Я сообщил об ошибке в MathWorks.
Это означает, что Tic / Toc, вероятно, дает вам неточные результаты, даже если он не производит эти безумно большие цифры. В качестве обходного пути, на этом компьютере используйте вместо этого etime (), и время только для более длинных частей работы компенсирует более низкое разрешение etime. Вы можете обернуть его в свои собственные функции tick / tock, которые используют тест for i = 1: 50000, чтобы определить, когда на текущем компьютере нарушен тик, как обычно использовать tic / toc, и предупредить их и вернуться к использованию etime () на сломанных системах.
ОБНОВЛЕНИЕ 2012-03-28: Я уже давно это видел в дикой природе, и, скорее всего, это связано с взаимодействием с таймером производительности высокого разрешения ЦП и масштабированием скорости, а также (в Windows) QueryPerformanceCounter, как здесь описано: http://support.microsoft.com/kb/895980/. Это не ошибка в tic / toc, проблема в функциях ОС, которые вызывает tic / toc. Установка параметра загрузки может обойти это.