Skip to content

“当前环境支持并发线程数”中并行求和代码存在问题 #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Mq-b opened this issue Oct 16, 2024 · 1 comment
Closed
Labels
announcement 公告 bug Something isn't working

Comments

@Mq-b
Copy link
Owner

Mq-b commented Oct 16, 2024

位置

template<typename ForwardIt>
auto sum(ForwardIt first, ForwardIt last){
    using value_type = std::iter_value_t<ForwardIt>;
    std::size_t num_threads = std::thread::hardware_concurrency();
    std::ptrdiff_t distance = std::distance(first, last);

    if(distance > 1024000){
        // 计算每个线程处理的元素数量
        std::size_t chunk_size = distance / num_threads;
        std::size_t remainder = distance % num_threads;

        // 存储每个线程的结果
        std::vector<value_type> results { num_threads };

        // 存储关联线程的线程对象
        std::vector<std::thread> threads;

        // 创建并启动线程
        auto start = first;
        for (std::size_t i = 0; i < num_threads; ++i) {
            auto end = std::next(start, chunk_size + (i < remainder ? 1 : 0));
            threads.emplace_back([start, end, &results, i] {
                results[i] = std::accumulate(start, end, value_type{});
            });
            start = end; // 开始迭代器不断向前
        }

        // 等待所有线程执行完毕
        for (auto& thread : threads)
            thread.join();

        // 汇总线程的计算结果
        value_type total_sum = std::accumulate(results.begin(), results.end(), value_type{});
        return total_sum;
    }

    value_type total_sum = std::accumulate(first, last, value_type{});
    return total_sum;
}

此处使用花括号初始化可能存在问题:

 // 存储每个线程的结果
std::vector<value_type> results { num_threads };

在面对一些类型,重载决议无法选择到我们想要的那个构造函数,也就是:

constexpr explicit vector( size_type count, const Allocator& alloc = Allocator() );

而是 std::initializer_list 的那个版本,用来创建初始化成员。

具体参见:Mq-b/Loser-HomeWork#207

可以简单的改为小括号初始化。

不过教案中提供的 godbolt 代码测试链接,的确是使用小括号初始化。

@Mq-b Mq-b added bug Something isn't working announcement 公告 labels Oct 16, 2024
@Mq-b
Copy link
Owner Author

Mq-b commented Oct 16, 2024

futurestd::packaged_task 一节中同样存在我们的并行求和的代码,不过也没有使用 {} 初始化。

// 存储每个线程要执行的任务
std::vector<std::packaged_task<value_type()>>tasks;
// 和每一个任务进行关联的 future 用于获取返回值
std::vector<std::future<value_type>>futures(num_threads);

这似乎只是个意外。

后续更新调整一下这些地方的格式对齐,有些丑陋了。

@Mq-b Mq-b closed this as completed in a83aeec Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
announcement 公告 bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant