CUDA C++核心庫(CCCL)

文章目錄

    • CUDA C++核心庫(CCCL)
    • 核心庫介紹
      • CUDA C++ 開發工具的層級范圍
      • 各層級工具的具體內容
    • Thrust
      • 自動內存管理
      • 類型安全
      • 自定義分配器(頁鎖定內存)
      • 高級API替代底層操作
      • thrust::transform
        • 基本使用
        • 幾種執行策略
      • iterator
      • load_cs
      • 高效索引mdspan
    • Libcu++
      • cuda::std::tuple
      • cuda::std::variant
      • cuda::std::pair

CUDA C++核心庫(CCCL)

一、標準 C++ 組成

  1. C++ 語言核心
  2. 標準庫(Standard Library)
    • 核心功能:
      ? 通用抽象(General Purpose Abstractions)
      ? 數據結構(Data Structures)
      ? 算法庫(Algorithms)
    • 價值:簡化開發流程,提升代碼健壯性,避免底層重復實現

二、CUDA C++ 組成

  1. 基礎組件:
    ? C++ 語言核心
    ? 主機標準庫(Host Standard Library)
  2. 擴展組件:
    ? CUDA 語言擴展(CUDA Language Extensions)
    ? CUDA C++ 核心庫(CUDA C++ Core Libraries, CCCL)
  3. CCCL 核心功能:
    • 異構 C++ 標準庫(Heterogeneous C++ Standard Library)
      ? 支持 CPU/GPU 協同編程
      ? 提供統一內存模型抽象
    • CUDA 基礎抽象(Fundamental CUDA Abstractions)
      ? 封裝線程管理(Thread Hierarchy)
      ? 設備內存操作(Memory Management)
    • 高性能并行算法庫(High-Performance Parallel Algorithms)
      ? 矩陣運算加速
      ? 數據并行處理原語

核心庫介紹

CUDA C++ 開發工具的層級范圍

  • 橫軸意義:從左到右,工具呈現從 “高層且易用(High-Level & Productive)” 到 “底層且更具控制力(Low-Level & More Control)” 的變化。
  • 左側起點(綠色箭頭 “Start Here”):建議從高層工具開始,如Thrust,因其易用性高、能提升開發效率。
  • 右側終點(紅色箭頭 “Don’t Start Here”):不建議直接從底層工具(如 PTX Wrappers)入手,這類工具復雜且維護難度大。

在這里插入圖片描述

各層級工具的具體內容

  1. 高層工具(High-Level & Productive)
    • libcu++:提供 C++ 標準庫擴展,例如cuda::std::variantcuda::std::optional,方便使用容器及抽象化功能。
    • Thrust:提供 CPU/GPU 并行算法,適用于快速開發高層算法和數據處理。
  2. 中間層工具(中等抽象層次)
    • 迭代器(Fancy Iterators):如cuda::std::spancuda::std::mdspan,用于處理復雜數據結構。
    • 設備范圍算法(Device-wide Algorithms):用于對設備內數據進行全局操作。
    • 塊范圍算法(Block-Scope Algorithms):如cuda::memcpy_async,適合更精細的塊級控制。
    • Warp 范圍算法(Warp-Scope Algorithms):通過cuda::atomic實現線程束間的同步與控制。
  3. 底層工具(Low-Level & More Control)
    • PTX Wrappers:對 PTX 匯編代碼進行封裝,適用于需要極端性能優化的場景。
    • CUB:提供低級 GPU 并行算法的實現,靈活性更高,但使用復雜度也隨之增加。

Thrust

自動內存管理

解釋:Thrust容器使用RAII(資源獲取即初始化)模式,在對象生命周期結束時自動釋放內存,避免內存泄漏。傳統CUDA編程需手動調用cudaFree,容易遺漏。

傳統方法

int* d_data;
cudaMalloc(&d_data, N * sizeof(int));
// 使用d_data
cudaFree(d_data); // 必須手動釋放,否則內存泄漏

Thrust方法

thrust::device_vector<int> d_data(N); // 自動分配內存
// 使用d_data
// 離開作用域時自動釋放內存

類型安全

解釋:Thrust容器在編譯期進行類型檢查,防止不匹配的數據操作。傳統cudaMemcpy僅檢查指針類型,不驗證實際數據類型。

不安全示例(傳統方法):

cuda::std::complex<float>* d_complex;
cudaMalloc(&d_complex, N * sizeof(cuda::std::complex<float>));
int* h_int = new int[N];
// 錯誤:類型不匹配,但cudaMemcpy不報錯
cudaMemcpy(d_complex, h_int, N * sizeof(int), cudaMemcpyHostToDevice);

安全示例(Thrust方法):

thrust::device_vector<cuda::std::complex<float>> d_complex(N);
thrust::host_vector<int> h_int(N);
// 編譯錯誤:無法將int賦值給complex<float>
// d_complex = h_int; // 此操作會觸發編譯錯誤

自定義分配器(頁鎖定內存)

解釋:Thrust允許通過自定義分配器使用頁鎖定內存(pinned memory),提升主機與設備間的數據傳輸效率。

傳統方法

float* h_data;
cudaHostAlloc(&h_data, N * sizeof(float), cudaHostAllocDefault); // 分配頁鎖定內存
// 使用h_data
cudaFreeHost(h_data); // 手動釋放

Thrust方法

using pinned_allocator = thrust::cuda_cub::tagged_allocator<float, // 分配的元素類型thrust::cuda_cub::thread_safe_allocator_tag, // 線程安全標記thrust::cuda_cub::pinned_host_memory_resource_tag // 固定內存標記
>;// 使用頁鎖定內存的host_vector
thrust::host_vector<float, pinned_allocator> h_data(N);
// 使用h_data
// 自動釋放

高級API替代底層操作

解釋:Thrust提供高層算法(如fill_n)替代底層函數(如cudaMemset),提升代碼可讀性和安全性。

傳統方法

float* d_data;
cudaMalloc(&d_data, N * sizeof(float));
cudaMemset(d_data, 0, N * sizeof(float)); // 字節級操作,需手動計算字節數
// 使用d_data
cudaFree(d_data);

Thrust方法

thrust::device_vector<float> d_data(N);
thrust::fill(d_data.begin(), d_data.end(), 0.0f); // 類型安全,自動處理內存

thrust::transform

基本使用

傳統方法

__global__ void gelu_kernel(float* out, const float* inp, int N) {int i = blockIdx.x * blockDim.x + threadIdx.x;if (i < N) {float x = inp[i];float cube = x * x * x;float cdf = 0.5f * (1.0f + tanh(0.79788456f * (x + 0.044715f * cube)));out[i] = x * cdf;}
}void gelu_forward(float* out, const float* inp, int N) {int block_size = 128;int grid_size = CEIL_DIV(N, block_size);gelu_kernel<<<grid_size, block_size>>>(out, inp, N);
}  

thrust::transform方法:

  • 使用thrust::transform方法,只需要關心每個元素的計算邏輯,不用手動管線程分工,代碼更加簡潔,突出”算法意圖“。
  • 可以直接使用多種多種執行策略,控制計算在設備上的執行,如thrust::device、thrust::cuda::par_nosync和thrust::cuda::par_on(stream)等。
struct gelu_functor {__host__ __device__float operator()(const float& x) const {  // 運算符重載operator(),將結構體轉變為函數對象float cube = x * x * x;return x * 0.5f * (1.0f + tanh(0.79788456f * (x + 0.044715f * cube)));}
};void gelu_forward(float* out, const float* inp, int N) {thrust::device_ptr<const float> d_inp(inp);thrust::device_ptr<float> d_out(out);// d_inp輸入數據的起始位置;d_inp+N輸入數據的結束位置;d_out輸出數據的起始位置thrust::transform(thrust::device, d_inp, d_inp + N, d_out, gelu_functor());
} 
幾種執行策略

thrust::device

  • 它指定 Thrust 算法應該在 GPU 設備上執行。它是一種相對通用的設備端執行策略,使用默認的 CUDA 流
  • 在默認情況下,使用thrust::device執行完 Thrust 算法后,主機端代碼如果繼續訪問與該操作相關的設備內存,會隱式地等待操作完成

thrust::cuda::par_nosync

  • 指示 Thrust 算法在 GPU 設備上運行,但它強調不進行隱式同步。這意味著 Thrust 操作提交到 GPU 后,主機端代碼會立即繼續執行,而不會等待 GPU 操作完成。
  • 利用這種策略可以實現主機端和設備端的重疊計算,提高整體的計算效率。例如,在一些復雜的計算流程中,主機端可能需要在設備端計算的同時進行一些其他的預處理或后處理操作,此時thrust::cuda::par_nosync就非常有用。
  • 由于沒有隱式同步,如果主機端后續需要訪問設備端操作的結果,必須手動調用 CUDA 的同步函數(如cudaDeviceSynchronize() )來確保 GPU 操作已經完成,否則會導致錯誤

thrust::cuda::par_on(stream)

  • 通過使用特定的 CUDA 流,可以更好地管理 GPU 資源,實現更細粒度的并行。比如,在一個應用中有多個不同優先級或者不同類型的計算任務,可以分別放在不同的 CUDA 流中,利用thrust::cuda::par_on(stream)將相應的 Thrust 操作分配到合適的流上。
  • 并發與同步管理:可以結合不同流之間的同步原語(如cudaStreamSynchronize() )來控制不同流中操作的執行順序和依賴關系。同時,不同流中的操作在硬件支持下能夠并發執行,進一步提高 GPU 利用率。

iterator

傳統方法:

__global__ void unpermute_kernel(float* inp, float *out, int B, int N, int NH, int d) {int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < B * NH * N * d) {int b = idx / (NH * N * d);int rest = idx % (NH * N * d);int nh_ = rest / (N * d);rest = rest % (N * d);int n = rest / d;int d_ = rest % d;int other_idx = (b * NH * N * d) + (n * NH * d) + (nh_ * d) + d_;out[other_idx] = __ldcs(&inp[idx]);}
}// 核函數調用示例
num_blocks = CEIL_DIV(B * T * C, block_size);
unpermute_kernel<<<num_blocks, block_size>>>(vaccum, out, B, T, NH, HS);  

優化方法:

// Thrust庫迭代器方式實現
auto map = thrust::make_transform_iterator(thrust::make_counting_iterator(0),  // 創建從 0 開始的計數迭代器,提供連續的索引值 idx[=] __host__ __device__ (int idx) {   // 通過 lambda 表達式作為變換操作,[=] 表示按值捕獲外部變量auto [b, n, nh_, d_] = i2n(idx, NH, T, HS);return (b * NH * T * HS) + (n * NH * HS) + (nh_ * HS) + d_;}
);cub::CacheModifiedInputIterator<cub::LOAD_CS, float> vaccumcs(vaccum);
// 該操作會根據 map 提供的索引,把 vaccumcs 指向的數據按序分散到 out 數組對應位置
thrust::scatter(thrust::device, vaccumcs, vaccumcs + B * T * C, map, out); 

load_cs

thrust的高級抽象不會犧牲底層控制能力。可以通過cub::CacheModifiedInputIterator<cub::LOAD_CS, float>來等價cuda kernel中直接調用底層的__ldcs指令。

傳統方法

// CUDA 核函數,實現兩個數組對應元素相加,結果存入輸出數組
__global__ void residual_forward_kernel(float* out, float* inp1, float* inp2, int N) {int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < N) {out[idx] = __ldcs(&inp1[idx]) + __ldcs(&inp2[idx]);}
}// 主機端函數,用于調用上述 CUDA 核函數
void residual_forward(float* out, float* inp1, float* inp2, int N) {const int block_size = 256;const int grid_size = CEIL_DIV(N, block_size); residual_forward_kernel<<<grid_size, block_size>>>(out, inp1, inp2, N);cudaCheck(cudaGetLastError()); 
}

thrust

void residual_forward(float* out, float* inp1, float* inp2, int N) {cub::CacheModifiedInputIterator<cub::LOAD_CS, float> inp1cs(inp1);cub::CacheModifiedInputIterator<cub::LOAD_CS, float> inp2cs(inp2);thrust::transform(thrust::device,inp1cs, inp1cs + N, inp2cs, out, thrust::plus<float>());
}

高效索引mdspan

使用cuda::std::mdspan管理多維數據,從而將傳統的按照一維數組訪問的方式,轉變為以多維方式進行訪問。

傳統方法

// permute_kernel函數實現矩陣重排列操作
__global__ void permute_kernel(float* q, float* k, float* v,const float* inp, int B, int N, int NH, int d) {// 計算當前線程的全局索引int idx = blockIdx.x * blockDim.x + threadIdx.x;// 原始代碼中的矩陣重排列計算// dlb[nh][n][d_] = inp[b][n][nh][d_]// 計算輸入張量的各個維度索引int b = idx / (NH * N * d);      // batch維度int rest = idx % (NH * N * d);   // 剩余部分int nh = rest / (N * d);         // head維度rest = rest % (N * d);           // 繼續分解剩余部分int n = rest / d;                // 序列長度維度int d_ = rest % d;               // 特征維度// 計算輸入張量的線性索引int inp_idx = (b * N * NH * d) +           // batch偏移(n * NH * d) +               // 序列長度偏移(nh * d) +                   // head偏移d_;                          // 特征維度偏移// 執行張量重排列操作q[idx] = __ldcs(&inp[inp_idx]); // 使用__ldcs進行緩存優化的內存讀取k[idx] = __ldcs(&inp[inp_idx + NH * d]);v[idx] = __ldcs(&inp[inp_idx + 2 * NH * d]);
}// attention_forward函數實現注意力前向傳播
void attention_forward(float* out, float* veccum, float* qkv, float* presft, float* att,int B, int T, int C, int NH) {const int block_size = 256;              // CUDA線程塊大小const int softmax_block_size = 256;      // Softmax操作的線程塊大小int HS = C / NH;                        // 每個head的維度大小// 計算每個head的維度大小float *q, *k, *v;q = qkv;                                 // 查詢矩陣Q的起始位置k = qkv + B * T * C;                     // 鍵矩陣K的起始位置v = qkv + 2 * B * T * C;                 // 值矩陣V的起始位置// 計算需要的CUDA線程塊數量int total_threads = B * NH * T * HS;int num_blocks = CEIL_DIV(total_threads, block_size);// 啟動permute_kernel進行張量重排列permute_kernel<<<num_blocks, block_size>>>(q, k, v, qkv, B, T, NH, HS);
}

優化方法:

void attention_forward(float* out, float* vaccum, float* qkvr, float* prestt, float* att,float* inp, int B, int T, int C, int NH) {// 設置CUDA塊大小常量const int block_size = 256;const int softmax_block_size = 256;// 計算每個注意力頭的維度大小int HS = C / NH;  // head size// 設置Q、K、V矩陣的指針,它們在內存中是連續存儲的float *q, *k, *v;q = qkvr + 0 * B * T * C;      // Q矩陣起始位置k = qkvr + 1 * B * T * C;      // K矩陣起始位置v = qkvr + 2 * B * T * C;      // V矩陣起始位置// 使用CUDA動態內存分配constexpr auto dyn = cuda::std::dynamic_extent;  // 這是一個編譯時常量,表示數組維度的大小在運行時確定using ext_t = cuda::std::extent<int, dyn, dyn, 3, dyn, dyn>;  // 定義了一個 5 維數組的維度結構using mds_t = cuda::std::mdspan<const float, ext_t>;  // 不擁有內存,只是提供多維索引到一維內存的映射;提高代碼可讀性和維護性,避免手動計算偏移量// 創建多維數組視圖,用于更方便地訪問數據ext_t extents(B, T, NH, HS);   // 只傳入動態維度,extents仍然是5維的mds_t inp_md(inp, extents);  // 將一維內存指針 inp 映射為多維視圖/*** 示例訪問方式:* 訪問批次b、時間步t、第0個矩陣(對應Q)、頭nh_、維度hs的數據* float value = inp_md(b, t, 0, nh_, hs);*/// 使用thrust庫創建迭代器,用于并行處理auto begin = thrust::make_counting_iterator(0);auto end = begin + B * NH * T * T;// 原始重排列操作的注釋:Q[b][nh][t][d_] = inp[b][t][nh][d_]// 使用thrust并行處理每個元素// [=]:捕獲方式為值捕獲(By Value),表示 Lambda 內部可以使用外部作用域的所有變量(如B, T, C, NH, q, k, v, inp_md等)thrust::for_each(thrust::cuda::par,begin, end,[=] __device__ (int idx) {// 計算當前處理位置的各個維度索引auto [b, t, nh_, hs] = idx2(idx, NH, T, HS);// 執行Q、K、V矩陣的數據重排列q[idx] = inp_md(b, t, 0, nh_, hs);  // Q矩陣賦值k[idx] = inp_md(b, t, 1, nh_, hs);  // K矩陣賦值v[idx] = inp_md(b, t, 2, nh_, hs);  // V矩陣賦值});
}

Libcu++

cuda::std::tuple

傳統方法

__global__ void permute_kernel(float* q, float* k, float* v,const float* inp, int B, int N, int NH, int d) {int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < B * NH * N * d) {int b = idx / (NH * N * d);int rest = idx % (NH * N * d);int nh_ = rest / (N * d);rest = rest % (N * d);int n = rest / d;int d_ = rest % d;//...}
}__global__ void unpermute_kernel(float* inp, float *out, int B,int N, int NH, int d) {int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < B * NH * N * d) {int b = idx / (NH * N * d);int rest = idx % (NH * N * d);int nh_ = rest / (N * d);rest = rest % (N * d);int n = rest / d;int d_ = rest % d;//...}
}

優化方法

  • 使用cuda::std::tuple減少了代碼冗余
__host__ __device__ 
cuda::std::tuple<int, int, int, int> 
idx2n(int idx, int E1, int E2, int E3) {int b = idx / (E1 * E2 * E3);int rest = idx % (E1 * E2 * E3);int nh_ = rest / (E2 * E3);rest = rest % (E2 * E3);int t = rest / E3;int hs = rest % E3;return {b, t, nh_, hs};
}__global__ void permute_kernel(float* q, float* k, float* v,const float* inp, int B, int N, int NH, int d) {int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < B * NH * N * d) {auto [b, n, nh_, d_] = idx2n(idx, NH, N, d);//...}
}__global__ void unpermute_kernel(float* inp, float *out, int B,int N, int NH, int d) {int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < B * NH * N * d) {auto [b, n, nh_, d_] = idx2n(idx, NH, N, d);//...}
}

cuda::std::variant

cuda::std::variant 是一種類型安全的聯合(tagged union )。它可以在同一時間存儲一個值,這個值的類型可以是在聲明 variant 時指定的幾種類型中的任意一種。與傳統的 union 不同,variant 知道當前存儲的值具體是哪種類型,并且提供了安全的訪問方式。

__global__ void variant_kernel() {// 聲明一個可以存儲 int 或 float 類型的 variantcuda::std::variant<int, float> var; var = 42;  // 存儲 int 類型的值if (auto *i = cuda::std::get_if<int>(&var)) {// 安全地獲取 int 類型的值std::cout << "The value is an int: " << *i << std::endl; }var = 3.14f;  // 存儲 float 類型的值if (auto *f = cuda::std::get_if<float>(&var)) {std::cout << "The value is a float: " << *f << std::endl; }
}

cuda::std::pair

cuda::std::pair 是一個簡單的模板類,用于將兩個不同類型的對象組合成一個單一的對象。它有兩個公共成員變量 firstsecond,可以方便地訪問存儲的兩個值。

__global__ void pair_kernel() {// 創建一個 pair,存儲 int 和 float 類型的值cuda::std::pair<int, float> my_pair(10, 2.5f); std::cout << "First value: " << my_pair.first << std::endl;std::cout << "Second value: " << my_pair.second << std::endl;
}

主要參考:

  • how-to-optim-algorithm-in-cuda

點擊查看我的更多AI學習筆記github

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

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

相關文章

MySQL InnoDB存儲引擎深度解析:從原理到優化

InnoDB的優勢InnoDB之所以成為眾多應用的首選&#xff0c;主要得益于以下幾個顯著優勢&#xff1a;事務支持&#xff1a;InnoDB是MySQL中唯一支持ACID&#xff08;原子性、一致性、隔離性、持久性&#xff09;事務的存儲引擎。它通過日志和鎖機制確保事務的完整性&#xff0c;這…

LLM評測框架Ragas:Natural Language Comparison指標(解決了Ollama推理框架不支持的問題)

Factural Correctness Factural Correctness是事實正確性是評價LLM生成的反饋和reference的事實正確性。該指標用于確定生成的響應與參考文獻的一致程度。Factural Correctness取值在0到1之間,越接近于1結果越好。 為了衡量回應和參考文獻之間的一致性,該指標使用 LLM 首先將…

HTTP 協議常見字段(請求頭/響應頭)

HTTP&#xff08;HyperText Transfer Protocol&#xff09;協議通過 請求頭&#xff08;Request Headers&#xff09; 和 響應頭&#xff08;Response Headers&#xff09; 傳遞元數據。以下是 最常見的 HTTP 字段 及其作用&#xff1a;1. 通用字段&#xff08;請求和響應均可使…

期貨配資軟件開發注意事項?

期貨配資軟件開發 期貨配資軟件開發涉及多個核心模塊&#xff0c;包括資金管理、風險控制、交易接口、用戶權限管理等。此類系統需符合金融監管要求&#xff0c;確保資金安全與數據合規。開發過程中需優先考慮高并發、低延遲及系統穩定性。期貨資管系統平臺搭建方案架構設計 采…

STM32-第十節-DMA直接存儲器存取

一、DMA&#xff1a;1.簡介&#xff1a;DMA&#xff0c;直接存儲區存取DMA可以提供外設和存儲器或存儲器與存儲器見的高速數據傳輸&#xff0c;無需CPU干預。12個通道&#xff1a;DMA1&#xff08;7個通道&#xff09;&#xff0c;DMA2&#xff08;5個通道&#xff09;每個通道…

服務器設置國外IP無法訪問對防御攻擊有用嗎?

將服務器設置為僅允許國外 IP 訪問&#xff0c;限制國內 IP 訪問&#xff0c;確實可以在某些特定場景下提高服務器的抗攻擊能力&#xff0c;但這并不能完全防御攻擊。以下是對這種方法的分析、優缺點以及其他防御攻擊的補充措施。1. 僅允許國外 IP 訪問是否有用&#xff1f;1.1…

八大作業票(一) 動火安全作業證

動火安全作業證 執行標準:GB30871 GSDH——2200001 申報單位 申請人 作業申請時間 年 月 日 時 分 動火內容 動火方式 動火地點 動火類別 特級動火□ 一級動火□ 二級動火□ 作業負責人 監護人 動火…

NumPy庫使用教學,簡單詳細。

NumPy 使用教學NumPy 是 Python 中用于科學計算的基礎庫&#xff0c;它提供了高性能的多維數組對象以及用于處理這些數組的工具。下面將結合多個代碼文件&#xff0c;詳細介紹 NumPy 的各種用法。1. 創建數組1.1 從列表創建數組import numpy as np# 一維數組 list1 [1,2,3,4,5…

vue3:十八、內容管理-實現行內圖片的預覽、審核功能

一、實現效果 實現圖片的顯示,大圖預覽;審核部分的待審核的審核功能 二、圖片預覽實現 1、參考官網 官網-圖片預覽 2、圖片預覽插槽設置 {row,index} 插槽中獲取row行信息、index索引信息(指定行圖片預覽需要用到) style 設置基本樣式寬width高height src 設置圖片的路徑…

Go后端配置文件教程

注&#xff1a;本文為博主&#xff0c;首次接觸項目時的入門級配置實操在 Go 后端中&#xff0c;使用配置文件管理參數&#xff08;如數據庫連接、服務端口等&#xff09;是必備技能。Viper 是 Go 生態中最流行的配置管理庫。支持多種配置文件、環境變量、命令行參數等&#xf…

ubuntu24.04安裝CUDA、VLLM、Pytorch等并部署Qwen3-8B-AWQ【50系顯卡通用】

1. 系統更新與依賴安裝 sudo apt update && sudo apt upgrade -y sudo apt install -y python3-pip python3-venv build-essential git nvidia-driver-575注:RTX 5070 Ti 推薦驅動 ≥550 版本 我是直接官網安裝最新的驅動了,反正向上兼容,驅動安裝教程可以參考我以…

Azure可靠性架構指南:構建云時代的高可用系統

隨著企業加速擁抱數字化轉型&#xff0c;云服務的可靠性已成為業務連續性的核心命題。Microsoft Azure憑借其"可靠性即核心"的設計理念&#xff0c;為企業技術決策者與架構師提供了一個可信賴的數字化底座。本文將系統解析Azure如何通過技術架構、工具鏈與方法論&…

linux 驅動 - v4l2 驅動框架

文章目錄一、/dev/videoX1. 查詢設備能力2. 獲取當前視頻格式3. 設置視頻格式4. 申請緩沖區1) mmap 方式2) user 分配5. 查詢緩沖區信息6. 將緩沖區放入隊1) fill_vb2_buffer2) buf_prepare3) get_userptr4) buf_init5) attach_dmabuf 和 map_dmabuf6) start_streaming7) 總結7…

windows內核研究(驅動開發-0環與3環的通信)

驅動開發0環與3環的通信 設備對象 在之前開發窗口程序時&#xff0c;消息都是被封裝成一個結構體&#xff08;MSG&#xff09;&#xff0c;在內核開發時&#xff0c;消息被封裝成另外一個結構體&#xff1a;IRP&#xff08;I/O Request Package&#xff09; 在窗口程序中&#…

ASP.NET Core Web API 內存緩存(IMemoryCache)入門指南

在 Web API 開發中&#xff0c;頻繁訪問數據庫或第三方服務可能會帶來性能瓶頸。為了提升接口響應速度并減輕后端壓力&#xff0c;使用緩存是非常有效的優化手段。本文將帶你快速上手 ASP.NET Core 提供的內存緩存&#xff08;IMemoryCache&#xff09;&#xff0c;無需安裝額外…

Axios Token 設置示例

以下是一個完整的 Axios Token 設置示例&#xff0c;涵蓋全局配置、請求攔截器和單次請求設置三種方式&#xff1a;1. 基礎配置&#xff08;推薦方案&#xff09;javascript復制代碼import axios from axios;// 創建 Axios 實例 const apiClient axios.create({baseURL: https…

Excel數據合并工具:零門檻快速整理

軟件介紹 在數據處理工作中&#xff0c;合并Excel同類數據是一項常見但繁瑣的任務。今天為大家推薦一款專為簡化此類操作設計的工具&#xff0c;它能快速完成工作表內多行同類數據的合并整理&#xff0c;大幅提升數據處理效率。 零門檻操作體驗 相比Excel自帶的數據透視…

深度學習 -- 梯度計算及上下文控制

深度學習 – 梯度計算及上下文控制 文章目錄深度學習 -- 梯度計算及上下文控制一&#xff0c;自動微分1.1 基礎概念1.2 計算梯度1.2.1 計算標量梯度1.2.2 計算向量梯度1.2.3 多標量梯度計算1.2.4 多向量梯度計算二&#xff0c;梯度上下文控制2.1 控制梯度計算2.2 累計梯度2.3 梯…

Redisson RLocalCachedMap 核心參數詳解

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

【Unity3D實例-功能-移動】角色移動-通過WSAD(Rigidbody方式)

你是否曾夢想在虛擬世界中自由翱翔&#xff0c;像海豚一樣在海洋自由穿梭&#xff0c;或者像宇航員一樣在宇宙中盡情探索&#xff1f;今天&#xff0c;我們就來聊聊如何在Unity中使用Rigidbody來實現角色移動。 廢話不多說&#xff0c;走&#xff0c;讓我們馬上來一探究竟&…