关于《C++并发编程实战》代码的问题

huangapple go评论66阅读模式
英文:

Question about "C++ Concurrency in Action" code

问题

  1. 作者为什么选择25作为min_per_thread?这只是一个任意的数字吗,还是有一定的考虑?

  2. 我不理解这段代码中的公式:

unsigned long const max_threads =
    (length + min_per_thread - 1) / min_per_thread;

为什么我们要使用这个公式来找到"最大线程数",以及我们需要它做什么?

我尝试搜索这段代码周围的类似问题,但没有找到任何相关信息。

英文:

I'm reading C++ Concurrency In Action and in page 32 (Chapter 2) there is this code.

template <typename Iterator, typename T>
struct accumulate_block
{
    void operator()(Iterator first, Iterator last, T &result)
    {
        result = std::accumulate(first, last, result);
    }
};
template <typename Iterator, typename T>
T parallel_accumulate(Iterator first, Iterator last, T init)
{
    unsigned long const length = std::distance(first, last);
    if (!length)
        return init;
    unsigned long const min_per_thread = 25;
    unsigned long const max_threads = (length + min_per_thread - 1) / min_per_thread;
    unsigned long const hardware_threads = std::thread::hardware_concurrency();
    unsigned long const num_threads = std::min(hardware_threads != 0 ? hardware_threads : 2, max_threads);
    unsigned long const block_size = length / num_threads;
    std::vector<T> results(num_threads);
    std::vector<std::thread> threads(num_threads - 1);
    Iterator block_start = first;
    for (unsigned long i = 0; i < (num_threads - 1); ++i)
    {
        Iterator block_end = block_start;
        std::advance(block_end, block_size);
        threads[i] = std::thread(accumulate_block<Iterator, T>(),
                                 block_end, std::ref(results[i]));
        block_start = block_end;
    }
 accumulate_block<Iterator,T(block_start,last,results[num_threads-1]); 
 
 for(auto& entry: threads)
     entry.join(); 
 return std::accumulate(results.begin(),results.end(),init);
}

I don't understand some things.

  1. Why did the author choose 25 as the min_per_thread? Is this just an arbitrary number or is there a thought behing it?
  2. I don't understand the formula in this piece of code:
unsigned long const max_threads=
 (length+min_per_thread-1)/min_per_thread; 

Why do we use this formula to find the "max threads" and what do we need it for?

I tried to search for other similar questions around this piece of code but found nothing.

答案1

得分: 3

为什么作者选择了25作为min_per_thread的值?这只是一个任意的数字,还是有一定考虑的?

数字25是一个任意的数值。你可以使用任何你喜欢的数值。

我不理解这段代码中的公式:

unsigned long const max_threads =
    (length + min_per_thread - 1) / min_per_thread;

当你将一个数,比如13length),除以4min_per_thread)时,由于整数运算,你会得到3。余数等于1,所以你只为三个范围[0, 3][4, 7][8, 11]提供了3个线程,但元素12没有分配到线程。你需要为余数提供一个线程。

你可以写成:

13 + (4 - 1) 等于 16,而 16 除以 4 将得到 4。现在,所有包含在余数范围内的范围都将有自己的线程。

例如,如果 length 等于 12,那么添加的值 min_per_thread - 1 不会影响所需的线程数量,在这种情况下仍然等于 3

总的来说,余数可以是范围 [0, min_per_thread - 1] 中的任何值。

特别地,如果 length 小于 min_per_thread,那么使用不带操作数 min_per_thread - 1 的表达式,max_threads 将等于 0,尽管在任何情况下都需要一个线程。

英文:

> Why did the author choose 25 as the min_per_thread? Is this just an
> arbitrary number or is there a thought behing it?

The number 25 is an arbitrary number. You may use any number as you like.

> I don't understand the formula in this piece of code:

unsigned long const max_threads=
 (length+min_per_thread-1)/min_per_thread; 

When you divide a number, for example 13 (length) by 4 (min_per_thread) you will get 3 due to the integer arithmetic. The remainder is equal to 1, so you provided only 3 threads for the three ranges [0, 3], [4,7] and [8, 11], but the element 12 is left without a thread. You need to provide a thread for the remainder.

You can write:

13 + ( 4 - 1 ) that is equal to 16, and 16 divided by 4 will yield 4. Now all ranges included in the range for the remainder will have their own thread.

If, for example, length is equal to 12 then the added value min_per_thread - 1 will not affect the required number of threads, equal to 3 in this case.

In general, the remainder can be any value in the range [0, min_per_thread - 1].

Particulary, if length is less than min_per_thread then to use the expression without the operand min_per_thread - 1 you will get that max_threads will be equal to 0, though one thread is required in any case.

huangapple
  • 本文由 发表于 2023年7月12日 20:45:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76670712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定