Skip to content
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

使用算法count_if()的并行版本来统计vector中偶数的数量 永远都不值得,即使有1,000,000,000个元素 #39

Open
xunboo opened this issue Oct 4, 2023 · 3 comments

Comments

@xunboo
Copy link

xunboo commented Oct 4, 2023

似乎这个理论有问题,实际测试:

auto eval = [](auto fun)
    {
        const auto t1 = std::chrono::high_resolution_clock::now();
        const auto [name, result] = fun();
        const auto t2 = std::chrono::high_resolution_clock::now();
        const std::chrono::duration<double, std::milli> ms = t2 - t1;
        std::cout << std::setw(28) << std::left << name << "sum: "
            << result << "\t time: " << ms.count() << " ms\n";
    };
{

    eval([&v] { return std::pair{ "std::count_if (seq, long)",
        std::count_if(SEQ
        v.begin(), v.end(),
        [](int elem) {
            return elem % 2 == 0;
        }) };  });
    eval([&v] { return std::pair{ "std::count_if (par, long)",
        std::count_if(PAR
        v.begin(), v.end(),
        [](int elem) {
            return elem % 2 == 0;
        }) };  });
        
        
   VS2022 C++17  release编译运行结果     

std::count_if (seq, long) sum: 100,000,007 time: 51.5 ms
std::count_if (par, long) sum: 100,000,007 time: 13.3 ms

@MeouSker77
Copy link
Owner

我的理解是,从理论上讲vector可以直接把首尾迭代器相减算出元素数量,然后在实际开始计算之前就可以指定每个线程计算哪一部分元素,这样就只有最后求总和的时候需要把各个线程的结果加起来,其他时候各个线程之间完全不需要通信和同步,所以并行比串行快是有可能的。但如果是非随机访问迭代器,比如链表的迭代器,这时候无法事先知道总共有多少元素,就只能一个个遍历所有元素然后动态分给不同线程来计算,这时候不同线程之间就需要用原子操作来进行同步以确保不同线程不会重复计算同一个元素,如果每前进一个元素都要进行一次原子操作的话,那么原子操作的开销远大于判定一个数是不是 2 的倍数的开销,所以这种情况下不管有多少个元素,并行肯定比串行慢。

@0x8A63F77D
Copy link

我的经验是,在Linux,gcc 11,使用了TBB作为线程库的时候,当每个元素要处理的任务量太小的时候,TBB创建线程的开销会远大于计算的开销。MSVC这边可能有别的优化?

@caomengxuan666
Copy link

判断奇偶只需要对最后一位数操作就行了,这个操作数范围也是在10之内的,然而并行计算是需要额外开销的,至少有个线程消耗摆在这,即使是原子操作也是有性能损失。肯定比加一个小运算耗时大的多。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants