青少年编程与数学 02-018 C++数据结构与算法 22课题、并行算法
课题摘要
并行算法是通过同时执行多个任务或操作来提高计算效率的算法。
一、GPU并行计算
GPU(图形处理单元)并行计算利用GPU的多核心架构,同时处理多个任务或数据片段,特别适合数据密集型和计算密集型的应用。
矩阵乘法示例
cpp
__global__ void matrixMul(float *a, float *b, float *c, int N) {
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if (row < N && col < N) {
float sum = 0.0f;
for (int k = 0; k < N; ++k) {
sum += a[row * N + k] * b[k * N + col];
}
c[row * N + col] = sum;
}
}
该代码展示了如何使用CUDA在GPU上执行矩阵乘法。
二、MPI并行计算
MPI(Message Passing Interface)是一种用于编写分布式内存系统并行程序的标准接口,允许程序员控制进程间通信和数据同步。
allgather操作示例
cpp
#include <mpi.h>
#include <iostream>
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int send_data = rank;
int recv_data[size];
MPI_Allgather(&send_data, 1, MPI_INT, recv_data, 1, MPI_INT, MPI_COMM_WORLD);
std::cout << "Process " << rank << " received data: ";
for (int i = 0; i < size; i++) {
std::cout << recv_data[i] << " ";
}
std::cout << std::endl;
MPI_Finalize();
return 0;
}
该代码展示了如何使用MPI的allgather操作,将每个进程的数据收集到所有进程中。
三、C++中的并行计算
C++可以通过多线程或多进程实现并行计算,适用于不同的计算场景。
多线程并行计算
cpp
#include <iostream>
#include <vector>
#include <thread>
#include <numeric>
void compute_sum(const std::vector<double>& arr, double& result) {
result = std::accumulate(arr.begin(), arr.end(), 0.0);
}
int main() {
std::vector<std::vector<double>> data = {
{1.0, 2.0, 3.0, 4.0, 5.0},
{6.0, 7.0, 8.0, 9.0, 10.0},
{11.0, 12.0, 13.0, 14.0, 15.0},
{16.0, 17.0, 18.0, 19.0, 20.0}
};
std::vector<double> results(data.size());
std::vector<std::thread> threads;
for (size_t i = 0; i < data.size(); ++i) {
threads.emplace_back(compute_sum, std::ref(data[i]), std::ref(results[i]));
}
for (auto& thread : threads) {
thread.join();
}
std::cout << "结果:";
for (const auto& result : results) {
std::cout << " " << result;
}
std::cout << std::endl;
return 0;
}
该代码使用C++的std::thread
库,通过多线程并行计算多个数组的和。
多进程并行计算
cpp
#include <iostream>
#include <vector>
#include <thread>
#include <future>
#include <numeric>
double compute_sum(const std::vector<double>& arr) {
return std::accumulate(arr.begin(), arr.end(), 0.0);
}
int main() {
std::vector<std::vector<double>> data = {
{1.0, 2.0, 3.0, 4.0, 5.0},
{6.0, 7.0, 8.0, 9.0, 10.0},
{11.0, 12.0, 13.0, 14.0, 15.0},
{16.0, 17.0, 18.0, 19.0, 20.0}
};
std::vector<std::future<double>> futures;
for (const auto& arr : data) {
futures.push_back(std::async(std::launch::async, compute_sum, arr));
}
std::cout << "结果:";
for (const auto& future : futures) {
std::cout << " " << future.get();
}
std::cout << std::endl;
return 0;
}
该代码使用C++的std::async
和std::future
,通过多进程并行计算多个数组的和。
四、SIMD并行计算
SIMD(单指令多数据)模型通过在多个处理单元上同时执行相同指令,但每个单元处理不同数据,适用于能够进行数据并发处理的场景。
SIMD并行计算示例
cpp
#include <iostream>
#include <vector>
#include <immintrin.h> // 使用SIMD指令集
void simd_add(const std::vector<double>& a, const std::vector<double>& b, std::vector<double>& result) {
size_t size = a.size();
size_t i = 0;
// 使用SIMD处理4个元素
for (; i + 3 < size; i += 4) {
__m256d va = _mm256_loadu_pd(&a[i]);
__m256d vb = _mm256_loadu_pd(&b[i]);
__m256d vc = _mm256_add_pd(va, vb);
_mm256_storeu_pd(&result[i], vc);
}
// 处理剩余的元素
for (; i < size; ++i) {
result[i] = a[i] + b[i];
}
}
int main() {
std::vector<double> a = {1.0, 2.0, 3.0, 4.0, 5.0};
std::vector<double> b = {6.0, 7.0, 8.0, 9.0, 10.0};
std::vector<double> result(a.size());
simd_add(a, b, result);
std::cout << "结果:";
for (const auto& value : result) {
std::cout << " " << value;
}
std::cout << std::endl;
return 0;
}
该代码使用C++的<immintrin.h>
库,通过SIMD指令集实现并行计算。
这些并行算法在不同的场景下具有各自的优势和适用性,可以根据具体需求选择合适的并行计算模型和工具。