日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

CUDA 7 Stream流简化并发性

發布時間:2023/11/28 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CUDA 7 Stream流简化并发性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CUDA 7 Stream流簡化并發性
異構計算是指高效地使用系統中的所有處理器,包括 CPU 和 GPU 。為此,應用程序必須在多個處理器上并發執行函數。 CUDA 應用程序通過在 streams 中執行異步命令來管理并發性,這些命令是按順序執行的。不同的流可以并發地執行它們的命令,也可以彼此無序地執行它們的命令。
在不指定流的情況下執行異步 CUDA 命令時,運行時使用默認流。在 CUDA 7 之前,默認流是一個特殊流,它隱式地與設備上的所有其他流同步。
CUDA 7 引入了大量強大的新功能 ,包括一個新的選項,可以為每個主機線程使用獨立的默認流,這避免了傳統默認流的序列化。本文將展示如何在 CUDA 程序中簡化實現內核和數據副本之間的并發。

CUDA 中的異步命令
如 CUDA C 編程指南所述,異步命令在設備完成請求的任務之前將控制權返回給調用主機線程(它們是非阻塞的)。這些命令是:
? 內核啟動;
? 存儲器在兩個地址之間復制到同一設備存儲器;
? 從主機到設備的 64kb 或更少內存塊的內存拷貝;
? 由后綴為 Async 的函數執行的內存復制;
? 內存設置函數調用。
為內核啟動或主機設備內存復制指定流是可選的;可以調用 CUDA 命令而不指定流(或通過將 stream 參數設置為零)。下面兩行代碼都在默認流上啟動內核。
kernel<<< blocks, threads, bytes >>>(); // default stream
kernel<<< blocks, threads, bytes, 0 >>>(); // stream 0
默認流
在并發性對性能不重要的情況下,默認流很有用。在 CUDA 7 之前,每個設備都有一個用于所有主機線程的默認流,這會導致隱式同步。正如 CUDA C 編程指南中的“隱式同步”一節所述,如果主機線程向它們之間的默認流發出任何 CUDA 命令,來自不同流的兩個命令就不能并發運行。
CUDA 7 引入了一個新選項, 每線程默認流 ,它有兩個效果。首先,它為每個主機線程提供自己的默認流。這意味著不同主機線程向默認流發出的命令可以并發運行。其次,這些默認流是常規流。這意味著默認流中的命令可以與非默認流中的命令同時運行。
要在 nvcc 7 及更高版本中啟用每線程默認流,可以在包含 CUDA 頭( cuda.h 或 cuda_runtime.h )之前,使用 nvcc 命令行選項 CUDA 或 #define 編譯 CUDA_API_PER_THREAD_DEFAULT_STREAM 預處理器宏。需要注意的是:當代碼由 nvcc 編譯時,不能使用 #define CUDA_API_PER_THREAD_DEFAULT_STREAM 在. cu 文件中啟用此行為,因為 nvcc 在翻譯單元的頂部隱式包含了 cuda_runtime.h 。
Multistream多流示例
看一個小例子。下面的代碼簡單地在八個流上啟動一個簡單內核的八個副本。只為每個網格啟動一個線程塊,這樣就有足夠的資源同時運行多個線程塊。作為遺留默認流如何導致序列化的示例,在默認流上添加不起作用的虛擬內核啟動。這是密碼。
const int N = 1 << 20;

global void kernel(float *x, int n)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
for (int i = tid; i < n; i += blockDim.x * gridDim.x) {
x[i] = sqrt(pow(3.14159,i));
}
}

int main()
{
const int num_streams = 8;

cudaStream_t streams[num_streams];
float *data[num_streams];for (int i = 0; i < num_streams; i++) {cudaStreamCreate(&streams[i]);cudaMalloc(&data[i], N * sizeof(float));// launch one worker kernel per streamkernel<<<1, 64, 0, streams[i]>>>(data[i], N);// launch a dummy kernel on the default streamkernel<<<1, 1>>>(0, 0);
}cudaDeviceReset();return 0;

}
首先讓檢查遺留行為,通過不帶選項的編譯。
nvcc ./stream_test.cu -o stream_legacy可以在 NVIDIA visualprofiler ( nvvp )中運行該程序,以獲得顯示所有流和內核啟動的時間軸。圖 1 顯示了 Macbook Pro 上生成的內核時間線,該 Macbook Pro 帶有 NVIDIA GeForce GT 750M (一臺開普勒 GPU )。可以看到默認流上虛擬內核的非常小的條,以及它們如何導致所有其他流序列化。

一個簡單的多流示例在將任何交錯內核發送到默認流時不會實現并發現在嘗試新的每線程默認流。
nvcc --default-stream per-thread ./stream_test.cu -o stream_per-thread
圖 2 顯示了來自 nvvp 的結果。在這里可以看到九個流之間的完全并發:默認流(在本例中映射到流 14 )和創建的其他八個流。請注意,虛擬內核運行得如此之快,以至于很難看到在這個圖像中默認流上有八個調用。

圖 2 :使用新的每線程默認流選項的多流示例,它支持完全并發執行。
MultiThread多線程示例
看另一個例子,該示例旨在演示新的默認流行為如何使多線程應用程序更容易實現執行并發。下面的例子創建了八個 POSIX 線程,每個線程在默認流上調用的內核,然后同步默認流。(需要在本例中進行同步,以確保探查器在程序退出之前獲得內核開始和結束時間戳。)
#include <pthread.h>
#include <stdio.h>

const int N = 1 << 20;

global void kernel(float *x, int n)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
for (int i = tid; i < n; i += blockDim.x * gridDim.x) {
x[i] = sqrt(pow(3.14159,i));
}
}

void *launch_kernel(void *dummy)
{
float *data;
cudaMalloc(&data, N * sizeof(float));

kernel<<<1, 64>>>(data, N);cudaStreamSynchronize(0);return NULL;

}

int main()
{
const int num_threads = 8;

pthread_t threads[num_threads];for (int i = 0; i < num_threads; i++) {if (pthread_create(&threads[i], NULL, launch_kernel, 0)) {fprintf(stderr, "Error creating threadn");return 1;}
}for (int i = 0; i < num_threads; i++) {if(pthread_join(threads[i], NULL)) {fprintf(stderr, "Error joining threadn");return 2;}
}cudaDeviceReset();return 0;

}
首先,編譯時不使用任何選項來測試遺留的默認流行為。
nvcc ./pthread_test.cu -o pthreads_legacy
在 nvvp 中運行它時,看到一個流,默認流,所有內核啟動都序列化,如圖 3 所示。

圖 3 :一個具有遺留默認流行為的多線程示例:所有八個線程都被序列化。
讓用新的 per-thread default stream 選項編譯它。
nvcc --default-stream per-thread ./pthread_test.cu -o pthreads_per_thread
圖 4 顯示,對于每個線程的默認流,每個線程都會自動創建一個新的流,它們不會同步,因此所有八個線程的內核都會并發運行。

圖 4 :每個線程默認流的多線程示例:所有八個線程的內核同時運行。
更多提示
在為并發進行編程時,還需要記住以下幾點。
? 記住:對于每線程的默認流,每個線程中的默認流的行為與常規流相同,只要同步和并發就可以了。對于傳統的默認流,這是不正確的。
? --default-stream 選項是按編譯單元應用的,確保將其應用于所有需要它的 nvcc 命令行。
? cudaDeviceSynchronize() 繼續同步設備上的所有內容,甚至使用新的每線程默認流選項。如果只想同步單個流,請使用 cudaStreamSynchronize(cudaStream_t stream) ,如的第二個示例所示。
? 從 CUDA 7 開始,還可以使用句柄 cudaStreamPerThread 顯式地訪問每線程的默認流,也可以使用句柄 cudaStreamLegacy 訪問舊的默認流。請注意, cudaStreamLegacy 仍然隱式地與每個線程的默認流同步,如果碰巧在一個程序中混合使用它們。
? 可以通過將 cudaStreamCreate() 標志傳遞給 cudaStreamCreate() 來創建不與傳統默認流同步的 非阻塞流 。
立即下載 CUDA 7rc CUDA toolkitversion7 . 0 的發布候選者今天可以向 NVIDIA 注冊的開發人員提供。如果不是注冊開發者, 在 NVIDIA 開發區注冊免費訪問 。了解 這里是 CUDA 7 的特點。
想了解更多關于 Tesla 平臺上的加速計算以及使用 CUDA 進行 GPU 計算的信息嗎?參加 3 月 17 日至 20 日在圣何塞會議中心舉行的 GPU 技術會議 ,這是世界上規模最大、最重要的 GPU 開發者大會。 Parallel Forall 的讀者可以使用折扣代碼 GM15PFAB 獲得任何會議通行證 20% 的折扣!`

總結

以上是生活随笔為你收集整理的CUDA 7 Stream流简化并发性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧洲在线观看 | 国产在线视频网 | 日韩高清成人 | 丁香六月天婷婷 | 成人h网站 | 欧美97| 国产美女精品视频国产 | www.777色 | 毛片a级片| 亚洲第一激情 | 91嫩草欧美久久久九九九 | 干一夜综合 | 国内毛片视频 | 在线国产中文字幕 | 日本黄色片免费 | 亚洲欧洲久久 | 一级二级在线观看 | 无套内谢少妇高潮免费 | 爆操老女人 | 欧美极品少妇xxxxⅹ免费视频 | 欧美男女交配视频 | 91成人在线免费 | 亚洲视频在线观看一区 | 精品视频免费播放 | 精品无码久久久久成人漫画 | 操操操综合 | 51吃瓜网今日 | 一区免费在线观看 | 久久久国产精华液999999 | 欧洲一区二区视频 | 国产第一亚洲 | 日韩精品视频免费在线观看 | 日韩在线观看av | 麻豆免费电影 | 邻居交换做爰2 | 欧美一级做性受免费大片免费 | 校霸被c到爽夹震蛋上课高潮 | 在线播放91 | 成人手机在线观看 | 欧美a网| 欧美激情在线观看 | 欧美三级三级三级爽爽爽 | 成人久久网站 | 欧美日韩精品一区二区三区四区 | 激情五月五月婷婷 | 成人av中文字幕 | 国产欧美日韩综合精品一区二区三区 | 亚洲第九十七页 | 欧美精选一区 | 中文字幕欧美亚洲 | 日本在线有码 | 久操热| 欧美第一页在线观看 | 日本大尺度床戏揉捏胸 | 色婷婷777 | 国产九色 | 少妇一级视频 | 污片免费看 | 欧美极品jizzhd欧美仙踪林 | 日韩免费成人av | 欧美精品一卡二卡 | 免费日韩一区 | 国产精品不卡一区二区三区 | 香蕉视频在线播放 | gogo亚洲国模私拍人体 | 国产精品国产精品国产 | 久久久综合 | 久婷婷| 国产精品免费久久 | 精品一区二区三区视频 | 丰满少妇理论片 | 国产精品熟女一区二区不卡 | 天天干干干| 在线毛片观看 | 亚洲一区中文字幕在线 | 在线观看的网站 | 97人人爽人人爽人人爽人人爽 | 精品少妇人妻av免费久久洗澡 | 亚洲精品大全 | 中文字幕在线看 | 免费看一级黄色大全 | 久久婷婷精品 | 日韩不卡在线观看 | 欧美午夜性生活 | 久久久久久免费观看 | 男女啪啪软件 | 西西人体www大胆高清 | 一级片免费在线 | 射一射 | 国产欧美精品一区二区色综合 | 狠狠干网址 | 在线观看亚洲大片短视频 | 国产夫妻一区 | 日本少妇电影 | 7777av| 国产又黄又爽 | 国产视频在线免费观看 | 中文字幕一二区 | 欧美日韩 一区二区三区 |