OpenCL C 平臺與設備

1. 核心概念

在 OpenCL C API 中:

  • 平臺 (Platform):代表一個 OpenCL 實現,通常對應硬件廠商(NVIDIA、AMD、Intel等)

  • 設備 (Device):具體的計算硬件單元(GPU、CPU、加速器等)

  • 上下文 (Context):管理設備內存和命令執行的環境

  • 命令隊列 (Command Queue):向設備提交命令的通道

2. 基本工作流程

  1. 查詢平臺?→?查詢設備?→?創建上下文?→?創建命令隊列

3. 平臺查詢與選擇

獲取平臺數量和信息

c

#include <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>int main() {cl_int err;// 1. 獲取平臺數量cl_uint num_platforms;err = clGetPlatformIDs(0, NULL, &num_platforms);if (err != CL_SUCCESS || num_platforms == 0) {printf("未找到 OpenCL 平臺!錯誤: %d\n", err);return 1;}printf("找到 %u 個 OpenCL 平臺\n", num_platforms);// 2. 獲取所有平臺cl_platform_id* platforms = (cl_platform_id*)malloc(num_platforms * sizeof(cl_platform_id));err = clGetPlatformIDs(num_platforms, platforms, NULL);// 3. 顯示平臺信息for (cl_uint i = 0; i < num_platforms; i++) {char name[128], vendor[128], version[128];clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(name), name, NULL);clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION, sizeof(version), version, NULL);printf("\n平臺 %u:\n", i);printf("  名稱: %s\n", name);printf("  供應商: %s\n", vendor);printf("  版本: %s\n", version);}free(platforms);return 0;
}
選擇特定平臺

c

// 選擇第一個平臺
cl_platform_id select_first_platform() {cl_uint num_platforms;clGetPlatformIDs(0, NULL, &num_platforms);cl_platform_id* platforms = (cl_platform_id*)malloc(num_platforms * sizeof(cl_platform_id));clGetPlatformIDs(num_platforms, platforms, NULL);cl_platform_id selected = platforms[0];free(platforms);return selected;
}// 按供應商選擇平臺
cl_platform_id select_platform_by_vendor(const char* vendor_name) {cl_uint num_platforms;clGetPlatformIDs(0, NULL, &num_platforms);cl_platform_id* platforms = (cl_platform_id*)malloc(num_platforms * sizeof(cl_platform_id));clGetPlatformIDs(num_platforms, platforms, NULL);cl_platform_id selected = NULL;for (cl_uint i = 0; i < num_platforms; i++) {char vendor[256];clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);if (strstr(vendor, vendor_name) != NULL) {selected = platforms[i];printf("選擇平臺: %s\n", vendor);break;}}free(platforms);return selected;
}

4. 設備查詢與選擇

獲取設備信息

c

void print_device_info(cl_device_id device) {char name[128], vendor[128], version[128];cl_device_type type;cl_uint compute_units;cl_ulong global_mem, local_mem;size_t max_work_group_size;clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(name), name, NULL);clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL);clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(version), version, NULL);clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(type), &type, NULL);clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(global_mem), &global_mem, NULL);clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(local_mem), &local_mem, NULL);clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_work_group_size), &max_work_group_size, NULL);printf("設備信息:\n");printf("  名稱: %s\n", name);printf("  供應商: %s\n", vendor);printf("  版本: %s\n", version);printf("  類型: %s\n", (type == CL_DEVICE_TYPE_GPU) ? "GPU" :(type == CL_DEVICE_TYPE_CPU) ? "CPU" :(type == CL_DEVICE_TYPE_ACCELERATOR) ? "加速器" : "未知");printf("  計算單元: %u\n", compute_units);printf("  全局內存: %.1f MB\n", global_mem / (1024.0 * 1024.0));printf("  本地內存: %.1f KB\n", local_mem / 1024.0);printf("  最大工作組大小: %zu\n", max_work_group_size);
}
獲取和選擇設備

c

cl_device_id get_devices(cl_platform_id platform, cl_device_type device_type) {cl_uint num_devices;cl_int err = clGetDeviceIDs(platform, device_type, 0, NULL, &num_devices);if (err != CL_SUCCESS || num_devices == 0) {printf("未找到指定類型的設備,錯誤: %d\n", err);return NULL;}cl_device_id* devices = (cl_device_id*)malloc(num_devices * sizeof(cl_device_id));clGetDeviceIDs(platform, device_type, num_devices, devices, NULL);printf("找到 %u 個設備:\n", num_devices);for (cl_uint i = 0; i < num_devices; i++) {char name[128];clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(name), name, NULL);printf("  %u: %s\n", i, name);}// 選擇第一個設備cl_device_id selected = devices[0];free(devices);return selected;
}

5. 創建上下文和命令隊列

創建上下文

c

cl_context create_context(cl_platform_id platform, cl_device_id device) {cl_context_properties properties[] = {CL_CONTEXT_PLATFORM,(cl_context_properties)platform,0};cl_int err;cl_context context = clCreateContext(properties, 1, &device, NULL, NULL, &err);if (err != CL_SUCCESS) {printf("創建上下文失敗,錯誤: %d\n", err);return NULL;}return context;
}// 為多個設備創建上下文
cl_context create_context_for_all_devices(cl_platform_id platform, cl_device_type device_type, cl_uint* num_devices, cl_device_id** devices) {// 獲取設備數量clGetDeviceIDs(platform, device_type, 0, NULL, num_devices);if (*num_devices == 0) return NULL;// 獲取設備列表*devices = (cl_device_id*)malloc(*num_devices * sizeof(cl_device_id));clGetDeviceIDs(platform, device_type, *num_devices, *devices, NULL);// 創建上下文cl_context_properties properties[] = {CL_CONTEXT_PLATFORM,(cl_context_properties)platform,0};cl_int err;cl_context context = clCreateContext(properties, *num_devices, *devices, NULL, NULL, &err);if (err != CL_SUCCESS) {free(*devices);*devices = NULL;return NULL;}return context;
}
創建命令隊列

c

cl_command_queue create_command_queue(cl_context context, cl_device_id device) {cl_int err;cl_command_queue queue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);if (err != CL_SUCCESS) {printf("創建命令隊列失敗,錯誤: %d\n", err);return NULL;}return queue;
}// 創建帶屬性的命令隊列(OpenCL 2.0+)
cl_command_queue create_command_queue_with_properties(cl_context context, cl_device_id device) {cl_queue_properties properties[] = {CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE,0};cl_int err;cl_command_queue queue = clCreateCommandQueueWithProperties(context, device, properties, &err);if (err != CL_SUCCESS) {printf("創建命令隊列失敗,錯誤: %d\n", err);return NULL;}return queue;
}

6. 完整示例

c

#include <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define CHECK_CL_ERROR(err, msg) \if (err != CL_SUCCESS) { \printf("%s, 錯誤: %d\n", msg, err); \return 1; \}int main() {cl_int err;cl_platform_id platform;cl_device_id device;cl_context context;cl_command_queue queue;printf("=== OpenCL 平臺和設備查詢 ===\n");// 1. 獲取平臺cl_uint num_platforms;err = clGetPlatformIDs(0, NULL, &num_platforms);CHECK_CL_ERROR(err, "獲取平臺數量失敗");cl_platform_id* platforms = (cl_platform_id*)malloc(num_platforms * sizeof(cl_platform_id));err = clGetPlatformIDs(num_platforms, platforms, NULL);CHECK_CL_ERROR(err, "獲取平臺列表失敗");// 顯示平臺信息for (cl_uint i = 0; i < num_platforms; i++) {char name[256], vendor[256];clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(name), name, NULL);clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);printf("平臺 %u: %s (%s)\n", i, name, vendor);}// 選擇第一個平臺platform = platforms[0];free(platforms);// 2. 獲取設備(優先選擇 GPU)cl_uint num_devices;err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices);if (err != CL_SUCCESS || num_devices == 0) {printf("未找到 GPU 設備,嘗試查找 CPU 設備\n");err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &num_devices);CHECK_CL_ERROR(err, "獲取設備數量失敗");}cl_device_id* devices = (cl_device_id*)malloc(num_devices * sizeof(cl_device_id));err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, num_devices, devices, NULL);if (err != CL_SUCCESS) {err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, num_devices, devices, NULL);CHECK_CL_ERROR(err, "獲取設備列表失敗");}// 顯示設備信息并選擇第一個設備device = devices[0];char device_name[256];clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(device_name), device_name, NULL);printf("選擇設備: %s\n", device_name);free(devices);// 3. 創建上下文cl_context_properties context_props[] = {CL_CONTEXT_PLATFORM,(cl_context_properties)platform,0};context = clCreateContext(context_props, 1, &device, NULL, NULL, &err);CHECK_CL_ERROR(err, "創建上下文失敗");// 4. 創建命令隊列queue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);CHECK_CL_ERROR(err, "創建命令隊列失敗");// 5. 顯示詳細設備信息printf("\n=== 詳細設備信息 ===\n");cl_uint compute_units;cl_ulong global_mem, local_mem;size_t max_work_group_size;char device_version[256], opencl_c_version[256];clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(global_mem), &global_mem, NULL);clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(local_mem), &local_mem, NULL);clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_work_group_size), &max_work_group_size, NULL);clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(device_version), device_version, NULL);clGetDeviceInfo(device, CL_OPENCL_C_VERSION, sizeof(opencl_c_version), opencl_c_version, NULL);printf("設備名稱: %s\n", device_name);printf("計算單元: %u\n", compute_units);printf("全局內存: %.1f MB\n", global_mem / (1024.0 * 1024.0));printf("本地內存: %.1f KB\n", local_mem / 1024.0);printf("最大工作組大小: %zu\n", max_work_group_size);printf("設備版本: %s\n", device_version);printf("OpenCL C 版本: %s\n", opencl_c_version);// 6. 清理資源clReleaseCommandQueue(queue);clReleaseContext(context);printf("\nOpenCL 環境初始化成功!\n");return 0;
}

7. 錯誤處理工具函數

c

// 獲取錯誤代碼的描述
const char* get_cl_error_string(cl_int error) {switch (error) {case CL_SUCCESS: return "CL_SUCCESS";case CL_DEVICE_NOT_FOUND: return "CL_DEVICE_NOT_FOUND";case CL_DEVICE_NOT_AVAILABLE: return "CL_DEVICE_NOT_AVAILABLE";case CL_COMPILER_NOT_AVAILABLE: return "CL_COMPILER_NOT_AVAILABLE";case CL_MEM_OBJECT_ALLOCATION_FAILURE: return "CL_MEM_OBJECT_ALLOCATION_FAILURE";case CL_OUT_OF_RESOURCES: return "CL_OUT_OF_RESOURCES";case CL_OUT_OF_HOST_MEMORY: return "CL_OUT_OF_HOST_MEMORY";case CL_PROFILING_INFO_NOT_AVAILABLE: return "CL_PROFILING_INFO_NOT_AVAILABLE";case CL_MEM_COPY_OVERLAP: return "CL_MEM_COPY_OVERLAP";case CL_IMAGE_FORMAT_MISMATCH: return "CL_IMAGE_FORMAT_MISMATCH";case CL_IMAGE_FORMAT_NOT_SUPPORTED: return "CL_IMAGE_FORMAT_NOT_SUPPORTED";case CL_BUILD_PROGRAM_FAILURE: return "CL_BUILD_PROGRAM_FAILURE";case CL_MAP_FAILURE: return "CL_MAP_FAILURE";case CL_INVALID_VALUE: return "CL_INVALID_VALUE";case CL_INVALID_DEVICE_TYPE: return "CL_INVALID_DEVICE_TYPE";case CL_INVALID_PLATFORM: return "CL_INVALID_PLATFORM";case CL_INVALID_DEVICE: return "CL_INVALID_DEVICE";case CL_INVALID_CONTEXT: return "CL_INVALID_CONTEXT";case CL_INVALID_QUEUE_PROPERTIES: return "CL_INVALID_QUEUE_PROPERTIES";case CL_INVALID_COMMAND_QUEUE: return "CL_INVALID_COMMAND_QUEUE";case CL_INVALID_HOST_PTR: return "CL_INVALID_HOST_PTR";case CL_INVALID_MEM_OBJECT: return "CL_INVALID_MEM_OBJECT";case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";case CL_INVALID_IMAGE_SIZE: return "CL_INVALID_IMAGE_SIZE";case CL_INVALID_SAMPLER: return "CL_INVALID_SAMPLER";case CL_INVALID_BINARY: return "CL_INVALID_BINARY";case CL_INVALID_BUILD_OPTIONS: return "CL_INVALID_BUILD_OPTIONS";case CL_INVALID_PROGRAM: return "CL_INVALID_PROGRAM";case CL_INVALID_PROGRAM_OBJECT: return "CL_INVALID_PROGRAM_OBJECT";case CL_INVALID_KERNEL_NAME: return "CL_INVALID_KERNEL_NAME";case CL_INVALID_KERNEL_DEFINITION: return "CL_INVALID_KERNEL_DEFINITION";case CL_INVALID_KERNEL: return "CL_INVALID_KERNEL";case CL_INVALID_ARG_INDEX: return "CL_INVALID_ARG_INDEX";case CL_INVALID_ARG_VALUE: return "CL_INVALID_ARG_VALUE";case CL_INVALID_ARG_SIZE: return "CL_INVALID_ARG_SIZE";case CL_INVALID_KERNEL_ARGS: return "CL_INVALID_KERNEL_ARGS";case CL_INVALID_WORK_DIMENSION: return "CL_INVALID_WORK_DIMENSION";case CL_INVALID_WORK_GROUP_SIZE: return "CL_INVALID_WORK_GROUP_SIZE";case CL_INVALID_WORK_ITEM_SIZE: return "CL_INVALID_WORK_ITEM_SIZE";case CL_INVALID_GLOBAL_OFFSET: return "CL_INVALID_GLOBAL_OFFSET";case CL_INVALID_EVENT_WAIT_LIST: return "CL_INVALID_EVENT_WAIT_LIST";case CL_INVALID_EVENT: return "CL_INVALID_EVENT";case CL_INVALID_OPERATION: return "CL_INVALID_OPERATION";case CL_INVALID_GL_OBJECT: return "CL_INVALID_GL_OBJECT";case CL_INVALID_BUFFER_SIZE: return "CL_INVALID_BUFFER_SIZE";case CL_INVALID_MIP_LEVEL: return "CL_INVALID_MIP_LEVEL";case CL_INVALID_GLOBAL_WORK_SIZE: return "CL_INVALID_GLOBAL_WORK_SIZE";default: return "未知錯誤";}
}

8. 最佳實踐

  1. 總是檢查錯誤代碼:每個 OpenCL 函數調用后檢查返回值

  2. 資源釋放:使用?clRelease*?函數釋放所有分配的資源

  3. 平臺選擇:提供回退機制,優先選擇 GPU,然后是 CPU

  4. 設備能力檢查:根據設備能力調整算法參數

  5. 錯誤信息:使用?get_cl_error_string?獲取有意義的錯誤信息

總結

函數用途說明
clGetPlatformIDs獲取平臺查詢可用的 OpenCL 平臺
clGetPlatformInfo獲取平臺信息名稱、供應商、版本等
clGetDeviceIDs獲取設備查詢指定類型的設備
clGetDeviceInfo獲取設備信息硬件規格和能力
clCreateContext創建上下文管理設備和內存
clCreateCommandQueue創建命令隊列提交命令到設備

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

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

相關文章

R語言貝葉斯方法在生態環境領域中的高階技術應用

貝葉斯統計已經被廣泛應用到物理學、生態學、心理學、計算機、哲學等各個學術領域&#xff0c;其火爆程度已經跨越了學術圈。一&#xff1a; 1.1復雜數據回歸&#xff08;混合效應&#xff09;模型的選擇策略 1&#xff09;科學研究中數據及其復雜性 2&#xff09;回歸分析歷史…

學習筆記:MySQL(day1)

DDL&#xff08;Data Definition Language&#xff0c;數據定義語言&#xff09;是 SQL 語言的一部分&#xff0c;用于定義和管理數據庫中的數據結構&#xff0c;包括創建、修改、刪除數據庫對象&#xff08;如數據庫、表、視圖、索引等&#xff09;。常見的 DDL 語句及其功能&…

C++ 模板初階:從函數重載到泛型編程的優雅過渡

&#x1f525;個人主頁&#xff1a;愛和冰闊樂 &#x1f4da;專欄傳送門&#xff1a;《數據結構與算法》 、C &#x1f436;學習方向&#xff1a;C方向學習愛好者 ?人生格言&#xff1a;得知坦然 &#xff0c;失之淡然 文章目錄前言一、引言&#xff1a;函數重載的痛點與模板…

從零開始的python學習——語句

? ? ? ? ? づ?ど &#x1f389; 歡迎點贊支持&#x1f389; 個人主頁&#xff1a;勵志不掉頭發的內向程序員&#xff1b; 專欄主頁&#xff1a;python學習專欄&#xff1b; 文章目錄 前言 一、順序語句 二、條件語句 2.1、什么是條件語句 2.2、語法格式 2.3、縮進和代碼…

Python基礎之元組列表集合字典

目錄一、元組&#xff08;Turple&#xff09;1.1、概念定義注意事項1.2、常見操作元組只支持查詢操作&#xff0c;不支持增刪改操作。查詢元素二、列表1.1、概念定義注意事項1.2、常見操作添加修改查找刪除排序列表推導式列表嵌套三、集合1.1、概念定義集合的特點1.2、常見操作…

Ubuntu 22.04 安裝 向日葵遠程Client端

通過向日葵主頁的下載deb包有可能遇到安裝失敗的情況 #因向向日葵提供的libwebkit包是4.0-37了,而向日葵依賴的是3.0.0(Reading database ... 303666 files and directories currently installed.) Preparing to unpack SunloginClient-10.1.1.38139_amd64.deb.1 ... sunloginc…

Linux中卸載和安裝Nginx

阿里云寶塔linux為例一&#xff1a;卸載1.停止 Nginx 服務# 檢查Nginx運行狀態 systemctl status nginx# 停止Nginx服務 sudo systemctl stop nginx# 禁用開機自啟 sudo systemctl disable nginx2. 卸載 Nginx 軟件包# 查看已安裝的Nginx包 yum list installed | grep nginx# 卸…

C++知識匯總(5)

目錄 1.寫在前面 1.C11的發展歷史 2.序列表初始化 3&#xff0c;C11中的std::initializer_list 4.左值和右值 1.左值引用和右值引用 2.生命周期的延長 3.左值和右值的參數匹配 4&#xff0c;移動構造和移動賦值 5.引用折疊 6.完美轉發 總結 1.可變模板參數 2.包擴展…

LeetCode 每日一題 2025/8/25-2025/8/31

記錄了初步解題思路 以及本地實現代碼&#xff1b;并不一定為最優 也希望大家能一起探討 一起進步 目錄8/25 498. 對角線遍歷8/26 3000. 對角線最長的矩形的面積8/27 3459. 最長 V 形對角線段的長度8/28 3446. 按對角線進行矩陣排序8/29 3021. Alice 和 Bob 玩鮮花游戲8/30 36.…

大模型訓練全方位架構分析

文章目錄前言一&#xff1a;數據工程二&#xff1a;計算硬件與集群三&#xff1a;訓練并行策略四&#xff1a;模型架構五&#xff1a;優化與訓練動力學六&#xff1a;內存管理七&#xff1a;訓練流程與工具鏈八&#xff1a;成本與效率九&#xff1a;倫理、安全與對齊十&#xf…

人工智能加速漏洞利用,15分鐘即可完成概念驗證?

一個由人工智能驅動的攻擊研究系統已經創建了十多個漏洞利用程序&#xff0c;在許多情況下將開發時間縮短到不到 15 分鐘&#xff0c;凸顯了全面自動化對企業防御者的影響。 該系統由兩位以色列網絡安全研究人員創建&#xff0c;利用大型語言模型 (LLM) 的提示、通用漏洞與暴露…

Go語言入門(13)-map

map是Go提供的另外一種集合&#xff0c;他可以&#xff1a;①將key映射到value;②快速通過key找到對應的value;同時&#xff0c;它的key幾乎可以是任何類型。聲明map&#xff0c;必須指定key和value的類型&#xff1a;下面來看一個簡單的例程&#xff0c;在該例程中&#xff0c…

基于51單片機的配電室遠程監控系統設計環境檢測GSM環境報警設計

基于51單片機的配電室遠程監控系統設計與環境檢測GSM報警系統 1. 系統功能介紹 本設計是一種基于 STC89C51/STC89C52 單片機 的智能配電室環境監控與報警系統。該系統將溫濕度檢測、水位檢測、煙霧檢測、入侵檢測與風扇、水泵控制相結合&#xff0c;同時配合 SIM900 GSM 模塊 實…

從RNN到Transformer

從RNN到Transformer 目錄 基礎篇&#xff1a;序列模型概述RNN循環神經網絡LSTM長短期記憶網絡Transformer架構時間序列預測應用計算機視覺應用大語言模型應用實戰與優化前沿發展 基礎篇&#xff1a;序列模型概述 {#基礎篇} 什么是序列數據&#xff1f; 序列數據是按照特定順…

【Java進階】Java與SpringBoot線程池深度優化指南

Java與SpringBoot線程池深度優化指南Java與SpringBoot線程池深度優化指南一、Java原生線程池核心原理1. ThreadPoolExecutor 核心參數關鍵參數解析&#xff1a;2. 阻塞隊列選擇策略3. 拒絕策略對比二、SpringBoot線程池配置與優化1. 自動配置線程池2. 異步任務配置類3. 自定義異…

mysql(自寫)

Mysql介于應用和數據之間&#xff0c;通過一些設計 &#xff0c;將大量數據變成一張張像excel的數據表數據頁&#xff1a;mysql將數據拆成一個一個的數據頁索引&#xff1a;為每個頁加入頁號&#xff0c;再為每行數據加入序號&#xff0c;這個序號就是所謂的主鍵。 將每個頁的…

Nginx 502 Bad Gateway:從 upstream 日志到 FastCGI 超時復盤

Nginx 502 Bad Gateway&#xff1a;從 upstream 日志到 FastCGI 超時復盤 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一…

Dreamore AI-解讀并描繪你的夢境

本文轉載自&#xff1a;Dreamore AI-解讀并描繪你的夢境 - Hello123工具導航 ** 一、&#x1f319; 初識 Dreamore AI&#xff1a;你的智能夢境伴侶 Dreamore AI 是一款超有趣的AI 夢境解析與可視化工具&#xff0c;它巧妙地把夢境解讀和圖像生成這兩大功能融為一體。你只需要…

集合-單列集合(Collection)

List系列集合&#xff1a;添加的元素是有序、可重復、有索引的。Set系列集合&#xff1a;添加的元素是無序、不重復、無索引的。代碼&#xff1a;public class A01_CollectionDemo1 {public static void main(String[] args) {/** 注意點&#xff1a;Collection是一個接口&…

寫一個 RTX 5080 上的 cuda gemm fp16

1. cpu 計算 fp16 四則運算由于會用到cpu 的gemm 與 gpu gemm 的對比驗證&#xff0c;所以&#xff0c;這里稍微解釋一下 cpu 計算fp16 gemm 的過程。這里為了簡化理解&#xff0c;cpu 中不使用 avx 相關的 fp16 運算器&#xff0c;而是直接使用 cpu 原先的 ALU 功能。這里使用…