Skip to content

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

Closed
@Mq-b

Description

@Mq-b

位置

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 代码测试链接,的确是使用小括号初始化。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions