#include <mpi.h> #include <omp.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define TOTAL_POINTS 1000000000 // 点数设为 1e9 // 主函数 int main(int argc, char *argv[]) { int rank, size; // 当前进程编号和总进程数 double local_pi = 0.0; // 局部计算的 pi 值 double global_pi = 0.0; // 最终全局汇总后的 pi 值 long long num_local_points; // 每个进程负责的点数 long long inside_count = 0; // 内部点的数量(每进程) // 初始化 MPI MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取当前进程 ID MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取总的进程数量 // 根据进程数分配任务量 num_local_points = TOTAL_POINTS / size + (TOTAL_POINTS % size > rank ? 1 : 0); // 设置随机种子(保证每次运行生成不同序列) srand(time(NULL) ^ rank); // 开始计时 double start_time = omp_get_wtime(); // 使用 OpenMP 并行化处理本地任务 #pragma omp parallel for reduction(+:inside_count) for (long long i = 0; i < num_local_points; ++i) { double x = rand() / (double)RAND_MAX; // 随机生成 [0, 1] 区间的 x 坐标 double y = rand() / (double)RAND_MAX; // 随机生成 [0, 1] 区间的 y 坐标 if (x * x + y * y <= 1.0) { // 判断是否位于单位圆内 inside_count++; } } // 计算局部 pi 值 local_pi = 4.0 * inside_count / num_local_points; // 将所有进程的结果汇聚到主进程(rank=0) MPI_Reduce(&local_pi, &global_pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); // 停止计时 double end_time = omp_get_wtime(); // 只有主进程输出最终结果 if (rank == 0) { global_pi /= size; // 求平均值得到最终的 PI 近似值 printf("Estimate of PI with Monte Carlo Method: %.6f\n", global_pi); printf("Time Taken: %.4f seconds\n", end_time - start_time); } // 清理 MPI 环境 MPI_Finalize(); return 0; }设置线程数为4
时间: 2025-06-26 08:00:17 浏览: 17
在这段代码中,您提到“设置线程数为4”。目前该代码通过 `#pragma omp parallel for` 实现了 OpenMP 并行化,默认会使用系统允许的所有可用线程。为了明确地限制线程数为 4,可以添加以下步骤:
---
### 修改部分
在主函数开始处(初始化 MPI 后),插入如下代码:
```c
int thread_count = 4; // 设置最大线程数为 4
omp_set_num_threads(thread_count); // 显式设定 OpenMP 的线程数量
```
完整修改后的代码片段如下所示:
```c
#include <mpi.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TOTAL_POINTS 1000000000 // 点数设为 1e9
// 主函数
int main(int argc, char *argv[]) {
int rank, size; // 当前进程编号和总进程数
double local_pi = 0.0; // 局部计算的 pi 值
double global_pi = 0.0; // 最终全局汇总后的 pi 值
long long num_local_points; // 每个进程负责的点数
long long inside_count = 0; // 内部点的数量(每进程)
// 初始化 MPI
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取当前进程 ID
MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取总的进程数量
// 设定 OpenMP 的线程数为 4
int thread_count = 4;
omp_set_num_threads(thread_count);
// 根据进程数分配任务量
num_local_points = TOTAL_POINTS / size + (TOTAL_POINTS % size > rank ? 1 : 0);
// 设置随机种子(保证每次运行生成不同序列)
srand(time(NULL) ^ rank);
// 开始计时
double start_time = omp_get_wtime();
// 使用 OpenMP 并行化处理本地任务
#pragma omp parallel for reduction(+:inside_count)
for (long long i = 0; i < num_local_points; ++i) {
double x = rand() / (double)RAND_MAX; // 随机生成 [0, 1] 区间的 x 坐标
double y = rand() / (double)RAND_MAX; // 随机生成 [0, 1] 区间的 y 坐标
if (x * x + y * y <= 1.0) { // 判断是否位于单位圆内
inside_count++;
}
}
// 计算局部 pi 值
local_pi = 4.0 * inside_count / num_local_points;
// 将所有进程的结果汇聚到主进程(rank=0)
MPI_Reduce(&local_pi, &global_pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
// 停止计时
double end_time = omp_get_wtime();
// 只有主进程输出最终结果
if (rank == 0) {
global_pi /= size; // 求平均值得到最终的 PI 近似值
printf("Estimate of PI with Monte Carlo Method: %.6f\n", global_pi);
printf("Time Taken: %.4f seconds\n", end_time - start_time);
}
// 清理 MPI 环境
MPI_Finalize();
return 0;
}
```
---
### 解释改动
1. **`omp_set_num_threads(thread_count)`**
- 此函数显式设置了 OpenMP 中使用的线程数目。
- 默认情况下,OpenMP 会选择 CPU 上的最大核心数作为线程数;通过这一步我们可以手动控制线程数量。
2. **影响范围**
- 调用 `omp_set_num_threads` 影响的是后续所有的 OpenMP 并行区域,除非再次调用该函数更改数值。
---
### 输出示例
假设我们以 4 个线程运行程序,则可能会看到如下输出:
```
Estimate of PI with Monte Carlo Method: 3.141592
Time Taken: 2.5678 seconds
```
请注意,由于涉及到随机性以及硬件性能的不同,实际运行时间可能有所变化。
---
阅读全文
相关推荐















