GPU中统一内存最新机制解析

news2024/10/7 8:19:51

通过异构内存管理简化 GPU 应用程序开发

在这里插入图片描述

异构内存管理 (HMM) 是一项 CUDA 内存管理功能,它扩展了 CUDA 统一内存编程模型的简单性和生产力,以包括具有 PCIe 连接的 NVIDIA GPU 的系统上的系统分配内存。 系统分配内存是指最终由操作系统分配的内存; 例如,通过 malloc、mmap、C++ new 运算符(当然使用前面的机制)或为应用程序设置 CPU 可访问内存的相关系统例程。

以前,在基于 PCIe 的计算机上,GPU 无法直接访问系统分配的内存。 GPU 只能访问来自特殊分配器(例如 cudaMalloc 或 cudaMallocManaged)的内存。

启用 HMM 后,所有应用程序线程(GPU 或 CPU)都可以直接访问应用程序的所有系统分配内存。 与统一内存(可以被视为 HMM 的子集或前身)一样,无需在处理器之间手动复制系统分配的内存。 这是因为它会根据处理器使用情况自动放置在 CPU 或 GPU 上。

在 CUDA 驱动程序堆栈中,CPU 和 GPU 页面错误通常用于发现内存应放置在何处。 同样,这种自动放置已经在统一内存中发生 - HMM 只是扩展了行为以覆盖系统分配的内存以及 cudaMalloc 托管内存。

这种直接读取或写入完整应用程序内存地址空间的新功能将显着提高基于 CUDA 构建的所有编程模型的程序员生产力:CUDA C++、Fortran、Python 中的标准并行性、ISO C++、ISO Fortran、OpenACC、OpenMP、 以及许多其他人。

事实上,正如接下来的示例所示,HMM 简化了 GPU 编程,使得 GPU 编程几乎与 CPU 编程一样易于访问。 一些亮点:

  • 编写 GPU 程序时,功能不需要显式内存管理; 因此,最初的“初稿”计划可以小而简单。 显式内存管理(用于性能调整)可以推迟到开发的后期阶段。
  • GPU 编程现在对于不区分 CPU 和 GPU 内存的编程语言来说是实用的。
  • 大型应用程序可以通过 GPU 加速,而无需进行大量内存管理重构或更改第三方库(其源代码并不总是可用)。

顺便说一句,新的硬件平台(例如 NVIDIA Grace Hopper)通过所有 CPU 和 GPU 之间基于硬件的内存一致性来原生支持统一内存编程模型。 对于这样的系统,HMM 不是必需的,事实上,HMM 在那里被自动禁用。 思考这个问题的一种方法是观察 HMM 实际上是一种基于软件的方式,提供与 NVIDIA Grace Hopper Superchip 相同的编程模型。

HMM之前的统一内存

2013 年推出的原始 CUDA 统一内存功能使您只需进行少量更改即可加速 CPU 程序,如下所示:

CPU模式

void sortfile(FILE* fp, int N) {
  char* data;
  data = (char*)malloc(N);

  fread(data, 1, N, fp);
  qsort(data, N, 1, cmp);


  use_data(data);
  free(data);
}

原来的统一内存调用方法

void sortfile(FILE* fp, int N) {
  char* data;
  cudaMallocManaged(&data, N);

  fread(data, 1, N, fp);
  qsort<<<...>>>(data, N, 1, cmp);
  cudaDeviceSynchronize();

  use_data(data);
  cudaFree(data);
}

这种编程模型简单、清晰且功能强大。 在过去的 10 年里,这种方法使无数应用程序能够轻松地从 GPU 加速中受益。 然而,仍然有改进的空间:注意需要一个特殊的分配器:cudaMallocManaged 和相应的 cudaFree。

如果我们可以更进一步,摆脱这些呢? 这正是 HMM 所做的。

HMM之后的统一内存

在具有 HMM 的系统上(详细信息如下),继续使用 malloc 和 free:

CPU模式

void sortfile(FILE* fp, int N) {
  char* data;
  data = (char*)malloc(N);

  fread(data, 1, N, fp);
  qsort(data, N, 1, cmp);


  use_data(data);
  free(data);
}

最新的CUDA统一内存和HMM

void sortfile(FILE* fp, int N) {
  char* data;
  data = (char*)malloc(N);

  fread(data, 1, N, fp);
  qsort<<<...>>>(data, N, 1, cmp);
  cudaDeviceSynchronize();

  use_data(data);
  free(data)
}

使用 HMM,现在两者之间的内存管理是相同的。

系统分配的内存和 CUDA 分配器

使用 CUDA 内存分配器的 GPU 应用程序在具有 HMM 的系统上“按原样”工作。 这些系统的主要区别在于,像 malloc、C++ new 或 mmap 这样的系统分配 API 现在创建可以从 GPU 线程访问的分配,而无需调用任何 CUDA API 来告诉 CUDA 这些分配的存在。 下表列出了具有 HMM 的系统上最常见的 CUDA 内存分配器之间的差异:

Memory allocators on systems with HMMPlacementMigratableAccessible from:
CPUGPURDMA
System allocated
malloc, mmap, …

First-touch
GPU or CPU
YYYY
CUDA managed
cudaMallocManaged
YYN
CUDA device-only
cudaMalloc, …
GPUNN
CUDA host-pinned
cudaMallocHost, …
CPUNY
Overview of system and CUDA memory allocators on systems with HMM

一般来说,选择更好地表达应用程序意图的分配器可以使 CUDA 提供更好的性能。 借助 HMM,这些选择就变成了性能优化,无需在首次从 GPU 访问内存之前预先完成。 HMM 使开发人员能够首先专注于并行化算法,然后在开销提高性能时执行与内存分配器相关的优化。

C++、Fortran 和 Python 的无缝 GPU 加速
HMM 使使用标准化和可移植的编程语言(例如 Python)对 NVIDIA GPU 进行编程变得更加容易,Python 不区分 CPU 和 GPU 内存,并假设所有线程都可以访问所有内存,以及 ISO Fortran 和 ISO C++ 等国际标准描述的编程语言 。

这些语言提供并发和并行设施,使实现能够自动将计算分派到 GPU 和其他设备。 例如,自 C++ 2017 以来,<algorithm> 头文件中的标准库算法接受执行策略,使实现能够并行运行它们。

从 GPU 原地对文件进行排序

例如,在 HMM 之前,对大于 CPU 内存的文件进行就地排序非常复杂,需要先对文件的较小部分进行排序,然后将它们合并为完全排序的文件。 通过HMM,应用程序可以使用mmap将磁盘上的文件映射到内存中,并直接从GPU读取和写入它。 更多详情请参见GitHub上的HMM示例代码file_before.cpp和file_after.cpp。

原来的动态分配

void sortfile(FILE* fp, int N) {
  std::vector<char> buffer;
  buffer.resize(N);
  fread(buffer.data(), 1, N, fp);
  
  // std::sort runs on the GPU:
  std::sort(std::execution::par,
    buffer.begin(), buffer.end(),
    std::greater{});
  use_data(std::span{buffer});
}

最新的统一内存+HMM的动态分配

void sortfile(int fd, int N) {
  auto buffer = (char*)mmap(NULL, N, 
     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    
  // std::sort runs on the GPU: 
  std::sort(std::execution::par,
    buffer, buffer + N,
    std::greater{});
  use_data(std::span{buffer});
}

使用 -stdpar=gpu 选项时,并行 std::sort 算法的 NVIDIA C++ 编译器 (NVC++) 实现会对 GPU 上的文件进行排序。 该选项的使用有很多限制,HPC SDK 文档中有详细说明。

在 HMM 之前:GPU 只能访问 NVC++ 编译的代码中堆上动态分配的内存。 也就是说,CPU 线程堆栈上的自动变量、全局变量和内存映射文件无法从 GPU 访问(请参见下面的示例)。
HMM之后:GPU可以访问所有系统分配的内存,包括其他编译器和第三方库编译的CPU代码中动态分配在堆上的数据、CPU线程堆栈上的自动变量、CPU内存中的全局变量、内存映射文件等

原子内存操作和同步原语

HMM 支持所有内存操作,其中包括原子内存操作。 也就是说,程序员可以使用原子内存操作来将 GPU 和 CPU 线程与标志同步。 虽然 C++ std::atomic API 的某些部分使用 GPU 上尚不可用的系统调用(例如 std::atomic::wait 和 std::atomic::notify_all/_one API),但大多数 C++ 并发原语 API 可轻松用于在 GPU 和 CPU 线程之间执行消息传递。

有关更多信息,请参阅 GitHub 上的 HPC SDK C++ 并行算法:与 C++ 标准库的互操作性文档和atomic_flag.cpp HMM 示例代码。 您可以使用 CUDA C++ 扩展此集。 有关更多详细信息,请参阅 GitHub 上的 Ticket_lock.cpp HMM 示例代码。

Before HMM CPU←→GPU message passing

void main() {
  // Variables allocated with cudaMallocManaged
  std::atomic<int>* flag;
  int* msg;
  cudaMallocManaged(&flag, sizeof(std::atomic<int>));
  cudaMallocManaged(&msg, sizeof(int));
  new (flag) std::atomic<int>(0);
  *msg = 0;
 
  // Start a different CPU thread…
  auto t = std::jthread([&] { 
    // … that launches and waits 
    // on a GPU kernel completing
    std::for_each_n(
      std::execution::par, 
      &msg, 1, [&](int& msg) {
        // GPU thread writes message…
        *msg = 42;       // all accesses via ptrs
        // …and signals completion…
        flag->store(1);  // all accesses via ptrs
    });
  });

After HMM CPU←→GPU message passing

void main() {
  // Variables on CPU thread stack:
  std::atomic<int> flag = 0;  // Atomic
  int msg = 0;                // Message
 
  


// Start a different CPU thread…
  auto t = std::jthread([&] { 
    // … that launches and waits 
    // on a GPU kernel completing
    std::for_each_n(
      std::execution::par, 
      &msg, 1, [&](int& msg) {
        // GPU thread writes message…
        msg = 42;
        // …and signals completion…
        flag.store(1);  
    });
  });
 
  // CPU thread waits on GPU thread
  while (flag.load() == 0);
  // …and reads the message:
  std::cout << msg << std::endl;
  // …the GPU kernel and thread
  // may still be running here…
}

Before HMM CPU←→GPU locks

void main() {
  // Variables allocated with cudaMallocManaged
  ticket_lock* lock;    // Lock
  int* msg;         // Message
  cudaMallocManaged(&lock, sizeof(ticket_lock));
  cudaMallocManaged(&msg, sizeof(int));
  new (lock) ticket_lock();
  *msg = 0;

  // Start a different CPU thread…
  auto t = std::jthread([&] {
    // … that launches and waits 
    // on a GPU kernel completing
    std::for_each_n(
      std::execution::par, 
      &msg, 1, [&](int& msg) {
        // GPU thread takes lock…
        auto g = lock->guard();
        // … and sets message (no atomics)
        msg += 1;
    }); // GPU thread releases lock here
  });
  
  { // Concurrently with GPU thread
    // … CPU thread takes lock…
    auto g = lock->guard();
    // … and sets message (no atomics)
    msg += 1;
  } // CPU thread releases lock here

  t.join();  // Wait on GPU kernel completion
  std::cout << msg << std::endl;
}

After HMM CPU←→GPU locks

void main() {
  // Variables on CPU thread stack:
  ticket_lock lock;    // Lock
  int msg = 0;         // Message

  // Start a different CPU thread…
  auto t = std::jthread([&] {
    // … that launches and waits 
    // on a GPU kernel completing
    std::for_each_n(
      std::execution::par, 
      &msg, 1, [&](int& msg) {
        // GPU thread takes lock…
        auto g = lock.guard();
        // … and sets message (no atomics)
        msg += 1;
    }); // GPU thread releases lock here
  });
  
  { // Concurrently with GPU thread
    // … CPU thread takes lock…
    auto g = lock.guard();
    // … and sets message (no atomics)
    msg += 1;
  } // CPU thread releases lock here

  t.join();  // Wait on GPU kernel completion
  std::cout << msg << std::endl;
}

使用 HMM 加速复杂的 HPC 工作负载

研究大型且寿命长的 HPC 应用程序的研究小组多年来一直渴望为异构平台提供更高效、更可移植的编程模型。 m-AIA 是一款多物理场求解器,由德国亚琛工业大学空气动力学研究所开发,包含近 300,000 行代码。 有关更多信息,请参阅使用 OpenACC 加速 C++ CFD 代码。 最初的原型不再使用 OpenACC,而是使用上述 ISO C++ 编程模型在 GPU 上进行部分加速,而原型工作完成时该模型尚不可用。

HMM 使我们的团队能够加速新的 m-AIA 工作负载,这些工作负载与 GPU 无关的第三方库(例如 FFTW 和 pnetcdf)接口,这些库用于初始条件和 I/O,并且不关心 GPU 直接访问相同的内存。

利用内存映射 I/O 进行快速开发

HMM 提供的一项有趣功能是直接来自 GPU 的内存映射文件 I/O。 它使开发人员能够直接从支持的存储或/磁盘读取文件,而无需将文件暂存在系统内存中,也无需将数据复制到高带宽 GPU 内存。 这还使应用程序开发人员能够轻松处理大于可用物理系统内存的输入数据,而无需构建迭代数据摄取和计算工作流程。

为了演示此功能,我们的团队编写了一个示例应用程序,该应用程序根据 ERA5 再分析数据集构建一年中每一天的每小时总降水量直方图。 有关更多详细信息,请参阅 ERA5 全局重新分析。

ERA5 数据集由几个大气变量的每小时估计值组成。 在数据集中,每个月的总降水量数据存储在单独的文件中。 我们使用了 1981 年至 2020 年 40 年的总降水量数据,总计 480 个输入文件,总输入数据大小约为 1.3 TB。 结果示例请参见下图。

使用 Unix mmap API,可以将输入文件映射到连续的虚拟地址空间。 使用 HMM,这个虚拟地址可以作为输入传递到 CUDA 内核,然后该内核可以直接访问这些值以构建一年中所有天每小时的总降水量直方图。

生成的直方图将驻留在 GPU 内存中,可用于轻松计算有趣的统计数据,例如北半球的平均月降水量。 例如,我们还计算了二月和八月的平均小时降水量。 要查看此应用程序的代码,请访问 GitHub 上的 HMM_sample_code。

Before HMM Batch and pipeline memory transfers

size_t chunk_sz = 70_gb;
std::vector<char> buffer(chunk_sz);

for (fp : files)
  for (size_t off = 0; off < N; off += chunk_sz) {
    fread(buffer.data(), 1, chunk_sz, fp);
    cudeMemcpy(dev, buffer.data(), chunk_sz, H2D);
  
    histogram<<<...>>>(dev, N, out);
    cudaDeviceSynchronize();
  }

After HMM Memory map and transfer on demand

void* buffer = mmap(NULL, alloc_size,
                    PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 
                    -1, 0);
for (fd : files)
  mmap(buffer+file_offset, fileByteSize, 
       PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, 0);


histogram<<<...>>>(buffer, total_N, out);
cudaDeviceSynchronize();

启用并检测 HMM

每当 CUDA 工具包和驱动程序检测到您的系统可以处理它时,它就会自动启用 HMM。 这些要求详细记录在 CUDA 12.2 发行说明:通用 CUDA 中。 你需要:

  • 带有开源 r535_00 驱动程序或更高版本的 NVIDIA CUDA 12.2。 有关详细信息,请参阅 NVIDIA Open GPU 内核模块安装文档。
  • 足够新的 Linux 内核:6.1.24+、6.2.11+ 或 6.3+。
  • 具有以下受支持架构之一的 GPU:NVIDIA Turing、NVIDIA Ampere、NVIDIA Ada Lovelace、NVIDIA Hopper 或更新版本。
  • 64 位 x86 CPU。

查询寻址模式属性以验证 HMM 是否已启用:

$ nvidia-smi -q | grep Addressing
Addressing Mode : HMM

要检测 GPU 可以访问系统分配的内存的系统,请查询 cudaDevAttrPageableMemoryAccess

此外,NVIDIA Grace Hopper Superchip 等系统支持 ATS,其行为与 HMM 类似。 事实上,HMM 和 ATS 系统的编程模型是相同的,因此对于大多数程序来说,仅检查 cudaDevAttrPageableMemoryAccess 就足够了。

然而,对于性能调整和其他高级编程,还可以通过查询 cudaDevAttrPageableMemoryAccessUsesHostPageTables 来区分 HMM 和 ATS。 下表显示了如何解释结果。

AttributeHMMATS
cudaDevAttrPageableMemoryAccess11
cudaDevAttrPageableMemoryAccessUsesHostPageTables01

对于只对查询 HMM 或 ATS 公开的编程模型是否可用感兴趣的可移植应用程序,查询“可分页内存访问”属性通常就足够了。

统一内存性能提示

预先存在的统一内存性能提示的语义没有变化。 对于已经在 NVIDIA Grace Hopper 等硬件一致性系统上使用 CUDA 统一内存的应用程序,主要的变化是 HMM 使它们能够在上述限制内“按原样”在更多系统上运行。

预先存在的统一内存提示也适用于 HMM 系统上的系统分配内存:

  1. __host__ cudaError_t cudaMemPrefetchAsync(* ptr, size_t nbytes, int device):
    异步将内存预取到 GPU(GPU 设备 ID)或 CPU(cudaCpuDeviceId)。
  2. __host__ cudaError_tcudaMemAdvise(*ptr, size_t nbytes, cudaMemoryAdvise,advice, int device): 提示系统:
  • 内存的首选位置:
    cudaMemAdviseSetPreferredLocation,或
  • 将访问内存的设备:cudaMemAdviseSetAccessedBy,或
  • 主要读取不经常修改的内存的设备:
    cudaMemAdviseSetReadMostly

更高级一点:有一个新的 CUDA 12.2 API cudaMemAdvise_v2,它使应用程序能够选择给定内存范围应该首选哪个 NUMA 节点。 当 HMM 将内存内容放在 CPU 端时,这一点就会发挥作用。

与往常一样,内存管理提示可能会提高或降低性能。 行为取决于应用程序和工作负载,但任何提示都不会影响应用程序的正确性。

CUDA 12.2 中 HMM 的局限性

CUDA 12.2 中的初始 HMM 实现提供了新功能,而不会降低任何现有应用程序的性能。 CUDA 12.2 中 HMM 的限制详细记录在 CUDA 12.2 发行说明:通用 CUDA 中。 主要限制是:

  • HMM仅适用于x86_64,尚不支持其他CPU架构。
  • 不支持 HugeTLB 分配上的 HMM。
  • 不支持文件支持内存和 HugeTLBfs 内存上的 GPU 原子操作。
  • 不完全支持没有后续 exec(3) 的 fork(2)。
  • 页面迁移以 4 KB 页面大小的块进行处理。

请继续关注未来的 CUDA 驱动程序更新,这些更新将解决 HMM 限制并提高性能。

总结

HMM 通过消除对在常见的基于 PCIe(通常是 x86)计算机上运行的 GPU 程序的显式内存管理的需要,简化了编程模型。 程序员可以直接使用 malloc、C++ new 和 mmap 调用,就像他们在 CPU 编程中所做的那样。

HMM 通过在 CUDA 程序中安全地使用各种标准编程语言功能,进一步提高程序员的工作效率。 无需担心意外地将系统分配的内存暴露给 CUDA 内核。

HMM 可实现与新的 NVIDIA Grace Hopper Superchip 和类似机器之间的无缝过渡。 在基于 PCIe 的机器上,HMM 提供与 NVIDIA Grace Hopper Superchip 上使用的相同的简化编程模型。

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

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

相关文章

face-api实现人脸识别。

face-api实现人脸识别 face-api的由来tensorflow.js 是什么部分代码模型介绍 face-api的由来 访问地址 JavaScript API for face detection and face recognition in the browser implemented on top of the tensorflow.js core API 官方说明 翻译&#xff1a;在tensorflow.js…

oppo手机怎么录屏?录制屏幕,就看这里!

“有人知道oppo手机怎么录屏吗&#xff0c;前几年买的oppo手机&#xff0c;用到现在感觉挺流畅的&#xff0c;也不是很卡顿&#xff0c;最近听说我这个型号的手机也有录屏功能&#xff0c;但是我不知道怎么打开&#xff0c;就想问问大伙&#xff0c;oppo手机怎么录屏呀。” 在…

MySql015——使用子查询

一、创建customers表 ######################## # Create customers table ######################## use study;CREATE TABLE customers (cust_id int NOT NULL AUTO_INCREMENT,cust_name char(50) NOT NULL ,cust_address char(50) NULL ,cust_city char…

LED地板屏幕的工作原理

LED地砖屏是一款数字化地面展示设备&#xff0c;它的实现主要是以数字技术为核心&#xff0c;通过微电脑全数字化处理以及先进的电路保护设备&#xff0c;对视频进行同步控制&#xff0c;并实现了高分辨率的显示效果&#xff0c;在展厅设计以及舞台演出中都有相关的应用。免费提…

【MySQL】组合查询

目录 一、组合查询 1.创建组合查询 2.union规则 3.包含或取消重复的行 4.对组合查询结果排序 一、组合查询 多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询&#xff08;多条SELECT语句&#xff09;&#xff0c;并将结果作为单个查…

kafka和消息队列

https://downloads.apache.org/kafka/3.5.1/kafka_2.13-3.5.1.tgz d kafka依赖与zookeeper kakka配置文件 broker.id1 #每个 broker 在集群中的唯一标识&#xff0c;正整数。每个节点不一样 listenersPLAINTEXT://192.168.74.70:9092 ##监听地址 num.network.threads3 #…

Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放

场景 开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放&#xff1a; 开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放_srs按需拉流_霸道流氓气质的博客-CSDN…

K-Means(K-均值)聚类算法

目录 K-Means 算法 K-Means 术语 K 值如何确定 K-Means 场景 美国总统大选摇争取摆选民 电商平台用户分层 给亚洲球队做聚类 ​编辑 其他场景 K-Means 工作流程 K-Means 开发流程 K-Means 的评价标准 K-Means 算法 对于 n 个样本点来说&#xff0c;根据距离公式&a…

如何使用HOOPS技术将3D模型转换成点云?

将3D模型转换为点云是一个常见的计算机图形学任务&#xff0c;通常用于将具有几何信息的复杂模型转换为一组离散的点坐标。这可以用于各种应用&#xff0c;如点云分析、计算机辅助设计、虚拟现实等。以下是一些步骤&#xff0c;可供您在将3D模型转换为点云时参考&#xff1a; …

还不会选渲染器?建筑设计师年度爱用排名来了!

近期&#xff0c;建筑设计网站CG architect公布了其主导的一年一度全球建筑渲染引擎调查报告&#xff1a;《2022年建筑可视化渲染引擎调查结果》&#xff0c;该报告主要是针对建筑可视化市场中50多种渲染引擎的使用比例情况。 在3月1号到7月31号期间&#xff0c;CG architect基…

vscode调试PHP代码

目录 准备工作ssh的连接以及配置调试 准备工作 1.首先你需要下载一个vscode 2.下载模块 你需要在VScode中去下载我们所需的两个模块PHP Debug以及remote -ssh 3.安装对应版本的xdebug 需要在xdebug的官方去进行分析&#xff0c;选择适合你自己版本的xdebug 去往官方&#x…

Thrift构建调用说明

安装开发环境 sudo yum -y groupinstall "Development Tools" 安装bison sudo yum install -y wget 安装autoconf wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz tar xvf autoconf-2.69.tar.gz cd autoconf-2.69 ./configure --prefix/usr make…

Android性能优化之APK瘦身详解(瘦身73%)

公司项目在不断的改版迭代中&#xff0c;代码在不断的累加&#xff0c;终于apk包不负重负了&#xff0c;已经到了八十多M了。可能要换种方式表达&#xff0c;到目前为止没有正真的往外推过&#xff0c;一直在内部执行7天讨论需求&#xff0c;5天代码实现的阶段。你在写上个版本…

【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南

Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库&#xff0c;所有的操作都是对象级别的粒度的&#xff0c;这种做法的优势是: 个别对象的失效&#xff0c;不会溢出为更大级别的系统失效。便于实现"强一致性"这个特性。此特性对于机器学习与大数据处理非…

初阶数据结构(六)队列的介绍与实现

&#x1f493;博主csdn个人主页&#xff1a;小小unicorn&#x1f493; ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的学习足迹&#x1f69a; &#x1f339;&#x1f339;&#x1f339;关注我带你学习编程知识 栈 队列的介绍队列的概念&#xff1a;队…

webassembly003 ggml ADAM (暂记)

Adam优化器的工作方式是通过不断更新一阶矩估计和二阶矩估计来自适应地调整学习率&#xff0c;并利用动量法来加速训练过程。这种方式可以在不同的参数更新方向和尺度上进行自适应调整&#xff0c;从而更有效地优化模型。 https://arxiv.org/pdf/1412.6980.pdf 参数 这些参数…

SCI论文创新思路

SCI论文创新思路 一、 创新的分类1、算法创新2、架构创新3、迁移创新4、思想创新5、方法创新6、组合创新 二、组合创新的必要性三、组合创新的流程四、组合创新举例1、组合创新公式2、生活中的例子3、关于CV的例子4、魔改的方法 一、 创新的分类 1、算法创新 比如提出CNN、LS…

django-发送邮件

一、业务场景 业务警告 邮箱验证 密码找回 二、邮件相关协议 1.SMYTP&#xff08;简答邮件传输协议 25端口&#xff09; 属于“推送”协议 负责发送 2.IMAP&#xff08;交互式邮件访问协议&#xff0c;应用层协议&#xff0c;143端口&#xff09; 用于从本地邮件客户端…

华为云Stack的学习(三)

四、华为云Stack公共组件 1.华为云Stack公共负载均衡方案介绍 1.1 LVS原理 LVS是四层负载均衡&#xff0c;建立在OSI模型的传输层之上&#xff0c;所以效率非常高。 LVS有两种转发模式&#xff1a; NAT模式的转发主要通过修改IP地址&#xff08;位于OSI模型的第三层网络层&…

可直接运营的零工零活招聘流量主小程序开发演示

在互联网高速发展的今天&#xff0c;诞生了很多互联网招聘平台&#xff0c;极大的方便了企业与求职者之间的对接。而在招聘市场&#xff0c;零工灵活招聘求职也是不可忽视的一个重要组成部分。基于帮助招聘企业快速获得优质员工和求职者快速寻找合适企业&#xff0c;我们在招聘…