C++ C++;,如何在非并行任务中通过线程精确划分cpu工作

C++ C++;,如何在非并行任务中通过线程精确划分cpu工作,c++,multithreading,parallel-processing,C++,Multithreading,Parallel Processing,我想做一个素数计算器 程序将n除以每一个小于n的数。如果除法的余数仅为0的1倍(不包括1的除法),则该数字为素数。在程序开始时,要求用户键入一个数字,然后对每个数字进行计算,直到用户键入的数字 这是一个非并行任务,但我试图通过在内核之间划分数字来实现并行 这是在线程之间划分任务的代码段 void division(int number) { int ithread[8]{}; int sum = 0; cout << "Preparation..";

我想做一个素数计算器

程序将n除以每一个小于n的数。如果除法的余数仅为0的1倍(不包括1的除法),则该数字为素数。在程序开始时,要求用户键入一个数字,然后对每个数字进行计算,直到用户键入的数字

这是一个非并行任务,但我试图通过在内核之间划分数字来实现并行

这是在线程之间划分任务的代码段

void division(int number)
{
    int ithread[8]{};
    int sum = 0;
    cout << "Preparation..";
    /* Calculating how many numbers the checker will check. */
    ithread[0] = (int)number*0.125;
    ithread[1] = (int)number*0.125;
    ithread[2] = (int)number*0.125;
    ithread[3] = (int)number*0.125;
    ithread[4] = (int)number*0.125;
    ithread[5] = (int)number*0.125;
    ithread[6] = (int)number*0.125;
    ithread[7] = (int)number*0.125;

    /* Calculating from what number the checkers will begin.
    the first thread will begin from 0. the second checker will begin from the last number the first                            
    did. The third will begin from the sum of numbers checked by first and second and so on. */

    thread thread0(noprint, ithread[0], 0);
    sum += ithread[0];
    thread thread1(noprint, ithread[1], sum);
    sum += ithread[1];
    thread thread2(noprint, ithread[2], sum);
    sum += ithread[2];
    thread thread3(noprint, ithread[3], sum);
    sum += ithread[3];
    thread thread4(noprint, ithread[4], sum);
    sum += ithread[4];
    thread thread5(noprint, ithread[5], sum);
    sum += ithread[5];
    thread thread6(noprint, ithread[6], sum);
    sum += ithread[6];
    thread thread7(noprint, ithread[7], sum);
    thread0.join();
    cout << "thread1";
    thread1.join();
    cout << "thread2";
    thread2.join();
    cout << "thread3";
    thread3.join();
    cout << "thread4";
    thread4.join();
    cout << "thread5";
    thread5.join();
    cout << "thread6";
    thread6.join();
    cout << "thread7";
    thread7.join();
    cout << "thread8";

}
无效分割(整数)
{
int-ithread[8]{};
整数和=0;

无法在此网站上查看pthreads库


查看有关老板-工人模型的部分


这个线程模型可能非常适用于您的问题。

不要试图在一开始就把工作一分为二-线程是不可预测的。您无法控制操作系统在每个核心上的其他负载,以及您认为“相等”的负载根据代码的不同,工作负载可能会有很大的不同。相反,将工作负载分成大量更小的单元,并让每个线程在上一个单元完成后从下一个单元开始,直到所有单元完成

至于让用户指定线程数,你到底坚持什么?向用户要求一个数字,然后生成那么多线程似乎很简单。但是,大多数多线程程序都不这样做。最好查询系统可以运行多少线程(例如),然后使用它

另外,另一方面,检查素数的算法效率极低-可能这只是一个学习练习,而不是认真的代码?如果不是,您可能想看看其他算法-检查素数是一个经过充分研究的问题


但是,杰宾特利,如果我像你说的那样,手术将不会成功 是的,应用程序将使用不同的线程,但是 另一种方式,这有什么意义?对我来说不是一样吗 只用一条线?我是个新手,如果我错了,很抱歉。-亚历克斯

不,它仍然是并行的。您有一个跟踪最后分配的工作块的共享数据结构。这可以像包含最后检查的数字的
int
一样简单。当线程用完工作时,它开始处理接下来的N个数字,并将
int
增加适当的数量。Wh在这样做的时候,你需要小心,多个线程不能同时使用共享变量——C++中有各种各样的机制或者第三方库来管理这个。 伪代码:

lastChecked = 1
thread 1: lock lastChecked
thread 1: lastChecked = 10
thread 1: unlock lastChecked
thread 1: start working on numbers 1 to 10
thread 2: lock lastChecked
thread 2: lastChecked = 20
thread 2: unlock lastChecked
thread 2: start working on numbers 11 to 20
thread 1: complete work
thread 1: lock lastChecked
thread 1 lastChecked = 30
thread 1: unlock lastChecked
thread 1: start working on numbers 21 to 30
// etc.

注意:您应该仔细选择每个工作单元的大小。如果将其设置得太大,则会返回到原始问题,其中某些线程可能会比其他线程完成得晚很多。如果将其设置得太小,则会增加线程在其他线程使用共享状态时等待太多时间以访问共享状态的风险,并且您会浪费时间d在分配每个工作负载的开销上花费的时间太多。

检查素数的一种方法使用三个阶段。初始阶段仅使用一个线程生成一个素数数组,最大值为p。下一阶段使用数组检查最大值为p^2(p平方)的素数,在线程之间平均划分从p到p^2的范围。每个线程创建自己的新找到的素数数组。线程完成后,数组连接到原始数组,并将p设置为找到的最高素数。然后重复该循环,直到p^2>=n。然后,最后阶段使用数组检查n是素数。

MMh.我不认为分割工作是编程的问题,我认为它更多地与数学有关…无论如何,我要看看那里,谢谢。谢谢你的提示,但我认为这个问题与数学有关,而不是与编程有关。我想他不想知道如何创建线程,而是想知道如何确定间隔t每个线程处理的工作负载是否相等?但是JBentley,如果我像你说的那样,操作将不会同时进行。是的,应用程序将使用不同的线程,但以另一种方式,这有什么意义?只使用一个线程不是一样吗?如果我错了,我很抱歉。谢谢你的提示。是的,这很简单学习练习。我14岁了,我想不出更好的算法;)