[4]CUDA中的向量計算與并行通信模式

CUDA中的向量計算與并行通信模式

  • 本節開始,我們將利用GPU的并行能力,對其執行向量和數組操作
  • 討論每個通信模式,將幫助你識別通信模式相關的應用程序,以及如何編寫代碼

1.兩個向量加法程序

  • 先寫一個通過cpu實現向量加法的程序
  • 如下所示,向量相加實際上是模仿GPU的寫法,在GPU中,tid 代表特定的某個線程的ID。
  • 如果你的cpu是雙核的,可以在每個核心上運行一個線程,分別將tid初始化為0和1,然后每次循環的時候+2,這樣的話可以實現一個核激素那偶數元素的和,一個核計算基數元素的和,通過兩個線程的實現并行計算
#include "stdio.h"
#include<iostream>
//Defining Number of elements in Array
#define N	5
//Defining vector addition function for CPU
void cpuAdd(int *h_a, int *h_b, int *h_c) {int tid = 0;	while (tid < N){h_c[tid] = h_a[tid] + h_b[tid];tid += 1;}
}int main(void) {int h_a[N], h_b[N], h_c[N];//Initializing two arrays for additionfor (int i = 0; i < N; i++) {h_a[i] = 2 * i*i;h_b[i] = i;}//Calling CPU function for vector additioncpuAdd (h_a, h_b, h_c);//Printing Answerprintf("Vector addition on CPU\n");for (int i = 0; i < N; i++) {printf("The sum of %d element is %d + %d = %d\n", i, h_a[i], h_b[i], h_c[i]);}return 0;
}

在這里插入圖片描述

  • 而總所周知,NVIDIA GPU包含多個塊,每個塊又包含多個線程,因此可以通過GPU實現更多線程并行計算向量的和,最大程度提高速度
  • 可以將代碼修改為核函數如下:
#include "stdio.h"
#include<iostream>
#include <cuda.h>
#include <cuda_runtime.h>//Defining number of elements in Array
#define N	5//Defining Kernel function for vector addition
__global__ void gpuAdd(int* d_a, int* d_b, int* d_c) {//Getting block index of current kernelint tid = blockIdx.x;	// handle the data at this indexif (tid < N)d_c[tid] = d_a[tid] + d_b[tid];
}int main(void) {//定義主機數組變量int h_a[N], h_b[N], h_c[N];//定義設備指針變量int* d_a, * d_b, * d_c;//分配顯卡內存cudaMalloc((void**)&d_a, N * sizeof(int));cudaMalloc((void**)&d_b, N * sizeof(int));cudaMalloc((void**)&d_c, N * sizeof(int));//Initializing Arraysfor (int i = 0; i < N; i++) {h_a[i] = 2 * i * i;h_b[i] = i;}// Copy input arrays from host to device memorycudaMemcpy(d_a, h_a, N * sizeof(int), cudaMemcpyHostToDevice);cudaMemcpy(d_b, h_b, N * sizeof(int), cudaMemcpyHostToDevice);//設置內核參數為5個塊,每個塊一個線程 ,并像核函數傳遞參數gpuAdd << <N, 1 >> > (d_a, d_b, d_c);//將計算結果從顯卡拷貝到主機cudaMemcpy(h_c, d_c, N * sizeof(int), cudaMemcpyDeviceToHost);printf("Vector addition on GPU \n");//Printing result on consolefor (int i = 0; i < N; i++) {printf("The sum of %d element is %d + %d = %d\n", i, h_a[i], h_b[i], h_c[i]);}//Free up memorycudaFree(d_a);cudaFree(d_b);cudaFree(d_c);return 0;
}

在這里插入圖片描述

  • 以上可以發現,通過GPU并行運算,或者多個線程的并行計算,明顯的減少了數組的處理時間。比起CPU上的串行計算,提高了吞吐率
  • 在此說一下吞吐量的含義:只對網絡、設備端口、虛電路或者其他設施,單位時間內成功的傳送數據的數量(以比特、字節、分貝等測量)

2. 對比CPU代碼和GPU代碼的延遲

  • CPU的加法程序和GPU的加法程序都是以一個模塊化的方式來編寫的
  • N的值較小時,看不出cpu與GPU的差異,但是當N值很大時,會發現兩者計算效率的顯著差異
  • 下邊將展示如何為并行計算計時并對兩者時間進行比較
clock_t start_d = clock();printf("Doing GPU Vector add\n");gpuAdd << <N, 1 >> > (d_a, d_b, d_c);cudaThreadSynchronize();clock_t end_d = clock();double time_d = double(end_d - start_d) / CLOCKS_PER_SEC;printf("No of elements in Array: %d \n Device time %f second \n Host time %f second \n ",N, time_d, time_h);

3. 對向量的每個元素進行平方

  • 前邊調用內核函數時啟用了N個塊,每個塊一個線程執行計算;另一種也可以只啟動1個塊,塊里邊有N個線程,淡然也可以啟用N個塊,每個塊M個線程
  • 下邊通過啟用一個塊中的N個線程來執行向量每個元素的平方運算
#include "stdio.h"
#include<iostream>
#include <cuda.h>
#include <cuda_runtime.h>
//Defining number of elements in Array
#define N	5
//Kernel function for squaring number
__global__ void gpuSquare(float *d_in, float *d_out) {//Getting thread index for current kernelint tid = threadIdx.x;	// handle the data at this indexfloat temp = d_in[tid];d_out[tid] = temp*temp;
}int main(void) {//Defining Arrays for hostfloat h_in[N], h_out[N];//Defining Pointers for devicefloat *d_in, *d_out;// allocate the memory on the gpucudaMalloc((void**)&d_in, N * sizeof(float));cudaMalloc((void**)&d_out, N * sizeof(float));//Initializing Arrayfor (int i = 0; i < N; i++) {h_in[i] = i;}//Copy Array from host to devicecudaMemcpy(d_in, h_in, N * sizeof(float), cudaMemcpyHostToDevice);//Calling square kernel with one block and N threads per blockgpuSquare << <1, N >> >(d_in, d_out);//Coping result back to host from device memorycudaMemcpy(h_out, d_out, N * sizeof(float), cudaMemcpyDeviceToHost);//Printing result on consoleprintf("Square of Number on GPU \n");for (int i = 0; i < N; i++) {printf("The square of %f is %f\n", h_in[i], h_out[i]);}//Free up memorycudaFree(d_in);cudaFree(d_out);return 0;
}

在這里插入圖片描述

  • 需注意

    • 每當使用這種方式啟動N個線程并行的時候,需要注意每個塊的最大線程不超過 5121024
    • 現在所有計算能力/顯卡算力在 3.0 - 7.5 的GPU卡,每個塊最大1024個線程
    • 如果N是2000,而你的GPU卡線程的最大數量是512,那么不能寫成 << <12 000 > >>,而應該使用<< <4,500 > >>,應該理性的選擇合適數量的塊和每個塊具有的線程數量

4. 并行通信模式

  • 當多個線程并行執行時,它們遵循一定的通信模式,知道它們在顯存里哪里輸入,哪里輸出

4.1 映射

  • 一對一操作,每個線程或任務讀取單一輸入,產生單一輸出,就是Map模式
d_out[i] = d_in[i] * 2

4.2 收集

  • 此模式下,每個線程或者任務,具有多個輸入,并產生單個輸出,保存到存儲器的單一位置,即Gather模式:
out[i] = (in[i-1] + in[i] + in[i+1]) / 3

4.3 分散式

  • Scatter 模式,線程或者任務讀取單一輸入,單項存儲器產生多個輸出,比如數組排序:
out[i-1] += 2 * in[i] and out[i+1] += 3 * in[i]

4.4 蒙版

  • 當線程或者任務要從數組中讀取固定形狀的相鄰元素時,這叫stencil模式,在圖像處理中非常有用。比如想用一個3X3或者5X5的窗口進行滑動濾波
  • 代碼類似Gather

4.5 轉置

  • 當想要輸入矩陣行主序,輸出矩陣想要列主序,或者有一個結構數組(SoA),想轉換成一個數組結構(AoS),它是特別有用的。Transpose模式如下:
out[i+j*128] = in[j + i*128]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/13810.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13810.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13810.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

軟件設計:基于 python 代碼快速生成 UML 圖

1. 官方文檔 PlantUML Language Reference Guide Comate | 百度研發編碼助手 百度 Comate (Coding Mate Powered by AI) 是基于文心大模型的智能代碼助手&#xff0c;結合百度積累多年的編程現場大數據和外部優秀開源數據&#xff0c;可以生成更符合實際研發場景的優質代碼。…

自動化測試里的數據驅動和關鍵字驅動思路的理解

&#x1f345; 視頻學習&#xff1a;文末有免費的配套視頻可觀看 &#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 初次接觸自動化測試時&#xff0c;對數據驅動和關鍵字驅動不甚理解&#xff0c;覺得有點故弄玄須…

GBDT、XGBoost、LightGBM算法詳解

文章目錄 一、GBDT (Gradient Boosting Decision Tree) 梯度提升決策樹1.1 回歸樹1.2 梯度提升樹1.3 Shrinkage1.4 調參1.5 GBDT的適用范圍1.6 優缺點 二、XGBoost (eXtreme Gradient Boosting)2.1 損失函數2.2 正則項2.3 打分函數計算2.4 分裂節點2.5 算法過程2.6 參數詳解2.7…

oracle中insert all的用法

1、簡述 使用insert into語句進行表數據行的插入&#xff0c;但是oracle中有一個更好的實現方式&#xff1a;使用insert all語句。 insert all語句是oracle中用于批量寫數據的 。insert all分又為 無判斷條件插入有判斷條件插入有判斷條件插入分為 Insert all when... 子句 …

利用 MongoDB Atlas 進行大模型語義搜索和RAG

節前&#xff0c;我們星球組織了一場算法崗技術&面試討論會&#xff0c;邀請了一些互聯網大廠朋友、參加社招和校招面試的同學. 針對算法崗技術趨勢、大模型落地項目經驗分享、新手如何入門算法崗、該如何準備、面試常考點分享等熱門話題進行了深入的討論。 匯總合集&…

基于英飛凌BGT60LTR11AIP E6327芯片具低功耗的脈沖多普勒操作模式常用于汽車應用的雷達上

芯片特征&#xff1a; 60 GHz收發器MMIC&#xff0c;帶一個發射器和一個接收器單元封裝天線&#xff08;AIP&#xff09;&#xff08;6.73.30.56 mm3)低功耗的脈沖多普勒操作模式自主模式用于運動和運動方向的集成檢測器運動檢測信號的直接輸出目標檢測范圍的15個可配置閾值檢測…

Android14之Binder調試(二百一十一)

簡介&#xff1a; CSDN博客專家&#xff0c;專注Android/Linux系統&#xff0c;分享多mic語音方案、音視頻、編解碼等技術&#xff0c;與大家一起成長&#xff01; 優質專欄&#xff1a;Audio工程師進階系列【原創干貨持續更新中……】&#x1f680; 優質專欄&#xff1a;多媒…

前端面試題日常練-day21 【面試題】

題目 希望這些選擇題能夠幫助您進行前端面試的準備&#xff0c;答案在文末。 AJAX 是什么的縮寫&#xff1f; a) Asynchronous JavaScript and XMLb) Asynchronous JavaScript and XHTMLc) Asynchronous Java and XMLd) Asynchronous Java and XHTML使用 AJAX 可以實現以下哪…

2024年5月20日優雅草蜻蜓API大數據服務中心v2.0.4更新

v2.0.4更新 v2.0.4更新 2024年5月20日優雅草蜻蜓API大數據服務中心v2.0.4更新-增加ai繪畫接口增加淘寶聯想詞接口底部增加聯系方式 更新日志 底部增加聯系方式 增加ai繪畫接口 增加淘寶聯想詞接口 增加用戶中心充值提示 用戶中心內頁顏色改版完成 截圖 部分具體更新接口信…

神經網絡優化器-從SGD到AdamW

優化器準則 凸優化基本概念 先定義凸集&#xff0c;集合中的兩個點連接的線還在集合里面&#xff0c;就是凸集&#xff0c;用數學語言來表示就是&#xff1a;對于集合中的任意兩個元素x&#xff0c;y以及任意實數 λ ∈ ( 0 , 1 ) \lambda \in (0,1) λ∈(0,1)&#xff0c;有…

【NLP】詞性標注

詞 詞是自然語言處理的基本單位&#xff0c;自動詞法分析就是利用計算機對詞的形態進行分析&#xff0c;判斷詞的結構和類別。 詞性&#xff08;Part of Speech&#xff09;是詞匯最重要的特性&#xff0c;鏈接詞匯和句法 詞的分類 屈折語&#xff1a;形態分析 分析語&#…

k8s 1.24.x之后如果rest 訪問apiserver

1.由于 在 1.24 &#xff08;還是 1.20 不清楚了&#xff09;之后&#xff0c;下面這兩個apiserver的配置已經被棄用 了&#xff0c;簡單的說就是想不安全的訪問k8s是不可能了&#xff0c;所以只能走安全的訪問方式也就是 https://xx:6443了&#xff0c;所以需要證書。 - --ins…

Git系列:git rm 的高級使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;歡迎蒞臨我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:「stormsha的主頁」…

【go項目01_學習記錄15】

重構MVC 1 Article 模型1.1 首先創建 Article 模型文件1.2 接下來創建獲取文章的方法1.3 新增 types.StringToUint64()函數1.4 修改控制器的調用1.5 重構 route 包1.6 通過 SetRoute 來傳參對象變量1.7 新增方法&#xff1a;1.8 控制器將 Int64ToString 改為 Uint64ToString1.9…

【數據結構】棧和隊列的相互實現

歡迎瀏覽高耳機的博客 希望我們彼此都有更好的收獲 感謝三連支持&#xff01; 1.用棧實現隊列 當隊列中進入這些元素時&#xff0c;相應的棧1中元素出棧順序與出隊列相反&#xff0c;因此我們可以使用兩個棧來使元素的出棧順序相同&#xff1b; 通過將棧1元素出棧&#xff0c;再…

Databend 倒排索引的設計與實現

倒排索引是一種用于全文搜索的數據結構。它的主要功能是將文檔中的單詞作為索引項&#xff0c;映射到包含該單詞的文檔列表。通過倒排索引&#xff0c;可以快速準確地定位到與查詢詞相匹配的文檔列表&#xff0c;從而大幅提高查詢性能。倒排索引在搜索引擎、數據庫和信息檢索系…

matlab實現繪制煙花代碼

下面是一個簡化的示例&#xff0c;它使用MATLAB的繪圖功能來模擬煙花爆炸的視覺效果。請注意&#xff0c;這個示例是概念性的&#xff0c;并且可能需要根據您的具體需求進行調整。 % 初始化參數 num_fireworks 5; % 煙花數量 num_particles_per_firework 200; % 每個煙花…

前端 CSS 經典:3D 漸變輪播圖

前言&#xff1a;無論什么樣式的輪播圖&#xff0c;核心 JS 實現原理都差不多。所以小伙伴們&#xff0c;還是需要了解一下核心 JS 實驗原理的。 效果圖&#xff1a; 實現代碼&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta chars…

MySQL —— 復合查詢

一、基本的查詢回顧練習 前面兩章節整理了許多關于查詢用到的語句和關鍵字&#xff0c;以及MySQL的內置函數&#xff0c;我們先用一些簡單的查詢練習去回顧之前的知識 1. 前提準備 同樣是前面用到的用于測試的表格和數據&#xff0c;一張學生表和三張關于雇員信息表 雇員信息…

優化數據查詢性能:StarRocks 與 Apache Iceberg 的強強聯合

Apache Iceberg 是一種開源的表格格式&#xff0c;專為在數據湖中存儲大規模分析數據而設計。它與多種大數據生態系統組件高度兼容&#xff0c;相較于傳統的 Hive 表格格式&#xff0c;Iceberg 在設計上提供了更高的性能和更好的可擴展性。它支持 ACID 事務、Schema 演化、數據…