本文最后更新于41 天前,其中的信息可能已经过时,如有错误请发送邮件到zhangweihao22@outlook.com
速度提升
使用time.h记录函数运行时间
经过测试,
普通矩阵乘的c语言实现时间为:
Time taken: 3.816000 seconds
源码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1024
#define TOTAL_SIZE (SIZE * SIZE)
// 函数声明
void generateRandomMatrix(int *matrix);
void printMatrix(int *matrix, int rows, int cols);
void matrixMultiplication(int *A, int *B, int *C);
int main() {
clock_t start, end;
double cpu_time_used;
start = clock();
int *A_h = (int *)malloc(TOTAL_SIZE * sizeof(int));
int *B_h = (int *)malloc(TOTAL_SIZE * sizeof(int));
int *C_h = (int *)malloc(TOTAL_SIZE * sizeof(int));
// 生成随机矩阵A和B
generateRandomMatrix(A_h);
generateRandomMatrix(B_h);
// 计算矩阵乘积C = A * B
matrixMultiplication(A_h, B_h, C_h);
// 释放内存
free(A_h);
free(B_h);
free(C_h);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("Time taken: %f seconds\n", cpu_time_used);
return 0;
}
// 生成随机矩阵
void generateRandomMatrix(int *matrix) {
for (int i = 0; i < TOTAL_SIZE; i++) {
matrix[i] = rand() % 10; // 生成0到9之间的随机数
}
}
// 矩阵乘法
void matrixMultiplication(int *A, int *B, int *C) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
C[i * SIZE + j] = 0;
for (int k = 0; k < SIZE; k++) {
C[i * SIZE + j] += A[i * SIZE + k] * B[k * SIZE + j];
}
}
}
}
cuda简单线程分配实现时间为:
Time taken: 3.096000 seconds
源码:
// 简单矩阵乘运算
#include<iostream>
#include<cuda_runtime.h>
#define M 1024
#define K 1024
#define N 1024
#define SIZE 1024
#define TOTAL_SIZE (SIZE * SIZE)
using namespace std;
__global__ void matrix_mult_kernel (int *A, int *B, int *C, int Mm ,int Kk, int Nn) {
// M为行数目、N为列数,K为中间的维度量
int row = blockIdx.y * blockDim.y + threadIdx.y; // 加载行索引
int col = blockIdx.x * blockDim.x + threadIdx.x; // 加载列索引
if(row < Mm && col < Nn) {
int value = 0.0;
// 为什么下面这里循环的次数为k?
for(int i = 0 ; i < Kk ; i ++) {
value += A[row * Kk + i] * B[i * Nn + col]; // 一个线程计算得出对应C矩阵的一个点(row , col)
}
// 一维线性储存数据
// C数组的行宽为N,列长为M
C[row * Nn + col] = value;
}
}
// 生成随机矩阵
void generateRandomMatrix(int *matrix) {
for (int i = 0; i < TOTAL_SIZE; i++) {
matrix[i] = rand() % 10; // 生成0到9之间的随机数
}
}
// 矩阵乘法
void matrixMultiplication(int *A, int *B, int *C) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
C[i * SIZE + j] = 0;
for (int k = 0; k < SIZE; k++) {
C[i * SIZE + j] += A[i * SIZE + k] * B[k * SIZE + j];
}
}
}
}
int main ()
{
clock_t start, end;
double cpu_time_used;
start = clock();
// int M = 3, K = 3, N = 3; // 矩阵均为为 3x3 和 3x3
// 创建并初始化矩阵 A 和 B
int *A_h = (int *)malloc(TOTAL_SIZE * sizeof(int));
int *B_h = (int *)malloc(TOTAL_SIZE * sizeof(int));
int *C_h = (int *)malloc(TOTAL_SIZE * sizeof(int));
// 生成随机矩阵A和B
generateRandomMatrix(A_h);
generateRandomMatrix(B_h);
// 计算矩阵乘积C = A * B
matrixMultiplication(A_h, B_h, C_h);
// device端变量的声明
int *A_d;
int *B_d;
int *C_d;
// 空间的开辟
cudaMalloc(&A_d,M*K*sizeof(int));
cudaMalloc(&B_d,K*N*sizeof(int));
cudaMalloc(&C_d,M*N*sizeof(int));
// 数据的装载
cudaMemcpy(A_d,A_h,M*K*sizeof(int),cudaMemcpyHostToDevice);
cudaMemcpy(B_d,B_h,K*N*sizeof(int),cudaMemcpyHostToDevice);
// 设置线程块、线程数目
dim3 blockSize(16,16);
// 向上取整得到grid维度数据
dim3 gridSize((N + blockSize.x - 1) / blockSize.x, (M + blockSize.y - 1) / blockSize.y);
matrix_mult_kernel<<<gridSize,blockSize>>>(A_d,B_d,C_d,M,K,N);
// 检测代码
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
std::cerr << "CUDA error: " << cudaGetErrorString(err) << std::endl;
return -1;
}
// 同步
cudaDeviceSynchronize();
// 拷贝结果
cudaMemcpy(C_h,C_d,M*N*sizeof(int),cudaMemcpyDeviceToHost);
// 释放内存
cudaFree(A_d);
cudaFree(B_d);
cudaFree(C_d);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("Time taken: %f seconds\n", cpu_time_used);
return 0;
}