commit
d4d23e4d5c
|
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
title: 2024-2025学年下学期期末
|
||||||
|
category:
|
||||||
|
- 软件工程学院
|
||||||
|
- 课程资料
|
||||||
|
tag:
|
||||||
|
- 试卷
|
||||||
|
author:
|
||||||
|
- タクヤマ
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2025春季学期并行程序设计期末考试试卷(回忆版)
|
||||||
|
|
||||||
|
### 选择题
|
||||||
|
|
||||||
|
选择题都较简单, 不做记录.
|
||||||
|
|
||||||
|
### 填空题
|
||||||
|
|
||||||
|
1. 均匀储存访问模型中, 处理器访问储存器的时间\_\_\_\_, 物理储存器被所有处理器\_\_\_\_, 每台处理器带\_\_\_\_缓存.
|
||||||
|
|
||||||
|
2. MPI的点到点通信模式包括:标准通信\_\_\_\_, \_\_\_\_, \_\_\_\_, \_\_\_\_.
|
||||||
|
|
||||||
|
3. 四种循环转换包括:循环交换, 循环分块, \_\_\_\_, \_\_\_\_.
|
||||||
|
|
||||||
|
4. MPI集合通信的三个主要功能是:通信, \_\_\_\_, \_\_\_\_.
|
||||||
|
|
||||||
|
### 简答题
|
||||||
|
|
||||||
|
1. 简述 OpenMP 的 Fork-Join 工作模式.
|
||||||
|
|
||||||
|
2. 分布式内存系统与共享内存系统的核心区别是什么?
|
||||||
|
|
||||||
|
3. MPI阻塞接收与非阻塞接收的区别是什么?
|
||||||
|
|
||||||
|
4. 临界区嵌套会导致什么问题? 如何解决?
|
||||||
|
|
||||||
|
5. 简述信号量(Semaphore)实现 Barrier 的方法.
|
||||||
|
|
||||||
|
### 编程题
|
||||||
|
|
||||||
|
1. 哲学家用餐问题, 如何用互斥锁与信号量解决哲学家用餐问题, 保证不会出现死锁和饥饿? (注:此题只需写伪代码, 不需要严格的参照接口定义)
|
||||||
|
|
||||||
|
2. 多个进程分别拥有私有的数组, 现在要计算各个进程中所有数组元素的平均值.
|
||||||
|
|
||||||
|
使用MPI_Allreduce实现函数void Global_average(double loc_arr[], int loc_n, MPI_Comm comm, double* global_avg), 先计算局部总和与元素总数, 再归约计算全局总和与总元素数, 最后算平均值, 运行结束后所有进程中的global_avg都应该储存相同的结果, 即全局平均值.
|
||||||
|
|
||||||
|
(其中loc_arr[]为每个进程拥有的局部数组, loc_n 为局部数组的大小, comm 为通讯器, global_avg 储存最终结果)
|
||||||
|
|
||||||
|
(注:本题下方提供了会用到的 MPI 函数定义以供查阅, 不需要特意背诵接口. 不过奇怪的是考试中唯独没有提供 MPI_Allreduce 的定义, 比较诡异)
|
||||||
|
|
@ -1,39 +1,33 @@
|
||||||
# 2025春季学期并行程序设计期末考试试卷(回忆版)
|
---
|
||||||
|
title: 并行程序设计
|
||||||
|
category:
|
||||||
|
- 软件工程学院
|
||||||
|
- 课程评价
|
||||||
|
tag:
|
||||||
|
- 课程
|
||||||
|
---
|
||||||
|
|
||||||
## 选择题
|
## 2024-2025学年下学期
|
||||||
|
|
||||||
选择题都较简单,不做记录。
|
### 试卷
|
||||||
|
|
||||||
## 填空题
|
- [2024-2025学年下学期期末试卷](./2024-2025学年下学期期末.md)
|
||||||
|
|
||||||
1.均匀储存访问模型中,处理器访问储存器的时间\_\_\_\_,物理储存器被所有处理器\_\_\_\_,每台处理器带\_\_\_\_缓存。
|
### 谷守珍
|
||||||
|
|
||||||
2.MPI的点到点通信模式包括:标准通信\_\_\_\_,\_\_\_\_,\_\_\_\_,\_\_\_\_。
|
#### 教学资源
|
||||||
|
|
||||||
3.四种循环转换包括:循环交换,循环分块,\_\_\_\_,\_\_\_\_。
|
- [2024-2025学年下学期课件](https://drive.vanillaaaa.org/SharedCourses/软件工程学院/并行程序设计/2024-2025学年下学期/课件)
|
||||||
|
- [2024-2025学年下学期作业](https://drive.vanillaaaa.org/SharedCourses/软件工程学院/并行程序设计/2024-2025学年下学期/作业)
|
||||||
|
|
||||||
4.MPI集合通信的三个主要功能是:通信,\_\_\_\_,\_\_\_\_。
|
## 推荐教材与参考资料
|
||||||
|
|
||||||
## 简答题
|
- [并行程序设计导论](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E5%AF%BC%E8%AE%BA.pdf?sign=v1EtFro7aKJbuG-4kyKAiV3dQf6kRNag6o1QPUNm2to=:0)
|
||||||
|
|
||||||
1.简述OpenMP的Fork-Join工作模式。
|
## 古早资料(不建议使用)
|
||||||
|
|
||||||
2.分布式内存系统与共享内存系统的核心区别是什么?
|
- [2008并行程序设计期末考试卷(missing-answer)](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%8F%A4%E6%97%A9%E8%B5%84%E6%96%99/2008%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E6%9C%9F%E6%9C%AB%E8%80%83%E8%AF%95%E5%8D%B7(missing-answer).pdf?sign=atGUDTJcLpJUcYobwRLrjWYCbgFwcGjcYAukksi6l5w=:0)
|
||||||
|
- [2011并行程序设计期末考试卷 - 参考答案](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%8F%A4%E6%97%A9%E8%B5%84%E6%96%99/2011%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E6%9C%9F%E6%9C%AB%E8%80%83%E8%AF%95%E5%8D%B7%20-%20%E5%8F%82%E8%80%83%E7%AD%94%E6%A1%88.pdf?sign=hgEFhYizXwUmhGWORgCfgGOIVV4MNUL8S3unBwIPt-Q=:0)
|
||||||
3.MPI阻塞接收与非阻塞接收的区别是什么?
|
- [参考解答-2009-2010第一学期并行程序设计期末考试卷](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%8F%A4%E6%97%A9%E8%B5%84%E6%96%99/%E5%8F%82%E8%80%83%E8%A7%A3%E7%AD%94%EF%BC%8D2009%EF%BC%8D2010%E7%AC%AC%E4%B8%80%E5%AD%A6%E6%9C%9F%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E6%9C%9F%E6%9C%AB%E8%80%83%E8%AF%95%E5%8D%B7.pdf?sign=ijnoA1gusQshYklKwB-dP2EnkW1VKyK59rfeykbSuLw=:0)
|
||||||
|
- [参考解答-2010并行程序设计期末考试卷](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%8F%A4%E6%97%A9%E8%B5%84%E6%96%99/%E5%8F%82%E8%80%83%E8%A7%A3%E7%AD%94%EF%BC%8D2010%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E6%9C%9F%E6%9C%AB%E8%80%83%E8%AF%95%E5%8D%B7.pdf?sign=JGuoMMfPVqe6PMA4wACP4gJMJmWuF2jRXHv_PYo7evY=:0)
|
||||||
4.临界区嵌套会导致什么问题?如何解决?
|
- [并行计算往年试题和划重点](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%8F%A4%E6%97%A9%E8%B5%84%E6%96%99/%E5%B9%B6%E8%A1%8C%E8%AE%A1%E7%AE%97%E5%BE%80%E5%B9%B4%E8%AF%95%E9%A2%98%E5%92%8C%E5%88%92%E9%87%8D%E7%82%B9.pdf?sign=eXhs12EbTxfjEHhV9gWZl3mWU7U51ltvtg3jh-9gVhk=:0)
|
||||||
|
|
||||||
5.简述信号量(Semaphore)实现Barrier的方法。
|
|
||||||
|
|
||||||
## 编程题
|
|
||||||
|
|
||||||
1.哲学家用餐问题,如何用互斥锁与信号量解决哲学家用餐问题,保证不会出现死锁和饥饿?(注:此题只需写伪代码,不需要严格的参照接口定义)
|
|
||||||
|
|
||||||
2.多个进程分别拥有私有的数组,现在要计算各个进程中所有数组元素的平均值。
|
|
||||||
|
|
||||||
使用MPI_Allreduce实现函数void Global_average(double loc_arr[], int loc_n, MPI_Comm comm, double* global_avg),先计算局部总和与元素总数,再归约计算全局总和与总元素数,最后算平均值,运行结束后所有进程中的global_avg都应该储存相同的结果,即全局平均值。
|
|
||||||
|
|
||||||
(其中loc_arr[]为每个进程拥有的局部数组,loc_n为局部数组的大小,comm为通讯器,global_avg储存最终结果)
|
|
||||||
|
|
||||||
(注:本题下方提供了会用到的MPI函数定义以供查阅,不需要特意背诵接口。不过奇怪的是考试中唯独没有提供MPI_Allreduce的定义,比较诡异)
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
Networked systems can be represented using graphs.
|
|
||||||
Tenants who use the systems in which their resources are
|
|
||||||
hosted need to check with the provider of the resources that
|
|
||||||
their resources are properly connected and that
|
|
||||||
their resources are properly separated from the resources of
|
|
||||||
other tenants. Since providers manage systems for
|
|
||||||
multiple tenants, a method to prove the connectivity and isolation
|
|
||||||
without revealing the network topology is required. As a solution,
|
|
||||||
an efficient zero-knowledge proof system of graph signatures
|
|
||||||
using a bilinear-map accumulator has been proposed, where the
|
|
||||||
verification time and the size of the proof data do not depend on
|
|
||||||
the number of graph vertexes and edges. However, this system
|
|
||||||
has two problems. First, since the proof does not include labels,
|
|
||||||
it is not possible to prove the connectivity considering network
|
|
||||||
bandwidth and cost. Second, since it assumes undirected graphs,
|
|
||||||
it cannot handle applications on directed graphs such as network
|
|
||||||
flows. In this study, we extend the previous system and propose
|
|
||||||
a zero-knowledge proof system of the connectivity for directed
|
|
||||||
graphs where each edge has labels. We implemented our system
|
|
||||||
on a PC using a pairng library and evaluate it by measuring the
|
|
||||||
processing times.
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
Networked systems can be represented using graphs.
|
|
||||||
Tenants who use the systems in which their resources are
|
|
||||||
hosted need to check with the provider of the resources that
|
|
||||||
their resources are properly connected and that
|
|
||||||
their resources are properly separated from the resources of
|
|
||||||
other tenants. Since providers manage systems for
|
|
||||||
multiple tenants, a method to prove the connectivity and isolation
|
|
||||||
without revealing the network topology is required. As a solution,
|
|
||||||
an efficient zero-knowledge proof system of graph signatures
|
|
||||||
using a bilinear-map accumulator has been proposed, where the
|
|
||||||
verification time and the size of the proof data do not depend on
|
|
||||||
the number of graph vertexes and edges. However, this system
|
|
||||||
has two problems. First, since the proof does not include labels,
|
|
||||||
it is not possible to prove the connectivity considering network
|
|
||||||
bandwidth and cost. Second, since it assumes undirected graphs,
|
|
||||||
it cannot handle applications on directed graphs such as network
|
|
||||||
flows. In this study, we extend the previous system and propose
|
|
||||||
a zero-knowledge proof system of the connectivity for directed
|
|
||||||
graphs where each edge has labels. We implemented our system
|
|
||||||
on a PC using a pairng library and evaluate it by measuring the
|
|
||||||
processing times.
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
Networked systems can be represented using graphs.
|
|
||||||
Tenants who use the systems in which their resources are
|
|
||||||
hosted need to check with the provider of the resources that
|
|
||||||
their resources are properly connected and that
|
|
||||||
their resources are properly separated from the resources of
|
|
||||||
other tenants. Since providers manage systems for
|
|
||||||
multiple tenants, a method to prove the connectivity and isolation
|
|
||||||
without revealing the network topology is required. As a solution,
|
|
||||||
an efficient zero-knowledge proof system of graph signatures
|
|
||||||
using a bilinear-map accumulator has been proposed, where the
|
|
||||||
verification time and the size of the proof data do not depend on
|
|
||||||
the number of graph vertexes and edges. However, this system
|
|
||||||
has two problems. First, since the proof does not include labels,
|
|
||||||
it is not possible to prove the connectivity considering network
|
|
||||||
bandwidth and cost. Second, since it assumes undirected graphs,
|
|
||||||
it cannot handle applications on directed graphs such as network
|
|
||||||
flows. In this study, we extend the previous system and propose
|
|
||||||
a zero-knowledge proof system of the connectivity for directed
|
|
||||||
graphs where each edge has labels. We implemented our system
|
|
||||||
on a PC using a pairng library and evaluate it by measuring the
|
|
||||||
processing times.
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
Networked systems can be represented using graphs.
|
|
||||||
Tenants who use the systems in which their resources are
|
|
||||||
hosted need to check with the provider of the resources that
|
|
||||||
their resources are properly connected and that
|
|
||||||
their resources are properly separated from the resources of
|
|
||||||
other tenants. Since providers manage systems for
|
|
||||||
multiple tenants, a method to prove the connectivity and isolation
|
|
||||||
without revealing the network topology is required. As a solution,
|
|
||||||
an efficient zero-knowledge proof system of graph signatures
|
|
||||||
using a bilinear-map accumulator has been proposed, where the
|
|
||||||
verification time and the size of the proof data do not depend on
|
|
||||||
the number of graph vertexes and edges. However, this system
|
|
||||||
has two problems. First, since the proof does not include labels,
|
|
||||||
it is not possible to prove the connectivity considering network
|
|
||||||
bandwidth and cost. Second, since it assumes undirected graphs,
|
|
||||||
it cannot handle applications on directed graphs such as network
|
|
||||||
flows. In this study, we extend the previous system and propose
|
|
||||||
a zero-knowledge proof system of the connectivity for directed
|
|
||||||
graphs where each edge has labels. We implemented our system
|
|
||||||
on a PC using a pairng library and evaluate it by measuring the
|
|
||||||
processing times.
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <queue>
|
|
||||||
#include <omp.h>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
std::queue<std::string> shared_queue;
|
|
||||||
int producers_done = 0;
|
|
||||||
omp_lock_t queue_lock;
|
|
||||||
omp_lock_t output_lock;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
void producer(int file_index, const char *filename)
|
|
||||||
{
|
|
||||||
std::ifstream file(filename);
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
#pragma omp critical
|
|
||||||
std::cerr << "Error opening file: " << filename << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string line;
|
|
||||||
while (std::getline(file, line))
|
|
||||||
{
|
|
||||||
omp_set_lock(&queue_lock);
|
|
||||||
shared_queue.push(line);
|
|
||||||
omp_unset_lock(&queue_lock);
|
|
||||||
}
|
|
||||||
omp_set_lock(&queue_lock);
|
|
||||||
producers_done++;
|
|
||||||
omp_unset_lock(&queue_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void consumer()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
std::string line;
|
|
||||||
bool should_exit = false;
|
|
||||||
|
|
||||||
omp_set_lock(&queue_lock);
|
|
||||||
if (!shared_queue.empty())
|
|
||||||
{
|
|
||||||
line = shared_queue.front();
|
|
||||||
shared_queue.pop();
|
|
||||||
omp_unset_lock(&queue_lock);
|
|
||||||
|
|
||||||
std::istringstream iss(line);
|
|
||||||
std::string word;
|
|
||||||
while (iss >> word)
|
|
||||||
{
|
|
||||||
omp_set_lock(&output_lock);
|
|
||||||
std::cout << word << std::endl;
|
|
||||||
omp_unset_lock(&output_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (producers_done == n)
|
|
||||||
should_exit = true;
|
|
||||||
omp_unset_lock(&queue_lock);
|
|
||||||
if (should_exit)
|
|
||||||
break;
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (argc < 3)
|
|
||||||
{
|
|
||||||
std::cerr << "Usage: " << argv[0] << " n file1 file2 ... filen" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
n = std::stoi(argv[1]);
|
|
||||||
if (argc != n + 2)
|
|
||||||
{
|
|
||||||
std::cerr << "Expected " << n << " files, got " << (argc - 2) << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
omp_init_lock(&queue_lock);
|
|
||||||
omp_init_lock(&output_lock);
|
|
||||||
|
|
||||||
#pragma omp parallel num_threads(2 * n)
|
|
||||||
{
|
|
||||||
int tid = omp_get_thread_num();
|
|
||||||
if (tid < n)
|
|
||||||
{
|
|
||||||
producer(tid, argv[2 + tid]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
consumer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
omp_destroy_lock(&queue_lock);
|
|
||||||
omp_destroy_lock(&output_lock);
|
|
||||||
|
|
||||||
std::cout << std::endl
|
|
||||||
<< "All producers and consumers have finished." << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// g++ -o producer_consumer -fopenmp producer_consumer.cpp -std=c++11
|
|
||||||
// .\producer_consumer 4 1.txt 2.txt 3.txt 4.txt
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
请在本目录下,在终端输入 .\producer_consumer 4 1.txt 2.txt 3.txt 4.txt 以运行程序
|
|
||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -1,162 +0,0 @@
|
||||||
#include <mpi.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int compare(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
return (*(int *)a - *(int *)b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void merge(int *a, int *b, int *merged, int size)
|
|
||||||
{
|
|
||||||
int i = 0, j = 0, k = 0;
|
|
||||||
while (i < size && j < size)
|
|
||||||
{
|
|
||||||
if (a[i] < b[j])
|
|
||||||
{
|
|
||||||
merged[k++] = a[i++];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
merged[k++] = b[j++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (i < size)
|
|
||||||
merged[k++] = a[i++];
|
|
||||||
while (j < size)
|
|
||||||
merged[k++] = b[j++];
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
MPI_Init(&argc, &argv);
|
|
||||||
int my_rank, comm_sz;
|
|
||||||
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
|
|
||||||
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
|
|
||||||
const int LOCAL_SIZE = 1250; // 共排序10000个元素,用8个进程,每个进程1250个元素
|
|
||||||
|
|
||||||
int *full_data = NULL;
|
|
||||||
if (my_rank == 0)
|
|
||||||
{
|
|
||||||
FILE *fp = fopen("input.txt", "r");
|
|
||||||
if (fp == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Failed to open input file\n");
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int total_size = comm_sz * LOCAL_SIZE;
|
|
||||||
full_data = malloc(total_size * sizeof(int));
|
|
||||||
for (int i = 0; i < total_size; i++)
|
|
||||||
{
|
|
||||||
if (fscanf(fp, "%d", &full_data[i]) != 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Invalid input format\n");
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int *local_data = malloc(LOCAL_SIZE * sizeof(int));
|
|
||||||
if (local_data == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Memory allocation failed!\n");
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_Scatter(full_data, LOCAL_SIZE, MPI_INT,
|
|
||||||
local_data, LOCAL_SIZE, MPI_INT,
|
|
||||||
0, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
// 本地排序
|
|
||||||
qsort(local_data, LOCAL_SIZE, sizeof(int), compare);
|
|
||||||
|
|
||||||
// 奇偶阶段排序
|
|
||||||
for (int phase = 0; phase < comm_sz; phase++)
|
|
||||||
{
|
|
||||||
int partner;
|
|
||||||
// 计算partner
|
|
||||||
if (phase % 2 == 0)
|
|
||||||
{
|
|
||||||
partner = my_rank + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
partner = my_rank - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查partner是否有效
|
|
||||||
if (partner < 0 || partner >= comm_sz)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 准备发送和接收缓冲区
|
|
||||||
int *received_data = malloc(LOCAL_SIZE * sizeof(int));
|
|
||||||
int *merged_data = malloc(2 * LOCAL_SIZE * sizeof(int));
|
|
||||||
|
|
||||||
// 使用阻塞式通信交换数据
|
|
||||||
MPI_Sendrecv(local_data, LOCAL_SIZE, MPI_INT, partner, 0,
|
|
||||||
received_data, LOCAL_SIZE, MPI_INT, partner, 0,
|
|
||||||
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
|
|
||||||
|
|
||||||
// 合并两个有序数组
|
|
||||||
merge(local_data, received_data, merged_data, LOCAL_SIZE);
|
|
||||||
|
|
||||||
// 保留前一半或后一半
|
|
||||||
if (my_rank < partner)
|
|
||||||
{
|
|
||||||
// 保留较小的一半
|
|
||||||
for (int i = 0; i < LOCAL_SIZE; i++)
|
|
||||||
{
|
|
||||||
local_data[i] = merged_data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 保留较大的一半
|
|
||||||
for (int i = 0; i < LOCAL_SIZE; i++)
|
|
||||||
{
|
|
||||||
local_data[i] = merged_data[LOCAL_SIZE + i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(received_data);
|
|
||||||
free(merged_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 排序完成后收集结果到0号进程
|
|
||||||
int *global_data = NULL;
|
|
||||||
if (my_rank == 0)
|
|
||||||
{
|
|
||||||
global_data = malloc(comm_sz * LOCAL_SIZE * sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_Gather(local_data, LOCAL_SIZE, MPI_INT,
|
|
||||||
global_data, LOCAL_SIZE, MPI_INT,
|
|
||||||
0, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
if (my_rank == 0)
|
|
||||||
{
|
|
||||||
FILE *fout = fopen("output.txt", "w");
|
|
||||||
if (fout == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Failed to open output file\n");
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < comm_sz * LOCAL_SIZE; i++)
|
|
||||||
{
|
|
||||||
fprintf(fout, "%d ", global_data[i]);
|
|
||||||
}
|
|
||||||
fprintf(fout, "\n");
|
|
||||||
fclose(fout);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(local_data);
|
|
||||||
free(full_data);
|
|
||||||
free(global_data);
|
|
||||||
MPI_Finalize();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +0,0 @@
|
||||||
# 作业说明
|
|
||||||
|
|
||||||
input.txt文件为无序的10000个数字,输入到0号进程,再分配到8个进程,各排序1250个数字,最后合并到0号进程输出到output.txt中
|
|
||||||
|
|
||||||
本目录下命令行运行:
|
|
||||||
1.mpicc mpi.c -o mpi
|
|
||||||
2.mpirun -np 8 ./mpi
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
# 2025春季学期并行程序设计期末考试试卷(回忆版)
|
|
||||||
|
|
||||||
## 选择题
|
|
||||||
|
|
||||||
选择题都较简单,不做记录。
|
|
||||||
|
|
||||||
## 填空题
|
|
||||||
|
|
||||||
1.均匀储存访问模型中,处理器访问储存器的时间\_\_\_\_,物理储存器被所有处理器\_\_\_\_,每台处理器带\_\_\_\_缓存。
|
|
||||||
|
|
||||||
2.MPI的点到点通信模式包括:标准通信\_\_\_\_,\_\_\_\_,\_\_\_\_,\_\_\_\_。
|
|
||||||
|
|
||||||
3.四种循环转换包括:循环交换,循环分块,\_\_\_\_,\_\_\_\_。
|
|
||||||
|
|
||||||
4.MPI集合通信的三个主要功能是:通信,\_\_\_\_,\_\_\_\_。
|
|
||||||
|
|
||||||
## 简答题
|
|
||||||
|
|
||||||
1.简述OpenMP的Fork-Join工作模式。
|
|
||||||
|
|
||||||
2.分布式内存系统与共享内存系统的核心区别是什么?
|
|
||||||
|
|
||||||
3.MPI阻塞接收与非阻塞接收的区别是什么?
|
|
||||||
|
|
||||||
4.临界区嵌套会导致什么问题?如何解决?
|
|
||||||
|
|
||||||
5.简述信号量(Semaphore)实现Barrier的方法。
|
|
||||||
|
|
||||||
## 编程题
|
|
||||||
|
|
||||||
1.哲学家用餐问题,如何用互斥锁与信号量解决哲学家用餐问题,保证不会出现死锁和饥饿?(注:此题只需写伪代码,不需要严格的参照接口定义)
|
|
||||||
|
|
||||||
2.多个进程分别拥有私有的数组,现在要计算各个进程中所有数组元素的平均值。
|
|
||||||
|
|
||||||
使用MPI_Allreduce实现函数void Global_average(double loc_arr[], int loc_n, MPI_Comm comm, double* global_avg),先计算局部总和与元素总数,再归约计算全局总和与总元素数,最后算平均值,运行结束后所有进程中的global_avg都应该储存相同的结果,即全局平均值。
|
|
||||||
|
|
||||||
(其中loc_arr[]为每个进程拥有的局部数组,loc_n为局部数组的大小,comm为通讯器,global_avg储存最终结果)
|
|
||||||
|
|
||||||
(注:本题下方提供了会用到的MPI函数定义以供查阅,不需要特意背诵接口。不过奇怪的是考试中唯独没有提供MPI_Allreduce的定义,比较诡异)
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
title: 2024-2025学年下学期期末
|
||||||
|
category:
|
||||||
|
- 软件工程学院
|
||||||
|
- 课程资料
|
||||||
|
tag:
|
||||||
|
- 试卷
|
||||||
|
author:
|
||||||
|
- タクヤマ
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2025春季学期计算理论基础期末考试试卷(回忆版)
|
||||||
|
|
||||||
|
> 注:这次考试的形式是五道题自行选四个做, 每题25分, 多做没有加分;此外, 原卷面是英文, 请大家注意
|
||||||
|
|
||||||
|
1. 给出接受以下语言的DFA:
|
||||||
|
所有以 $1$ 开头, 能被 $5$ 整除的二进制串, 如 $101, 1010, 1111$, 左侧(自动机读入的第一个符号)为最高位, 右侧为最低位
|
||||||
|
|
||||||
|
2. 请给出 DFA 化简中 State Elimination Technique 的复杂度的 tight bound, 要有明确的推理过程
|
||||||
|
|
||||||
|
3. A marble is dropped at A and B. Levers x1, x2 and x3 cause the marble tofall either to the left or to the right. Whenever a marble encounters a lever, it causes the lever to reverse after the marble passes, so the next marble will take the opposite branch. The game wins when there is a marble falls through C. The levers are all initialized to the left. Model this toy by a DFA.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
4. 证明语言 $L = \{a^nb^nc^md^m (n \geq m \geq 1) \cup a^nb^mc^md^n (n \geq m \geq 1)\}$ 不是 CFL
|
||||||
|
|
||||||
|
5. 构造如下的图灵机, 其功能为:给定三个非负整数 $n, m, k$, 判断 $n + m$ 是否等于 $k$.
|
||||||
|
|
||||||
|
输入的形式为:
|
||||||
|
$$\underbrace{11……1}_{n\text{个}}0\underbrace{11……1}_{m\text{个}}0\underbrace{11……1}_{k\text{个}}$$
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -1,13 +1,25 @@
|
||||||
---
|
---
|
||||||
title: 信息安全数学基础(二)
|
title: 计算理论基础
|
||||||
category:
|
category:
|
||||||
- 软件工程学院
|
- 软件工程学院
|
||||||
- 课程评价
|
- 课程评价
|
||||||
tag:
|
tag:
|
||||||
- 信息安全
|
- 课程
|
||||||
- 数学基础
|
|
||||||
- 抽象代数
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 这门课是抽象代数,但是并没有涉及到抽象代数真正复杂的部分,较为浅尝辄止,所以课程本身的学习难度并不高。
|
## 2024-2025学年下学期
|
||||||
### 同样地,这门课实际考试不难,老师会捞,请大家不要害怕。
|
|
||||||
|
### 试卷
|
||||||
|
|
||||||
|
- [2024-2025学年下学期期末试卷](./2024-2025学年下学期期末.md)
|
||||||
|
|
||||||
|
### 徐鸣
|
||||||
|
|
||||||
|
#### 教学资源
|
||||||
|
|
||||||
|
- [2024-2025学年下学期课件](https://drive.vanillaaaa.org/SharedCourses/软件工程学院/计算理论基础/2024-2025学年下学期/课件)
|
||||||
|
- [2024-2025学年下学期作业](https://drive.vanillaaaa.org/SharedCourses/软件工程学院/计算理论基础/2024-2025学年下学期/作业)
|
||||||
|
|
||||||
|
## 推荐教材与参考资料
|
||||||
|
|
||||||
|
- [Hopcroft, Motwani, Ullman_Introduction to Automata Theory, Languages, and Computations (3rd)](https://drive.vanillaaaa.org/d/SharedCourses/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80/Hopcroft%2C%20Motwani%2C%20Ullman_Introduction%20to%20Automata%20Theory%2C%20Languages%2C%20and%20Computations%20(3rd).pdf?sign=RLDrOgi0VxawUe9Wj_l_JLQhR7xQr7e7hkte6B-_NAc=:0)
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,18 +0,0 @@
|
||||||
# 2025春季学期计算理论基础期末考试试卷(回忆版)
|
|
||||||
|
|
||||||
## 注:这次考试的形式是五道题自行选四个做,每题25分,多做没有加分;此外,原卷面是英文,请大家注意
|
|
||||||
|
|
||||||
1.给出接受以下语言的DFA:
|
|
||||||
所有以1开头,能被5整除的二进制串,如101, 1010, 1111,左侧(自动机读入的第一个符号)为最高位,右侧为最低位
|
|
||||||
|
|
||||||
2.请给出DFA化简中State Elimination Technique的复杂度的tight bound,要有明确的推理过程
|
|
||||||
|
|
||||||
3.A marble is dropped at A and B. Levers x1, x2 and x3 cause the marble tofall either to the left or to the right. Whenever a marble encounters a lever, it causes the lever to reverse after the marble passes, so the next marble will take the opposite branch. The game wins when there is a marble falls through C. The levers are all initialized to the left. Model this toy by a DFA.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
4.证明语言 $L = \{a^nb^nc^md^m (n \geq m \geq 1) \cup a^nb^mc^md^n (n \geq m \geq 1)\}$ 不是CFL
|
|
||||||
|
|
||||||
5.构造如下的图灵机,其功能为:给定三个非负整数n, m, k,判断n + m是否等于k。
|
|
||||||
|
|
||||||
输入的形式为:$$\underbrace{11……1}_{n个}0\underbrace{11……1}_{m个}0\underbrace{11……1}_{k个}$$
|
|
||||||
|
|
@ -9,16 +9,17 @@ tag:
|
||||||
- 专业基础
|
- 专业基础
|
||||||
---
|
---
|
||||||
|
|
||||||
# 软件工程数学
|
|
||||||
|
|
||||||
## 2023Spring
|
## 2022-2023学年下学期
|
||||||
|
|
||||||
### 韩莉
|
### 韩莉
|
||||||
|
|
||||||
- 老师人挺好的, 教的也挺好
|
- 老师人挺好的, 教的也挺好
|
||||||
- 作业量适中
|
- 作业量适中
|
||||||
|
|
||||||
## 2024Spring
|
## 2023-2024学年下学期
|
||||||
### 韩莉
|
|
||||||
|
|
||||||
|
### 韩莉
|
||||||
|
|
||||||
## 真题卷
|
## 真题卷
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue