摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/12/04

news2025/2/26 9:48:18

Learning Roadmap:

Section 1: Intro to Parallel Programming & MUSA

  1. Deep Learning Ecosystem(摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/11/30-CSDN博客)
  2. Ubuntu+Driver+Toolkit+conda+pytorch+torch_musa环境安装(2024/11/24-Ubuntu Windows双系统安装 | 2024/11/30-GPU驱动&MUSA Toolkit安装)
  3. C/C++ Review(摩尔线程国产显卡 MUSA 并行编程学习笔记-2024/11/22-CSDN博客)
  4. GPU intros(摩尔线程国产显卡 MUSA 并行编程学习笔记-2024/11/25-CSDN博客)
  5. GPU硬件架构 (摩尔线程国产显卡 MUSA 并行编程学习笔记-2024/11/26-CSDN博客)
  6. Write First Kernels (Here) (2024/11/27-线程层级 | 2024/11/28-First MUSA Kernel to Count Thread | 2024/12/02-向量相加 | 2024/12/03-向量相加(3D))
  7. MUSA API
  8. Faster Matrix Multiplication
  9. Triton
  10. Pytorch Extensions(摩尔线程国产显卡 MUSA 并行编程学习笔记-2024/11/21-CSDN博客)
  11. MNIST Multilayer Perceptron

Section 2: Parallel Programming & MUSA in Depth

  1. Analyzing Parallel Program Performance on a Quad-Core CPU
  2. Scheduling Task Graphs on a Multi-Core CPU
  3. A Simple Renderer in MUSA
  4. Optimizing DNN Performance on DNN Accelerator Hardware
  5. llm.c

Ref:摩尔学院 High-Performance Computing with GPUs | Stanford CS149 - Video | Stanford CS149 - Syllabus

Kernel to Multiply Matrix

Ref:  High-Performance Computing with GPUs Chapter 5 | 摩尔学院 - MUSA基础

下面的代码将用CPU与GPU分别对两个矩阵(Matrix A: 256 * 512, Matrix B: 512 * 256)进行相乘,并计算对应的平均耗时

代码地址

MUSA PLAY GROUND - Github

代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <musa_runtime.h>

#define M 256  // Number of rows in A and C
#define K 512   // Number of columns in A and rows in B
#define N 256  // Number of columns in B and C
#define BLOCK_SIZE 32

// Example 3x2 @ 2x4 = 3x4 -> (M x K) @ (K x N) = (M x N)
// A = [[1, 2], 
//      [3, 4], 
//      [5, 6]]

// B = [[7, 8, 9, 10],
//      [11, 12, 13, 14]]

// C = A * B = [[1*7 + 2*11, 1*8 + 2*12, 1*9 + 2*13, 1*10 + 2*14],
//              [3*7 + 4*11, 3*8 + 4*12, 3*9 + 4*13, 3*10 + 4*14],
//              [5*7 + 6*11, 5*8 + 6*12, 5*9 + 6*13, 5*10 + 6*14]]

// C = [[29, 32, 35, 38],
//      [65, 72, 79, 86],
//      [101, 112, 123, 134]]


// CPU matrix multiplication
void matmul_cpu(float *A, float *B, float *C, int m, int k, int n) {
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            float sum = 0.0f;
            for (int l = 0; l < k; l++) {
                sum += A[i * k + l] * B[l * n + j];
            }
            C[i * n + j] = sum;
        }
    }
}

// MUSA kernel for matrix multiplication
__global__ void matmul_gpu(float *A, float *B, float *C, int m, int k, int n) {
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;

    if (row < m && col < n) {
        float sum = 0.0f;
        for (int l = 0; l < k; l++) {
            sum += A[row * k + l] * B[l * n + col];
        }
        C[row * n + col] = sum;
    }
}

// Initialize matrix with random values
void init_matrix(float *mat, int rows, int cols) {
    for (int i = 0; i < rows * cols; i++) {
        mat[i] = (float)rand() / RAND_MAX;
    }
}

// Function to measure execution time
double get_time() {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return ts.tv_sec + ts.tv_nsec * 1e-9;
}

int main() {
    float *h_A, *h_B, *h_C_cpu, *h_C_gpu;
    float *d_A, *d_B, *d_C;
    int size_A = M * K * sizeof(float);
    int size_B = K * N * sizeof(float);
    int size_C = M * N * sizeof(float);

    // Allocate host memory
    h_A = (float*)malloc(size_A);
    h_B = (float*)malloc(size_B);
    h_C_cpu = (float*)malloc(size_C);
    h_C_gpu = (float*)malloc(size_C);

    // Initialize matrices
    srand(time(NULL));
    init_matrix(h_A, M, K);
    init_matrix(h_B, K, N);

    // Allocate device memory
    musaMalloc(&d_A, size_A);
    musaMalloc(&d_B, size_B);
    musaMalloc(&d_C, size_C);

    // Copy data to device
    musaMemcpy(d_A, h_A, size_A, musaMemcpyHostToDevice);
    musaMemcpy(d_B, h_B, size_B, musaMemcpyHostToDevice);

    // Define grid and block dimensions
    dim3 blockDim(BLOCK_SIZE, BLOCK_SIZE);
    dim3 gridDim((N + BLOCK_SIZE - 1) / BLOCK_SIZE, (M + BLOCK_SIZE - 1) / BLOCK_SIZE);

    // Warm-up runs
    printf("Performing warm-up runs...\n");
    for (int i = 0; i < 3; i++) {
        matmul_cpu(h_A, h_B, h_C_cpu, M, K, N);
        matmul_gpu<<<gridDim, blockDim>>>(d_A, d_B, d_C, M, K, N);
        musaDeviceSynchronize();
    }

    // Benchmark CPU implementation
    printf("Benchmarking CPU implementation...\n");
    double cpu_total_time = 0.0;
    for (int i = 0; i < 20; i++) {
        double start_time = get_time();
        matmul_cpu(h_A, h_B, h_C_cpu, M, K, N);
        double end_time = get_time();
        cpu_total_time += end_time - start_time;
    }
    double cpu_avg_time = cpu_total_time / 20.0;

    // Benchmark GPU implementation
    printf("Benchmarking GPU implementation...\n");
    double gpu_total_time = 0.0;
    for (int i = 0; i < 20; i++) {
        double start_time = get_time();
        matmul_gpu<<<gridDim, blockDim>>>(d_A, d_B, d_C, M, K, N);
        musaDeviceSynchronize();
        double end_time = get_time();
        gpu_total_time += end_time - start_time;
    }
    double gpu_avg_time = gpu_total_time / 20.0;

    // Print results
    printf("CPU average time: %f microseconds\n", (cpu_avg_time * 1e6f));
    printf("GPU average time: %f microseconds\n", (gpu_avg_time * 1e6f));
    printf("Speedup: %fx\n", cpu_avg_time / gpu_avg_time);

    // Free memory
    free(h_A);
    free(h_B);
    free(h_C_cpu);
    free(h_C_gpu);
    musaFree(d_A);
    musaFree(d_B);
    musaFree(d_C);

    return 0;
}

编译

    mcc '02 matmul.mu' -o matmul -mtgpu -O2 -lmusart

   ./matmul

输出结果

 如图所示,GPU提速明显

Notes

同步函数

musaDeviceSynchronize()

确保kernel相关的任务都执行完毕。执行完成后方可安全的执行下一个kernel

__syncthreads()

用途:在同一个block内,同步所有线程的执行。在线程块内所有线程到达此命令前,所有线程都不会执行其后的指令


典型用例:当有多个线程要访问SharedMemory的同一地址,而这个地址存储的值被修改,则需要用__syncthreads同步

注意事项:调用_syncthreads时,必须保证block内所有线程都会调用到这个函数,否则会出错
 


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2254311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac安装MINIO服务器实现本地上传和下载服务

0.MINIO学习文档 Minio客户端mc使用 | Elibaron学习笔记 1.Mac安装MINIO 中文官方网址&#xff1a;MinIO下载和安装 | 用于创建高性能对象存储的代码和下载内容 (1) brew 安装 brew install minio/stable/minio &#xff08;2&#xff09;安装完成&#xff0c;执行brew i…

2024-12-03OpenCV图片处理基础

OpenCV图片处理基础 OpenCV的视频教学&#xff1a;https://www.bilibili.com/video/BV14P411D7MH 1-OpenCV摄像头读取 OpenCV使用摄像头读取图片帧&#xff0c;点击S保存当前帧到指定文件夹&#xff0c;点击Q关闭窗口&#xff0c;点击其他按钮打印按钮的值 要实现这个功能&…

nginx中tcp_nodelay、types_hash_max_size都是什么配置?

nginx中tcp_nodelay、types_hash_max_size都是什么配置&#xff1f; 在 Nginx 中&#xff0c;tcp_nodelay 和 types_hash_max_size 是两个不同的配置项&#xff0c;它们分别与网络性能优化和 MIME 类型的管理相关。 1. tcp_nodelay 功能&#xff1a; 控制是否启用 TCP_NODELAY…

openGauss开源数据库实战十九

文章目录 任务十九 openGauss DML 语句测试任务目标实施步骤一、准备工作二、INSERT语句三、DELETE语句四、UPDATE语句五、清理工作 任务十九 openGauss DML 语句测试 任务目标 掌握DML语句的用法,包括INSERT语句、DELETE语句和UPDATE语句。 实施步骤 一、准备工作 使用Li…

400G智算网络助力知名自动驾驶企业算力训练提效

根据Gartner的最新趋势预测&#xff0c;自动驾驶技术正迅速发展&#xff0c;预计在未来几年内将带来显著的商业效益&#xff0c;特别是在决策智能和边缘人工智能领域。目前&#xff0c;一家领军企业正积极拥抱基于大模型的数字化转型之路&#xff0c;作为自动驾驶领域的佼佼者&…

openEuler 知:安装 GNOME 桌面

openEuler 标准版 ISO 镜像默认不带桌面安装方式&#xff0c;可以先用最小化方式安装系统&#xff0c;然后单独安装 GNOME 组来实现桌面化 dnf group install GNOME -y安装完后&#xff0c;将 systemd 默认 target 设置为 graphical.target systemctl set-default graphical.…

《ODIN: A Single Model for 2D and 3D Segmentation》CVPR2024

斯坦福和微软&#xff1a; 代码链接&#xff1a;ODIN: A Single Model For 2D and 3D Perception 论文链接&#xff1a;2401.02416 摘要 这篇论文介绍了ODIN&#xff08;Omni-Dimensional INstance segmentation&#xff09;&#xff0c;一个能够同时处理2D RGB图像和3D点云…

多行为推荐-KBS 24|基于HyperGRU对比网络的短视频推荐多行为序列建模

论文&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S0950705124004751?via%3Dihub 关键词&#xff1a;短视频推荐&#xff0c;多行为推荐&#xff0c;对比学习&#xff0c;RNN 1 动机 这是我第一次看短视频推荐里涉及到多行为的论文&#xff0c;动机还…

企业网双核心交换机实现冗余和负载均衡(MSTP+VRRP)

MSTP&#xff08;多生成树协议&#xff09; 通过创建多个VLAN实例&#xff0c;将原有的STP、RSTP升级&#xff0c;避免单一VLAN阻塞后导致带宽的浪费&#xff0c;通过将VLAN数据与实例绑定&#xff0c;有效提升网络速率。 VRRP&#xff08;虚拟路由冗余协议&#xff09; 用…

图解RabbitMQ七种工作模式生产者消费者模型的补充

文章目录 1.消费者模型2.生产者-消费者模型注意事项2.1资源释放顺序问题2.2消费者的声明问题2.3虚拟机和用户的权限问题 3.七种工作模式3.1简单模式3.2工作模式3.3发布/订阅模式3.4路由模式3.5通配符模式3.6RPC通信3.7发布确认 1.消费者模型 之前学习的这个消息队列的快速上手…

制造业管理系统中ERP与MES的区别

在当今工业4.0的背景下&#xff0c;数字化管理已成为现代工厂不可或缺的一部分。在这一进程中&#xff0c;企业资源计划&#xff08;ERP&#xff09;系统和制造执行系统&#xff08;MES&#xff09;扮演着关键角色。尽管如此&#xff0c;许多工厂的管理者对于ERP和MES的理解仍存…

面向初学者的 Ansys Mechanical 中的接触建模

接触概述 Ansys Mechanical 中的接触建模是仿真结构不同部分在各种条件下如何相互作用的关键方面。它涉及定义表面的接触方式&#xff0c;即它们是接触、滑动还是分离。Ansys Mechanical 提供了广泛的接触选项来准确建模这些交互&#xff0c;包括粘合、摩擦和无分离接触。每个…

【C++指南】C++内存管理 深度解析

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C指南》 期待您的关注 目录 引言 一、C 内存管理概述 二、C内存区域划分 三、C 内存管理方式 &#x1f343;1.自动内存管理…

聚类算法全面解析:理论与实践结合

聚类&#xff08;Clustering&#xff09;是数据挖掘和机器学习中一类重要的无监督学习方法&#xff0c;旨在将数据划分为多个类别&#xff0c;使得类别内部的数据相似度高&#xff0c;而类别之间的数据差异较大。聚类广泛应用于图像分割、市场分析、生物信息学、文本挖掘等领域…

Python 批量剪辑视频片头片尾工具

Python 批量剪辑视频片头片尾工具 1.简介&#xff1a; 批量剪辑片头片尾的软件&#xff0c;让你的视频创作事半功倍&#xff0c;视频剪辑处理完成后&#xff0c;用户可以在指定文件夹中查看已经剪切完片头片尾的视频‌。这些工具不仅适用于个人用户进行日常的视频编辑工作&am…

大模型分类1—按应用类型

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl根据应用领域,大模型可分为自然语言处理、计算机视觉和多模态大模型。 1. 自然语言处理大模型(NLP) 1.1 应用领域与技术架构 自然语言处理大模型(NLP)的应用领域广泛,包括但不限于文本分类、…

保姆级教程用vite创建vue3项目并初始化添加PrimeVue UI踩坑实录

文章目录 一、什么是PrimeVue二、详细教程1.添加PrimeVue2.配置main.js3.添加自动引入4.配置vite.config.js5.创建测试页面 一、什么是PrimeVue PrimeVue 是一个用于 Vue.js 3.x 开发的一款高质量、广受欢迎的 Web UI 组件库。 官网地址&#xff1a;https://primevue.org/ 二、…

Go的Gin比java的Springboot更加的开箱即用?

前言 隔壁组的云计算零零后女同事&#xff0c;后文简称 云女士 &#xff0c;非说 Go 的 Gin 框架比 Springboot 更加的开箱即用&#xff0c;我心想在 Java 里面 Springboot 已经打遍天下无敌手&#xff0c;这份底蕴岂是 Gin 能比。 但是云女士突出一个执拗&#xff0c;非我要…

php 系统函数 记录

PHP intval() 函数 PHP函数介绍—array_key_exists(): 检查数组中是否存在特定键名 如何使用PHP中的parse_url函数解析URL PHP is_array()函数详解&#xff0c;PHP判断是否为数组 PHP函数介绍&#xff1a;in_array()函数 strpos定义和用法 strpos() 函数查找字符串在另一字符串…