Использование std :: chrono :: stable_clock для тестирования кода в потоке / асинхронности - PullRequest
0 голосов
/ 26 августа 2018

Предположим, у меня есть много вычислений, которые я хочу выполнить (и оценить время процессора) в нескольких потоках.В качестве игрушечного примера:

#include <chrono>
#include <future>
#include <iostream>
#include <vector>


using unit_t = std::chrono::nanoseconds;

unit_t::rep expensive_computation() {
    auto start = std::chrono::steady_clock::now();
    // Something time-consuming here...
    auto end = std::chrono::steady_clock::now();

    auto duration = std::chrono::duration_cast<unit_t>(end - start).count();

    return duration;
}

int main() {
    std::vector<std::future<unit_t::rep>> computations;

    for (int i = 0; i < 100; i++) {
        computations.push_back(std::async(expensive_computation));
    }

    for (size_t i = 0; i < computations.size(); i++) {
        auto duration = computations[i].get();
        std::cout << "#" << i << " took " << duration << "ns" << std::endl;
    }
}

Я обеспокоен тем, что, поскольку steady_clock является монотонным в потоках базовые такты для каждого процесса, а не для потока (если запланирован какой-либо поток,такты для всех потоков).Это будет означать, что если бы поток спал, steady_clock все равно работал бы для него, и это время было бы неправильно включено в duration для этого потока.Правильно ли мое подозрение?Или steady_clock ставит галочку только для процессорного времени потока внутри потока?

Другими словами, является ли этот подход безопасным способом независимо рассчитать время большого количества вычислений (таким образом, что время, потраченное ЦП на один поток, не повлияет наduration из другой темы)?Или мне нужно выделять отдельные процессы для каждого вычисления, чтобы сделать отметку steady_clock only, когда вычисление выполняется / запланировано?

edit: Я также признаю, что ускорение большего количества потоковчем ядра могут быть неэффективным подходом к этой проблеме (хотя я не особо беспокоюсь о пропускной способности вычислений; более того, я просто хочу, чтобы все они как группа завершили в самое быстрое время).Я подозреваю, что на практике мне нужно было бы поддерживать ограниченный список потоков с небольшими константами в полете (скажем, ограниченный числом ядер) и только начинать новые вычисления, когда ядро ​​становится доступным.Но это не должно влиять на сроки, о которых я забочусь выше;это должно влиять только на время настенных часов.

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Это означало бы, что если бы поток спал, то для этого все равно оставалось бы устойчивое время, а это время было бы неправильно включено в длительность этого потока.

Это не будетбыть неправильно , хотя, как указано в стандарте для класса std::chrono::steady_clock, он измеряет физическое время, а не время ЦП или любое другое время.Смотрите здесь под [time.clock.steady] :

Объекты класса steady_­clock представляют часы, для которых значения time_­point никогда не уменьшаются как физические Опережает время и для которого значения time_­point увеличиваются с постоянной скоростью относительно реального времени ...

Тем не менее, ваш код выглядит хорошо, так как он даст вам время, измеренное для каждогонить беги.Есть ли причина, по которой вы хотите измерять процессорное время здесь?Если так, то дайте мне знать в комментариях.

0 голосов
/ 26 августа 2018

Стандарт определяет, что steady_clock модель физическое время (в отличие от процессорного времени).

с [time.clock.steady]:

Объекты класса steady_clock представляют часы, для которых значения time_point никогда не уменьшаются по мере продвижения физического времени и для которых значения time_point продвигаются с постоянной скоростью относительно реального времени.То есть часы не могут быть отрегулированы.

При этом, насколько хорошо реализация моделирует физическое время, является проблемой QOI.Тем не менее, ваш код выглядит хорошо для меня.

Если ваши эксперименты окажутся неудовлетворительными, клиенты <chrono> могут также создавать свои собственные пользовательские часы, которые будут иметь статус первого класса в библиотеке <chrono>.

...