Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-使用并发线程查找要添加到目标值的三个数字_C_Multithreading - Fatal编程技术网

C-使用并发线程查找要添加到目标值的三个数字

C-使用并发线程查找要添加到目标值的三个数字,c,multithreading,C,Multithreading,我正在做一个C项目,我必须从一个文本文件中读取10000行任意整数到一个数组中,然后找到三个加在目标值上的整数。然后,它打印出查找值所需的时间 例如,如果我的目标是233,那么这三个数字可能是81/102/50。也就是说,如果在文本文件中找到这些数字 我创建了三个嵌套for循环来查找10000个整数的每个组合。我花了大约5分钟,没有使用任何线程 我的项目涉及到实现并发线程,我很难找到一种更快的方法来查找数字 我曾想过将数组一分为二,其中一个线程找到0-5000和另一个5000-10000的组合,

我正在做一个C项目,我必须从一个文本文件中读取10000行任意整数到一个数组中,然后找到三个加在目标值上的整数。然后,它打印出查找值所需的时间

例如,如果我的目标是233,那么这三个数字可能是81/102/50。也就是说,如果在文本文件中找到这些数字

我创建了三个嵌套for循环来查找10000个整数的每个组合。我花了大约5分钟,没有使用任何线程

我的项目涉及到实现并发线程,我很难找到一种更快的方法来查找数字


我曾想过将数组一分为二,其中一个线程找到0-5000和另一个5000-10000的组合,但我意识到这不起作用,因为这三个数字可能在其中的任何一半。有什么想法吗?

有没有消极的价值观?您能否记录输入过程中遇到的最大值和最小值?(答:是的,这很容易做到。如果外部循环识别出两个无法相加到目标值的值,则可以使用该选项来消除内部循环。)

假设你有N个数字。然后,您可以决定在3个线程之间分配工作负载,以便(例如,从稀薄的空气中提取部分):

  • 线程1将处理索引0到N/5的外部循环
  • 线程2将为索引N/5+1到N/3执行外循环;及
  • 线程3将处理索引N/3+1到N的外部循环
中间循环将从外部循环索引加上一开始,如果有解决方案,内部循环将从中间索引加上一开始

<> P>非对称分区的原因是,第一个线程将在中间和内部循环中检查更多的值,而不是其他线程。事实上,我认为我没有充分地扭曲工作负载,
5
应该是一个更大的数字,3也应该更大,以此类推。如果你有更多的线程,计算会变得更复杂。您希望大致平衡每个线程的工作负载

如果将每个线程的外循环范围的分数指定为F1、F2、F3,则:

  • 螺纹1可用于C1=(N/F1)•(N-1)•(N-2)试验
  • 螺纹2可用于C2=(N/F2)•(N-N/F1-1)•(N-N/F1-2)试验
  • 螺纹3可用于C3=(N/F3)•(N-N/F1-N/F2-1)•(N-N/F1-N/F2-2)试验

你想要C1吗≈ C2≈ C3。m线程的泛化是相当清楚的;解决办法并非如此。您可以更改术语以使用范围的乘法分数,或者为线程1指定[L1..U1],为线程2指定[L2..U2],为线程3指定[L3..U3],前提是L2=U1+1、L3=U2+1和[L1..U3]覆盖整个范围N,等等。

首先对数组进行排序。然后,可以使用两个嵌套循环和一个二进制搜索,而不是三个嵌套循环。两个嵌套循环查找两个数字的每一个和。得到两个数字的和后,第三个数字必须等于目标值减去该和。因此,您可以进行二进制搜索以确定数组中是否存在第三个数字

新算法的速度估计如下。三个嵌套循环计算
10000,选择3个
和,即1670亿个和。这大约是每秒5亿个总数(假设您的运行时间为5分钟)

两个嵌套循环计算
10000,选择2
部分和。那是5000万部分和。对于这些部分和中的每一个,代码都需要执行二进制搜索,这最多需要进行
ceil(log_2(10000))=14次比较。因此,比较的总数是7亿

结果是用7亿次比较替换1670亿次。假设比较比求和更昂贵,那么即使没有并发线程,运行时间也大约为4秒

要添加并发性,只需将阵列除以您拥有的处理器内核数。(这里需要注意的是,如果线程多于内核,那么线程就不会真正并发运行。)每个线程的外部循环只使用数组的一部分。线程的内部循环扫描整个数组以计算部分和。然后线程进行二进制搜索,查看数组中是否存在第三个数字


例如,如果您有一个4核处理器,那么每个线程都有一个使用1/4阵列的外部循环。这将使运行速度提高四倍,从而将运行时间减少到1秒左右。

我们也可以通过以下方式使用多线程:

int save_num[3][8]; //To give a different cache line
omp_set_num_threads(3); Set number of threads as 3 
#pragma omp parallel for
for(int i = 0; i< 10000; i++){
 int local_sum = file[i];
 int thread = omp_get_thread_num();
 save_num[thread][1]=local_sum;
#pragma omp critical
 if(save_num[0][1] + save_num[1][1] + save_num[2][1] ==233) {
  break;
 }
}
int save_num[3][8]//指定不同的缓存线
omp_设置_数量_线程(3);将线程数设置为3
#pragma-omp并行
对于(int i=0;i<10000;i++){
int local_sum=文件[i];
int thread=omp_get_thread_num();
save_num[thread][1]=本地_和;
#pragma-omp-critical
if(save_num[0][1]+save_num[1][1]+save_num[2][1]==233){
打破
}
}
我还没有测试过这段代码。尽管逻辑将保持不变。这将在三个线程中运行它,只进入临界部分一次,并在
save_num
变量中保存三个数字时检查条件是否为真