Как перенести результат из std :: future в C ++ 11? - PullRequest
1 голос
/ 06 ноября 2019

Я хочу асинхронно обработать std::vector<int> в моей программе. Однако при извлечении объектов не используется семантика перемещения.

Я создал минимальный рабочий пример и прикрепил его ниже. Согласно cplusplus.com , семантика перемещения при копировании и построении векторов линейна по размеру объекта перемещения и постоянна по размеру объекта перемещения, если они совместно используют один и тот же распределитель(Я использую стандартную). В соответствии с cplusplus.com снова, при извлечении объекта из std::future<T>::get() и T не является ни void, ни ссылочным типом (что не так), он ведет себя как перемещение значения.

Я даже попытался использовать inputs[i].get(); вместо этого во втором цикле, в настоящее время в комментариях, и не назначать его ни для чего. Это все равно дает линейное увеличение времени.

std::vector<std::vector<int>> GenerateTestCases(int input_size, int number_inputs) {
    std::vector<std::vector<int>> cases(number_inputs);

    for (auto i = 0; i < number_inputs; i++) {
        std::vector<int> some_vector(input_size);
        cases[i] = std::move(some_vector);
    }

    return std::move(cases);
}

int main() {
    for (auto i = 0; i < 25; i++) {
        auto size = (int)pow(2, i);
        int iterations = 100;

        auto test_cases = GenerateTestCases(size, iterations);

        std::vector<std::future<std::vector<int>>> inputs(iterations);

        const auto start = std::chrono::high_resolution_clock::now();

        for (auto i = 0; i < test_cases.size(); i++) {
            std::promise<std::vector<int>> prom;
            prom.set_value(std::move(test_cases[i]));

            inputs[i] = std::move(prom.get_future());
        }

        const auto middle = std::chrono::high_resolution_clock::now();

        for (auto i = 0; i < test_cases.size(); i++) {
            //inputs[i].get();
            auto& result = (inputs[i]);
            auto value = std::move(result.get());
        }

        const auto end = std::chrono::high_resolution_clock::now();

        const auto elapsed_first = std::chrono::duration_cast<std::chrono::nanoseconds>
        (middle - start).count();

        const auto elapsed_second = std::chrono::duration_cast<std::chrono::nanoseconds>
        (end - middle).count();

        std::cout << "First: " << elapsed_first << std::endl;
        std::cout << "Second: " << elapsed_second << std::endl;
        std::cout << std::endl;
    }

    char c;
    std::cin >> c;
}

Я, однако, вижу линейное увеличение времени выполнения, когда я выполняю свой код выше, в диапазоне от

Первое:13440 нс: второй: 9919 нс

для наименьшего размера массивов до

Первый: 25919 нс Второй: 300147450 нс

для самого большого.

Я использую VS2019 на Win10 и компилирую для x64, если это из интереса.

1 Ответ

2 голосов
/ 06 ноября 2019

Стоимость времени, вероятно, связана с уничтожением вектора.


Я провел тест, и время не увеличивается, когда результаты сохраняются в другом векторе (т.е. предотвращают разрушение)

http://coliru.stacked -crooked.com / a / dc7792496a981de3


Хотя в исходном коде время действительно увеличивается

http://coliru.stacked -crooked.com / а / 66b96809fb35b3d2

...