Multithreading 如何将多线程函数结果存储到一个数组或向量

Multithreading 如何将多线程函数结果存储到一个数组或向量,multithreading,c++11,Multithreading,C++11,我制作了一个程序,可以在两个指定的边界内找到素数。制作起来很容易,而且效果很好。问题是速度太慢了。为了解决这个问题,我决定使用多个线程来分割任务。如果边界差大于等于100,则将创建100个线程。每个线程将调用函数PrimeIterator,并将边界差的工作量除以100。例如:如果我将开始边界输入为100,将结束边界输入为1100,那么100个线程中的每个线程将计算10个数字,以确定它们是否为素数 显然,每个线程将同时运行。我希望所有确定的素数都存储在一个数组中。为此,我尝试为每个线程创建100个

我制作了一个程序,可以在两个指定的边界内找到素数。制作起来很容易,而且效果很好。问题是速度太慢了。为了解决这个问题,我决定使用多个线程来分割任务。如果边界差大于等于100,则将创建100个线程。每个线程将调用函数
PrimeIterator
,并将边界差的工作量除以100。例如:如果我将开始边界输入为100,将结束边界输入为1100,那么100个线程中的每个线程将计算10个数字,以确定它们是否为素数

显然,每个线程将同时运行。我希望所有确定的素数都存储在一个数组中。为此,我尝试为每个线程创建100个不同的向量(使用for循环)来存储数字,这样就不会有一个全局数组被所有100个线程使用。假设(从未使其工作),在存储之后,它们将被排序并存储到一个数组/向量中,在那里它们可以显示给用户

问题是:如何存储调用同一函数PrimeIterator的所有100个线程的值

注意:将工作负载平均分配给每个线程的逻辑没有完成,也不起作用。那部分我不需要任何帮助

代码:

include "stdafx.h"
#include "iostream"
#include <thread>
#include <cmath>
#include <vector>

using namespace std;

bool PrimeNumberChecker(int x);
void PrimeIterator(int x, int y);



static const int num_threads = 99;

int main()
{
    int val1, dividend, divisor, threadIterator1, threadIterator2;
    int x, y, i;
    thread t[num_threads];

    cout << "Enter Start Boundary: ";
    cin >> x;
    cout << "\nEnter End Boundary: ";
    cin >> y;

    val1 = (y - x) / 100;
    dividend = floor(val1);
    divisor = fmod(y-x, 100);


    if (y-x >= 100) 
    {
        thread t2(PrimeIterator, x, divisor);

        for (i = 1; i <= num_threads; i++)
        {
            threadIterator1 = dividend * i;
            threadIterator2 = dividend * (i + 1);

            t[i] = thread(PrimeIterator, threadIterator1, threadIterator2, i);
        }

        t2.join();
        for (int i = 0; i < num_threads; ++i) {
            t[i].join();
        }
    }



    system("pause");
    return 0;
}

bool PrimeNumberChecker(int x) 
{
    int i, t;

    for (i = 2; i <= x ; i++) 
    {

        for (t = 2; t <= x; t++)
        {
            if (i*t == x)
            {
                return false;
            }

        }

    }
    return true;
}


void PrimeIterator(int startBoundary, int endBoundary)
{
    int i;

        for (i = startBoundary; i <= endBoundary; i++)
        {
            if (PrimeNumberChecker(i))
            {


            }
        }


}
包括“stdafx.h”
#包括“iostream”
#包括
#包括
#包括
使用名称空间std;
布尔素数切克(整数x);
void素数迭代器(intx,inty);
静态常量int num_线程=99;
int main()
{
int val1,被除数,除数,threadIterator1,threadIterator2;
int x,y,i;
线程t[num_threads];
cout>x;
cout>y;
val1=(y-x)/100;
股息=下限(val1);
除数=fmod(y-x,100);
如果(y-x>=100)
{
线程t2(素数迭代器,x,除数);

对于(i=1;i如果您真的希望优化代码找到素数,那么请查找一些关于这方面的文章。搜索快速素数算法将得到许多结果

但是,您的代码有几个主要问题:

  • 由于代码主要受CPU限制,如果您创建的线程数超过处理器的核心数,则不会获得任何性能提升。如果您希望为CPU编写快速代码,您可以执行一些测试,如1、2、4或8个线程,并比较性能
  • 你尝试了太多的可能性。例如,如果你想知道101是否为素数,你只需要尝试2到10之间的
    i
    (包括2到10)(101的平方根向下舍入为10)
  • 你也可以很容易地跳过所有偶数,除了2,这是很容易检查的
  • 对大数进行模运算而不是测试
    t
    也应该要快得多。如果您想测试10以下的数,您的代码可能还可以
假设您正在搜索101是否为素数。使用您的代码,您将为
i
循环尝试101-2+1值,为
t
循环尝试大约一半的值,因此它将进行大约5000次测试

现在,假设optimize
i
只循环测试3、5、7和9(一旦你测试了你的数字是奇数),你已经将测试数量减少到了大约200个。这快了25倍,而且还远远不是最佳的


如果您测试的数字约为10000,则使用这两种优化的代码速度将快100倍以上。

如果您确实希望优化后的代码能够找到素数,请查找一些关于素数的文章。搜索快速素数算法将得到许多结果

但是,您的代码有几个主要问题:

  • 由于代码主要受CPU限制,如果您创建的线程数超过处理器的核心数,则不会获得任何性能提升。如果您希望为CPU编写快速代码,您可以执行一些测试,如1、2、4或8个线程,并比较性能
  • 你尝试了太多的可能性。例如,如果你想知道101是否为素数,你只需要尝试2到10之间的
    i
    (包括2到10)(101的平方根向下舍入为10)
  • 你也可以很容易地跳过所有偶数,除了2,这是很容易检查的
  • 对大数进行模运算而不是测试
    t
    也应该要快得多。如果您想测试10以下的数,您的代码可能还可以
假设您正在搜索101是否为素数。使用您的代码,您将为
i
循环尝试101-2+1值,为
t
循环尝试大约一半的值,因此它将进行大约5000次测试

现在,假设optimize
i
只循环测试3、5、7和9(一旦你测试了你的数字是奇数),你已经将测试数量减少到了大约200个。这快了25倍,而且还远远不是最佳的


如果你测试一个10000左右的数字,那么这2个优化的代码就快了100倍。

好的。你应该提到OpenMP:比所有的市长C++编译器支持的线程要容易得多。@ Pal1970对这些指针非常感谢!我认为主线程可以创造更小的更多。“工作线程”。好的。你应该提到OpenMP:比所有的市长C++编译器支持的线程要容易得多。@ Prim1970感谢这些指针!我认为主线程可以创建更小的“工作者线程”。