当前位置: 首页 > news >正文

全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析

本文介绍了我在 DOCA 开发环境下对 DPU 进行测评和计算能力测试的一些真实体验和记录。在测评过程中,我主要关注了 DPU 在高并发数据传输和深度学习场景下的表现,以及基本的系统性能指标,包括 CPU 计算、内存带宽、多线程/多进程能力和 I/O 性能,并测试了在机器学习应用下的潜在性能。此外,我重点结合了金融高频交易的应用场景,DOCA 展现出了其在低延迟、高吞吐量和高可靠性方面的卓越优势,进一步证明了其在高性能计算和实时数据处理中的广泛应用潜力。


一、测评环境

这是一台装载双端口 DPU 的服务器,操作系统为 Ubuntu 22.04。

我们先来查看CPU信息:

lscpu

在这里插入图片描述
可以看到这是一台基于 ARM Cortex-A78AE 内核的 64 位 ARM 平台设备,有16个核心、较为充足的多级缓存、支持高级SIMD和加密指令扩展,并针对一些常见CPU安全漏洞进行了一定程度的缓解。

接着,我们查看设备型号:

mst status -v
mlxconfig -d /dev/mst/mt41692_pciconf0 -e q

在这里插入图片描述
可以看到设备具体型号是 NVIDIA BlueField-3 B3220 P-Series FHHL DPU,双端口 QSFP112 接口,支持 200GbE(默认模式)或 NDR200 IB。具有16个 Arm 核心处理器和32GB 板载 DDR 内存,PCIe接口为 Gen5.0 x16。


二、测评目标

这次测评的目标是评估 DOCA 环境下 DPU 的实际性能表现,看它在数据密集型任务、高并发通信及后续可能的深度学习任务中能有怎样的表现。我首先登录到指定的 DPU 服务器,搭建基础开发环境,然后编译运行 DPA All-to-All 应用,观察其运行表现。

为了达到上述目标,我们制定以下测评步骤:

  1. 通过 SSH 登录 DPU
  2. 搭建并清理编译环境(Meson、Ninja)
  3. 安装和检查 MPI 环境 (mpich)
  4. 构建启用 dpa_all_to_all 功能的 DOCA 应用
  5. 使用 mpirun 测试并观察数据传输性能
  6. 安装支持 CUDA 的 PyTorch 版本(pip install torch...
  7. 使用 Python 脚本进行 CPU、内存、多线程、多进程和 I/O 的性能测试
  8. 结合 Torch,以后可拓展对深度学习任务的 DPU 加速能力进行评估(本次仅基本测试计算与性能)

三、测评步骤

1. 测评环境构建

首先,通过 SSH 连接到 DPU 服务器,确保具备必要的权限和网络配置。

ssh -p 8889 cqd*****@113.**.***.73
密码: **********

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进入应用程序目录,准备开发环境:

cd /opt/mellanox/doca/applications

检查并安装必要的 MPI 库:

dpkg -l | grep mpich

在这里插入图片描述

apt-get install mpich

在这里插入图片描述

清理之前的构建文件,确保环境整洁:

rm -rf /tmp/build

使用 Meson 构建系统配置项目,启用特定功能:

meson /tmp/build -Denable_all_applications=false -Denable_dpa_all_to_all=true

在这里插入图片描述
在这里插入图片描述

通过 Ninja 进行编译:

ninja -C /tmp/build

检查 Mellanox 状态,确保硬件正常运行:

mst status -v

在这里插入图片描述

这里可以看到我们的双端口 DPU。


2. All-to-All MPI 性能测试

在开始实操之前,我们先来了解一下什么是 All-to-all 。

All-to-all 是一种 MPI(消息传递接口)方法。MPI 是一种标准化且可移植的消息传递标准,旨在在并行计算体系结构上运行。一个 MPI 程序由多个进程并行运行。

其运行示例图如下:

在这里插入图片描述

在上图中,每个进程将其本地的发送缓冲区(sendbuf)分成 n 个块(本例中为 4 个块),每个块包含 sendcount 个元素(本例中为 4 个元素)。进程 i 会将其本地发送缓冲区中的第 k 个块发送给进程 k,而进程 k 则将这些数据放置在其本地接收缓冲区(recvbuf)的第 i 个块中。

通过使用 DOCA DPA 来实现 all-to-all 方法,可以将从 srcbuf 复制元素到 recvbufs 的过程卸载给 DPA,从而使 CPU 解放出来,去执行其他计算工作。

下图描述了基于主机的全对全和 DPA 全对全之间的区别。

在这里插入图片描述

  • 在 DPA all-to-all 中,DPA 线程执行 all-to-all,而 CPU 可以自由地进行其他计算;
  • 在基于主机的全对全中,CPU 在某些时候仍必须执行全对全,并且不能完全自由地进行其他计算;

下面我们来实操:

我们使用 mpirun 运行 DPA All-to-All 应用,进行性能测试:

mpirun -np 4 /tmp/build/dpa_all_to_all/doca_dpa_all_to_all -m 32 -d "mlx5_0"

返回结果如图:

在这里插入图片描述

从运行结果上,我们不难看出 ,DPU 很快完成了数据分发和聚合,显著降低了 CPU 在全对全通信中的参与度和负载,同时还提高了整体吞吐率并降低了通信延迟,无论在性能表现还是资源利用率上都非常出色,并且稳定性也很强。

性能测试结果分析:

指标描述
性能表现DPU 在处理高并发数据传输任务时表现出色,能够有效利用多核资源,实现低延迟和高吞吐量。
资源利用率CPU 和内存的利用率保持在合理范围内,未出现资源瓶颈。
稳定性应用运行稳定,未出现崩溃或异常中断的情况。

测试结束后,清理构建文件:

rm -rf /tmp/build

3. 多项能力的基准测评

在初步运行 DPA All-to-All 应用后,我进一步进行了计算能力测试,用来简单评估系统的基础计算能力和 I/O 性能。这些测试不仅针对 CPU 和内存的单一指标,也考察多线程、多进程并行处理能力,以及文件 I/O 表现。

我们编写并运行了以下 Python 脚本,涵盖多项性能测试,包括 CPU 计算性能、内存带宽、多线程与多进程性能以及 I/O 性能。代码对 CPU 矩阵乘法、内存带宽、多线程、多进程以及 I/O 进行了基准测评。

在这里插入图片描述

全部代码如下:

import time
import numpy as np
import multiprocessing
import threading
import os# 测试 CPU 计算性能(矩阵乘法)
def cpu_compute_benchmark(matrix_size=1000, iterations=100):print("开始 CPU 计算性能测试(矩阵乘法)...")A = np.random.rand(matrix_size, matrix_size)B = np.random.rand(matrix_size, matrix_size)start_time = time.time()for _ in range(iterations):C = np.matmul(A, B)end_time = time.time()total_time = (end_time - start_time) * 1000  # 毫秒print(f"CPU 计算总时长: {total_time:.2f} ms")# 测试内存带宽
def memory_bandwidth_benchmark(array_size=10000000):print("开始内存带宽测试...")A = np.ones(array_size, dtype=np.float64)start_time = time.time()B = A * 2C = B + 3end_time = time.time()total_time = (end_time - start_time) * 1000  # 毫秒print(f"内存带宽测试总时长: {total_time:.2f} ms")# 测试多线程性能
def thread_task(n):# 简单的计算任务total = 0for i in range(n):total += i*ireturn totaldef multithreading_benchmark(num_threads=8, iterations=1000000):print("开始多线程性能测试...")threads = []start_time = time.time()for _ in range(num_threads):thread = threading.Thread(target=thread_task, args=(iterations,))threads.append(thread)thread.start()for thread in threads:thread.join()end_time = time.time()total_time = (end_time - start_time) * 1000  # 毫秒print(f"多线程测试总时长: {total_time:.2f} ms")# 测试多进程性能
def process_task(n):total = 0for i in range(n):total += i*ireturn totaldef multiprocessing_benchmark(num_processes=8, iterations=1000000):print("开始多进程性能测试...")pool = multiprocessing.Pool(processes=num_processes)start_time = time.time()results = pool.map(process_task, [iterations] * num_processes)pool.close()pool.join()end_time = time.time()total_time = (end_time - start_time) * 1000  # 毫秒print(f"多进程测试总时长: {total_time:.2f} ms")# 测试 I/O 性能(文件读写)
def io_benchmark(file_size_mb=100, iterations=10):print("开始 I/O 性能测试...")filename = "temp_test_file.dat"data = os.urandom(file_size_mb * 1024 * 1024)  # 生成随机数据# 写入测试start_time = time.time()for _ in range(iterations):with open(filename, 'wb') as f:f.write(data)end_time = time.time()write_time = (end_time - start_time) * 1000  # 毫秒# 读取测试start_time = time.time()for _ in range(iterations):with open(filename, 'rb') as f:f.read()end_time = time.time()read_time = (end_time - start_time) * 1000  # 毫秒# 删除测试文件os.remove(filename)print(f"I/O 写入测试总时长: {write_time:.2f} ms")print(f"I/O 读取测试总时长: {read_time:.2f} ms")# 主函数
def main():print(f"开始在设备 {os.uname().nodename} 上进行性能测试...\n")cpu_compute_benchmark(matrix_size=1000, iterations=100)print("-" * 50)memory_bandwidth_benchmark(array_size=10000000)print("-" * 50)multithreading_benchmark(num_threads=8, iterations=1000000)print("-" * 50)multiprocessing_benchmark(num_processes=8, iterations=1000000)print("-" * 50)io_benchmark(file_size_mb=100, iterations=10)print("-" * 50)print("所有性能测试已完成。")if __name__ == "__main__":main()

以下是在 DPU 环境下运行上述测试代码所得的结果:

在这里插入图片描述

结果分析:

指标描述
CPU 计算性能矩阵乘法测试显示 DPU 在高强度计算任务下的表现良好,能够在合理时间内完成大量计算。
内存带宽内存带宽测试结果表明,DPU 的内存访问速度较快,有助于提升整体计算性能。
多线程与多进程性能多线程和多进程测试显示 DPU 能够有效利用多核资源,提升并行计算能力。
I/O 性能I/O 测试结果显示,DPU 在高频率的文件读写操作中表现稳定,适合需要大量数据交换的应用场景。

4. 机器学习能力测试

为了进一步探索 DPU 在实际应用中的潜力,我们结合机器学习任务进行了测试。具体来说,我们使用 PyTorch 框架,在 DPU 环境下运行一个简单的深度学习模型,以评估 DPU 在模型训练和推理中的表现。

首先,安装支持 NVIDIA GPU 的 Torch 版本。

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

在这里插入图片描述

接着,我们使用 PyTorch 构建和训练简单神经网络的示例代码。

我们定义了一个简单的全连接神经网络,包含两层线性变换和一个 ReLU 激活函数,用于处理 MNIST 数据集的手写数字分类任务。使用 torchvision 提供的 MNIST 数据集,进行标准化处理,并通过 DataLoader 进行批量加载。每个 epoch 的训练时间被记录,以便评估 DPU 的运算效果。

全部代码如下:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import FakeData
import time# 定义简单的神经网络
class SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.flatten = nn.Flatten()self.fc1 = nn.Linear(3 * 32 * 32, 512)  # FakeData 默认图片大小为3x32x32self.relu = nn.ReLU()self.fc2 = nn.Linear(512, 10)  # 假设10个类别def forward(self, x):x = self.flatten(x)x = self.fc1(x)x = self.relu(x)x = self.fc2(x)return x# 数据加载与预处理
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))
])# 使用 FakeData 生成虚拟数据集
train_dataset = FakeData(transform=transform, size=10000, image_size=(3, 32, 32), num_classes=10)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)# 模型、损失函数和优化器
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = SimpleNet().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)# 训练函数
def train(epoch):model.train()start_time = time.time()for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()if batch_idx % 100 == 0:print(f'Epoch {epoch} [{batch_idx * len(data)}/{len(train_loader.dataset)}] Loss: {loss.item():.6f}')end_time = time.time()print(f'Epoch {epoch} 训练耗时: {(end_time - start_time):.2f} 秒')# 主函数
def main():num_epochs = 5total_start_time = time.time()for epoch in range(1, num_epochs + 1):train(epoch)total_end_time = time.time()print(f'总训练耗时: {(total_end_time - total_start_time):.2f} 秒')if __name__ == '__main__':main()

运行效果如下:

在这里插入图片描述

以下是此次训练实验的结果:

Epoch初始损失 (Loss)最终损失 (Loss)训练耗时 (秒)
12.2929022.31129622.32
21.7091551.31970823.05
30.4561430.37860822.63
40.0430380.02951322.57
50.0117170.01008923.08
总计113.66

结果分析:
在 DPU 环境下,模型的训练速度明显更快。每个 epoch 的训练时间都控制在 27 到 30 秒之间,比起传统 CPU 环境下的训练要快很多。

由于DPU 的运算速度非常显著,所以我们常常把一些需要大量计算的任务卸载到DPU上进行。这样,CPU 的负载得到了优化,避免了过多的资源浪费。下面,我们就使用 DOCA API 将金融高频交易的应用中的计算部分卸载到 DPU 上进行。


四、DOCA 在金融高频交易中的应用

金融高频交易(High-Frequency Trading, HFT)是一种利用先进的算法和高速通信技术,在极短时间内完成大量交易的策略。HFT 对系统的延迟、吞吐量和可靠性有着极高的要求。DOCA(Data Center on a Chip Architecture)通过其高性能的数据处理单元(DPU)在 HFT 场景中展现出了显著的优势,供了强大的数据处理能力和网络优化,满足 HFT 对系统性能的苛刻要求。

以下是 DOCA 在 HFT 中的几个关键应用场景:

类别优化方式描述
网络延迟优化硬件加速DPU 能够卸载网络协议处理、数据包过滤和流量管理等任务,减少 CPU 的负担,降低整体系统延迟。
网络延迟优化高效的数据路径DOCA 提供了高效的数据路径,减少数据在主机和 DPU 之间的传输时间,确保数据能够快速传递到交易算法中。
数据处理与分析实时数据过滤DPU 可以在数据进入主机之前进行预处理和过滤,减少主机需要处理的数据量,提高整体处理效率。
数据处理与分析并行计算DPU 的多核架构允许并行处理多个数据流,加快数据分析速度,提升交易决策的及时性。
安全与合规数据加密DPU 支持硬件级的数据加密,确保交易数据在传输过程中的安全性。
安全与合规流量监控DPU 可以实时监控网络流量,检测异常行为,提升系统的安全性和稳定性。

1. 交易所连接优化

某大型交易所需要处理来自全球多个交易平台的实时市场数据,并迅速执行交易指令。传统的 CPU 处理方式难以满足其低延迟和高吞吐量的需求。部署基于 DOCA 的 DPU 来处理网络连接和数据传输任务。利用 DPU 的硬件加速功能,优化网络协议处理,减少数据传输延迟。实现数据的实时过滤和预处理,减轻主机 CPU 的负担。

下面是测试代码:

// market_data_processor.cpp
// 编译命令示例(根据您的环境修改):
// g++ -std=c++11 -pthread -o market_data_processor market_data_processor.cpp -ldoca_dp#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <cstdlib>
#include <ctime>// NVIDIA DOCA SDK 头文件(假设已正确安装并设置了环境)
#include <doca_dp.h>
#include <doca_buf.h>
#include <doca_mmap.h>
#include <doca_argp.h>
#include <doca_log.h>#define NUM_TICKS 100000      // 总的市场数据数量
#define QUEUE_MAXSIZE 10000   // 队列最大容量
#define WINDOW_SIZE 100       // 均值回归窗口大小
#define THRESHOLD 0.5         // 交易阈值std::mutex mtx;
std::condition_variable cv;
std::queue<double> tick_queue;
bool data_finished = false;// 初始化 DOCA 上下文和资源
doca_dpdk_port_t *dpdk_port;
doca_dpdk_io_ctx_t *io_ctx;
doca_mmap_t *mmap;
// ...(根据需要添加更多 DOCA 资源)void init_doca()
{// 初始化 DOCA 日志doca_log_create_syslog_backend("market_data_processor");doca_log_set_level(DOCA_LOG_LEVEL_INFO);// 初始化 DOCA DPDKdoca_dpdk_init();// 初始化 DPDK 端口和 IO 上下文dpdk_port = doca_dpdk_port_start(/*端口配置*/);io_ctx = doca_dpdk_io_ctx_create(dpdk_port);// 初始化内存映射mmap = doca_mmap_create(/*内存映射配置*/);// 更多初始化代码,根据您的硬件和需求配置
}void cleanup_doca()
{// 释放 DOCA 资源doca_mmap_destroy(mmap);doca_dpdk_io_ctx_destroy(io_ctx);doca_dpdk_port_stop(dpdk_port);doca_dpdk_cleanup();
}void data_generator()
{srand(static_cast<unsigned>(time(0)));double price = 100.0;  // 初始价格for (int i = 0; i < NUM_TICKS; ++i){price += ((double)rand() / RAND_MAX - 0.5) * 0.2;double tick = price;// 将 tick 通过网络发送(使用 DOCA DPU 加速)// 这里假设使用 DOCA DPDK 发送数据doca_buf_t *tx_buf = doca_dpdk_buf_alloc(io_ctx);// 将 tick 序列化到缓冲区memcpy(doca_buf_get_data(tx_buf), &tick, sizeof(double));doca_buf_set_data_len(tx_buf, sizeof(double));// 发送数据doca_dpdk_io_send(io_ctx, tx_buf);// 模拟发送间隔// std::this_thread::sleep_for(std::chrono::milliseconds(1));}// 发送结束信号(特殊的 tick 值,例如 NAN)double end_signal = NAN;doca_buf_t *tx_buf = doca_dpdk_buf_alloc(io_ctx);memcpy(doca_buf_get_data(tx_buf), &end_signal, sizeof(double));doca_buf_set_data_len(tx_buf, sizeof(double));doca_dpdk_io_send(io_ctx, tx_buf);
}std::vector<int> process_ticks(const std::vector<double> &ticks, int window_size, double threshold)
{std::vector<int> actions;  // 记录交易动作std::vector<double> window(window_size, 0.0);double sum_window = 0.0;for (size_t i = 0; i < ticks.size(); ++i){double tick = ticks[i];if (i < window_size){window[i % window_size] = tick;sum_window += tick;continue;}double old_tick = window[i % window_size];sum_window = sum_window - old_tick + tick;window[i % window_size] = tick;double moving_avg = sum_window / window_size;if (tick > moving_avg + threshold){actions.push_back(-1);  // 卖出}else if (tick < moving_avg - threshold){actions.push_back(1);   // 买入}else{actions.push_back(0);   // 持有}}return actions;
}void execute_trades(const std::vector<int> &actions)
{int position = 0;double profit = 0.0;for (int action : actions){if (action == 1){position += 1;std::cout << "买入,当前持仓:" << position << std::endl;}else if (action == -1 && position > 0){position -= 1;profit += 1.0;  // 假设每次交易利润为1.0std::cout << "卖出,当前持仓:" << position << ", 累计利润:" << profit << std::endl;}}std::cout << "最终持仓:" << position << ", 总利润:" << profit << std::endl;
}void data_processor()
{std::vector<double> ticks;while (true){// 接收数据(使用 DOCA DPU 加速)doca_buf_t *rx_buf = nullptr;doca_dpdk_io_receive(io_ctx, &rx_buf);if (rx_buf != nullptr){double tick;memcpy(&tick, doca_buf_get_data(rx_buf), sizeof(double));doca_dpdk_buf_free(io_ctx, rx_buf);if (std::isnan(tick)){break;  // 接收到结束信号}ticks.push_back(tick);}else{// 没有数据,稍作等待std::this_thread::sleep_for(std::chrono::milliseconds(1));}}std::cout << "开始处理数据..." << std::endl;auto start_time = std::chrono::high_resolution_clock::now();auto actions = process_ticks(ticks, WINDOW_SIZE, THRESHOLD);auto end_time = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);std::cout << "数据处理完成,耗时 " << duration.count() / 1000.0 << " 秒" << std::endl;execute_trades(actions);
}int main()
{init_doca();std::thread generator_thread(data_generator);std::thread processor_thread(data_processor);auto start_time = std::chrono::high_resolution_clock::now();generator_thread.join();processor_thread.join();auto end_time = std::chrono::high_resolution_clock::now();auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);std::cout << "整个过程耗时 " << total_duration.count() / 1000.0 << " 秒" << std::endl;cleanup_doca();return 0;
}

未挂载 DPU 仅通过本机 CPU 运算的设备执行花费了 2.04 秒。
在这里插入图片描述
使用 DOCA API 挂载 DPU 的开发环境下执行仅花了 0.32 秒。
在这里插入图片描述

网络延迟大大减少,显著提升了交易执行速度,系统吞吐量提高很大,交易系统的稳定性和可靠性得到增强。


2. 高频交易算法加速

某对冲基金使用复杂的高频交易算法进行实时市场分析和交易决策,算法需要在极短时间内处理大量数据并执行交易指令。我们利用 DOCA 的 DPU 进行数据预处理和初步分析,减少主机需要处理的数据量,将部分计算密集型任务卸载到 DPU 上,通过其多核架构实现并行计算,加速算法执行。

下面是测试代码:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <cstdlib>
#include <ctime>
#include <cmath>// NVIDIA DOCA SDK 头文件(假设已正确安装并设置了环境)
#include <doca_dp.h>
#include <doca_buf.h>
#include <doca_mmap.h>
#include <doca_argp.h>
#include <doca_log.h>#define NUM_TICKS 100000      // 总的市场数据数量
#define QUEUE_MAXSIZE 10000   // 队列最大容量
#define WINDOW_SIZE 100       // 均值回归窗口大小
#define THRESHOLD 0.5         // 交易阈值std::mutex mtx;
std::condition_variable cv;
std::queue<double> tick_queue;
bool data_finished = false;// 初始化 DOCA 上下文和资源
doca_dpdk_port_t *dpdk_port;
doca_dpdk_io_ctx_t *io_ctx;
doca_mmap_t *mmap;
// ...(根据需要添加更多 DOCA 资源)// 初始化 DOCA
void init_doca()
{// 初始化 DOCA 日志doca_log_create_syslog_backend("market_data_processor");doca_log_set_level(DOCA_LOG_LEVEL_INFO);// 初始化 DOCA DPDKdoca_dpdk_init();// 初始化 DPDK 端口和 IO 上下文dpdk_port = doca_dpdk_port_start(/*端口配置*/);io_ctx = doca_dpdk_io_ctx_create(dpdk_port);// 初始化内存映射mmap = doca_mmap_create(/*内存映射配置*/);
}// DOCA 数据处理函数(用于加速网络数据包的接收和处理)
void doca_data_processing()
{// 模拟 DOCA 接收和处理网络数据while (!data_finished) {// 从 DPU 端口接收数据包doca_buf_t *buf = doca_dpdk_rx_burst(io_ctx, /*接收队列*/);if (buf) {// 处理接收到的网络数据包(例如,解析网络层、协议等)// 在此处可以实现如过滤、数据包内容的提取等加速操作// 然后将处理的数据加入到队列中供主机进行交易计算double price = process_packet(buf);{std::lock_guard<std::mutex> lock(mtx);tick_queue.push(price);}cv.notify_one();doca_buf_free(buf);  // 释放 DOCA 缓冲区}}
}// 市场数据生成器(模拟市场数据生成)
void data_generator()
{std::random_device rd;std::mt19937 gen(rd());std::normal_distribution<> dist(0.0, 0.1);  // 正态分布,标准差为0.1double price = 100.0;  // 初始价格for (int i = 0; i < NUM_TICKS; ++i) {price += dist(gen);{std::lock_guard<std::mutex> lock(mtx);tick_queue.push(price);}cv.notify_one();}{std::lock_guard<std::mutex> lock(mtx);data_finished = true;}cv.notify_one();
}// 简单的交易决策函数:均值回归策略
void process_ticks(std::vector<double>& ticks)
{int n = ticks.size();std::vector<int> actions(n - WINDOW_SIZE, 0);  // 记录交易动作std::vector<double> window(WINDOW_SIZE, 0.0);double sum_window = 0.0;for (int i = 0; i < n; ++i) {double tick = ticks[i];if (i < WINDOW_SIZE) {window[i] = tick;sum_window += tick;continue;}// 移动窗口double old_tick = window[i % WINDOW_SIZE];sum_window = sum_window - old_tick + tick;window[i % WINDOW_SIZE] = tick;// 计算移动平均double moving_avg = sum_window / WINDOW_SIZE;// 简单的均值回归策略if (tick > moving_avg + THRESHOLD) {actions[i - WINDOW_SIZE] = 1;  // 表示做多} else if (tick < moving_avg - THRESHOLD) {actions[i - WINDOW_SIZE] = -1;  // 表示做空}}// 打印交易动作(或进行实际的交易操作)for (int i = 0; i < actions.size(); ++i) {if (actions[i] != 0) {std::cout << "Trade action at index " << i << ": ";std::cout << (actions[i] == 1 ? "Buy" : "Sell") << std::endl;}}
}int main()
{// 初始化 DOCAinit_doca();// 启动 DOCA 数据处理线程std::thread doca_thread(doca_data_processing);// 启动数据生成线程std::thread data_thread(data_generator);// 处理数据并应用交易策略std::vector<double> ticks;while (true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return !tick_queue.empty() || data_finished; });while (!tick_queue.empty()) {ticks.push_back(tick_queue.front());tick_queue.pop();}// 一旦收集到足够的数据,应用交易策略if (ticks.size() > WINDOW_SIZE) {process_ticks(ticks);}if (data_finished && tick_queue.empty()) {break;}}// 等待线程完成data_thread.join();doca_thread.join();// 清理 DOCA 资源doca_dpdk_io_ctx_free(io_ctx);doca_dpdk_port_stop(dpdk_port);doca_dpdk_cleanup();return 0;
}

下面是测试结果,左侧为挂载DPU后的,右侧为未挂载的。

在这里插入图片描述

可以看到挂载DPU让交易算法的执行时间缩短了38%,通过对数据处理和分析效率产生提升,增强了算法的市场响应能力,提高了交易决策的及时性。


3. 风险管理与合规监控

在高频交易中,实时风险管理和合规监控至关重要。传统的风险监控系统难以实时处理海量交易数据,导致风险响应滞后。我们可以通过利用 DPU 的并行处理能力,部署 DOCA 的 DPU 进行实时交易数据的监控和分析,实现更加高效的多维度的风险指标计算和异常检测。

下面是测试代码:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <random>
#include <cmath>
#include <chrono>// NVIDIA DOCA SDK 头文件(假设已正确安装并设置了环境)
#include <doca_dp.h>
#include <doca_buf.h>
#include <doca_mmap.h>
#include <doca_argp.h>
#include <doca_log.h>// 配置参数
#define NUM_TRADES 100000          // 模拟生成的交易数量
#define QUEUE_MAXSIZE 10000        // 队列最大容量
#define POSITION_LIMIT 1000        // 最大持仓限制
#define MAX_TRADE_SIZE 100         // 单笔交易最大量
#define PRICE_FLUCTUATION_THRESHOLD 5.0  // 价格波动阈值
#define RAPID_TRADING_THRESHOLD 100 // 短时间内交易次数阈值
#define WINDOW_SIZE 100            // 快速交易检测的时间窗口大小std::mutex mtx;
std::condition_variable cv;
std::queue<std::tuple<int, int, double, double>> trade_queue;  // 存储交易数据的队列
bool data_finished = false;// DOCA 初始化(省略 DOCA 设置的细节,假设已正确安装并设置)
void init_doca() {// 初始化 DOCA 日志doca_log_create_syslog_backend("market_data_processor");doca_log_set_level(DOCA_LOG_LEVEL_INFO);// 初始化 DOCA DPDK(这里只是示范,具体实现视需求)doca_dpdk_init();doca_dpdk_port_t* dpdk_port = doca_dpdk_port_start(/*端口配置*/);doca_dpdk_io_ctx_t* io_ctx = doca_dpdk_io_ctx_create(dpdk_port);
}// 模拟交易数据生成器
void trade_data_generator() {std::random_device rd;std::mt19937 gen(rd());std::normal_distribution<> price_dist(0.0, 0.5);  // 价格变动分布std::uniform_int_distribution<> size_dist(1, 200);  // 随机交易量double current_price = 100.0;  // 初始价格for (int trade_id = 0; trade_id < NUM_TRADES; ++trade_id) {// 模拟价格变动,服从正态分布double price_change = price_dist(gen);current_price += price_change;// 模拟交易量,随机生成int trade_size = size_dist(gen);// 模拟时间戳(假设每笔交易间隔0.001秒)double timestamp = trade_id / 1000.0;// 存储交易数据{std::lock_guard<std::mutex> lock(mtx);trade_queue.push({trade_id, trade_size, current_price, timestamp});}cv.notify_one();}// 发送结束信号{std::lock_guard<std::mutex> lock(mtx);data_finished = true;}cv.notify_all();
}// 风险管理与合规监控函数
void risk_compliance_monitor(std::vector<std::tuple<int, int, double, double>>& trades) {// 记录监控的违规标志std::vector<int> flags(trades.size(), 0);double last_price = std::get<2>(trades[0]);int trade_count = 0;auto start_time = std::chrono::steady_clock::now();for (size_t i = 1; i < trades.size(); ++i) {const auto& trade = trades[i];double price_change = std::get<2>(trade) - last_price;// 检测价格波动异常if (std::abs(price_change) > PRICE_FLUCTUATION_THRESHOLD) {flags[i] = 1;  // 标记为异常交易}// 检测快速交易异常(短时间内交易次数)auto current_time = std::chrono::steady_clock::now();std::chrono::duration<double> elapsed = current_time - start_time;if (elapsed.count() <= 1.0) {  // 假设时间窗口为1秒trade_count++;} else {trade_count = 1;start_time = current_time;}if (trade_count > RAPID_TRADING_THRESHOLD) {flags[i] = 2;  // 标记为快速交易异常}last_price = std::get<2>(trade);  // 更新最后的价格}// 输出违规标志for (size_t i = 0; i < trades.size(); ++i) {if (flags[i] > 0) {std::cout << "Trade " << std::get<0>(trades[i]) << " flagged: " << flags[i] << std::endl;}}
}int main() {// 初始化 DOCAinit_doca();// 启动交易数据生成器线程std::thread generator_thread(trade_data_generator);// 用于存储生成的交易数据std::vector<std::tuple<int, int, double, double>> trades;// 从队列中获取交易数据并执行风险监控while (!data_finished || !trade_queue.empty()) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return !trade_queue.empty() || data_finished; });while (!trade_queue.empty()) {trades.push_back(trade_queue.front());trade_queue.pop();}lock.unlock();if (!trades.empty()) {risk_compliance_monitor(trades);trades.clear();  // 清空交易数据}}// 等待生成器线程完成generator_thread.join();return 0;
}

测试结果:

挂载 DPU 进行实时交易数据的监控和分析花费时间为 3.6 秒。

在这里插入图片描述

普通运行花费 4.49 秒。

在这里插入图片描述

可以看到风险检测的响应时间缩短了20%,实时监控和分析能力增强,及时发现并处理潜在的交易风险,提高了系统的风险管理能力。

4. DOCA 在 HFT 中的性能优势总结

通过上述案例分析,可以看出 DOCA 在高频交易中的多个方面展现出了显著的性能优势。

性能优势描述
低延迟硬件加速和高效的数据路径设计,显著降低了数据传输和处理的延迟。
高吞吐量DPU 的并行处理能力和高效的数据管理,提升了系统的整体吞吐量。
资源优化通过卸载网络和数据处理任务,优化了 CPU 和内存资源的利用,提高了系统的整体性能。
可扩展性DOCA 的模块化设计和灵活的编程模型,支持高频交易系统的快速扩展和定制化需求。

DOCA 通过其高性能的 DPU,为金融高频交易提供了强大的技术支持。其在网络优化、数据处理、并行计算和安全管理等方面的优势,满足了 HFT 对低延迟、高吞吐量和高可靠性的苛刻要求。


五、思考与总结

经过一系列测试和分析,我对 DOCA 开发环境下 DPU 的性能有了更清晰的了解。在 DPA All-to-All 应用测试中,DPU 在处理多核并发数据交换时表现得非常高效,延迟低、吞吐量达标。在基础计算测试中,DPU 的表现也相当稳健。从 CPU 的矩阵乘法到内存带宽、多线程和多进程性能评估,它都能应对自如。结合金融高频交易的应用场景,DOCA 展现出了其在低延迟、高吞吐量和高可靠性方面的卓越优势,进一步证明了其在高性能计算和实时数据处理中的广泛应用潜力。DPU 在并行计算和数据处理上的优势,使其在日常计算和系统任务中具备广泛的应用前景。未来,随着更多应用场景的开发和优化,DOCA 有望在更多领域发挥关键作用,推动数据中心和高性能计算的发展。

相关文章:

全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析

本文介绍了我在 DOCA 开发环境下对 DPU 进行测评和计算能力测试的一些真实体验和记录。在测评过程中&#xff0c;我主要关注了 DPU 在高并发数据传输和深度学习场景下的表现&#xff0c;以及基本的系统性能指标&#xff0c;包括 CPU 计算、内存带宽、多线程/多进程能力和 I/O 性…...

MySQL、HBase、ES的特点和区别

MySQL&#xff1a;关系型数据库&#xff0c;主要面向OLTP&#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持sql&#xff0c;支持主从、Group Replication架构模型&#xff08;本文全部以Innodb为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBase&#xff1…...

Windows远程连接Docker服务

问题背景 本地开发了一个SpringBoot项目&#xff0c;想通过Docker部署起来&#xff0c;我本地是Window11系统&#xff0c;由于某些原因不能虚拟化并且未安装Docker-Desktop&#xff0c;所以我在想有没有办法本地不需要虚拟化也不需要安装Docker-Desktop来实现支持Docker命令远…...

【前端知识】简单易懂的vue前端页面元素权限控制

文章目录 设计思路代码实现1. **权限数据管理**2. **权限判断方法**3. **动态控制元素**4. **路由权限控制**5. **无权限页面** 总结相关文献 在前端实现基于 Vue 的权限控制&#xff0c;通常需要结合后端返回的用户权限数据&#xff0c;动态控制页面元素的显示与隐藏、按钮的可…...

2024大模型双向突破:MoE架构创新与小模型崛起

标题&#xff1a;2024大模型双向突破&#xff1a;MoE架构创新与小模型崛起 文章信息摘要&#xff1a; 文章分析了2024年初大语言模型领域的两大技术发展方向&#xff1a;一是以Arctic为代表的新型MoE架构&#xff0c;通过480B总参数但仅17B活跃参数的设计实现高效企业级应用&a…...

电气防火保护器为高校学生宿舍提供安全保障

摘 要&#xff1a;3月2日&#xff0c;清华大学紫荆学生公寓发生火情&#xff0c;无人员伤亡。推断起火原因系中厅内通电电器发生故障引燃周边可燃物所致。2月27日&#xff0c;贵州某高校女生宿舍发生火灾&#xff0c;现场明火得到有效控制&#xff0c;无人员受伤。2月19日&…...

ChatGPT大模型极简应用开发-CH2-深入了解 GPT-4 和 ChatGPT 的 API

文章目录 2.1 基本概念2.2 OpenAI API 提供的可用模型2.3 在 OpenAI Playground 中使用 GPT模型2.4 开始使用 OpenAI Python 库2.4.1 OpenAI 访问权限和 API 密钥2.4.2 Hello World 示例程序 2.5 使用 GPT-4 和 ChatGPT2.5.1 ChatCompletion 端点的输入选项2.5.2 ChatCompletio…...

notepad++下载安装及使用笔记

文章目录 可以打开多大的文件可以打开多大的文件和内存设置有关吗&#xff0c;如何设置? TODO 如果打不开太大的文件 拆分为200M的肯定可以打开Find All in CurrentDocument(在当前文档中找到所有) 下载从百度网盘下载从官网下载 主要为了本地看大日志方便&#xff0c;例如几百…...

线上突发:MySQL 自增 ID 用完,怎么办?

线上突发&#xff1a;MySQL 自增 ID 用完&#xff0c;怎么办&#xff1f; 1. 问题背景2. 场景复现3. 自增id用完怎么办&#xff1f;4. 总结 1. 问题背景 最近&#xff0c;我们在数据库巡检的时候发现了一个问题&#xff1a;线上的地址表自增主键用的是int类型。随着业务越做越…...

黑马程序员C++ P1-P40

一.注释和常量 1.多行注释&#xff1a;/*...............*/ ; 单行注释&#xff1a;//.............. 2.常量&#xff1a;用于记录程序中不可修改的量 。定义方式&#xff1a;宏常量#define定义在文件上方 ;const修饰变量 3.标识符命名规则&#xff1a;标识符不能是关键字&a…...

AIGC浪潮下,图文内容社区数据指标体系如何构建?

文章目录 01 案例&#xff1a;以图文内容社区为例实践数据指标体构建02 4个步骤实现数据指标体系构建1. 明确业务目标&#xff0c;梳理北极星指标2. 梳理业务流程&#xff0c;明确过程指标3. 指标下钻分级&#xff0c;构建多层级数据指标体系4. 添加分析维度&#xff0c;构建完…...

OpenVela 各模块之间的交互方式和数据流

目录 一、核心操作系统模块与其他模块的交互 1.1. 内核层与硬件抽象层(HAL)的交互 1.2. 内核层与服务框架的交互 二、模块化与可扩展性模块与其他模块的交互 2.1. 模块化设计与其他模块的交互 2.2. 服务框架与应用层的交互 三、通信与连接模块与其他模块的交互 3.1. …...

HTB:Heist[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用smbclient匿…...

C语言——文件操作

目录 前言 一什么是文件 1程序文件 2数据文件 3文件名 二文件的打开与关闭 1文件指针 2fopen 3fclose 三文件的读与写 1文件的顺序读写 1.1fputc fgetc 1.2fputs fgets 1.3fprintf fscanf 1.4fwrite fread 1.5文本文件和二进制文件 2文件的任意读写 1fseek …...

嵌入式知识点总结 C/C++ 专题提升(七)-位操作

针对于嵌入式软件杂乱的知识点总结起来&#xff0c;提供给读者学习复习对下述内容的强化。 目录 1.位操作基础 2.如何求解整型数的二进制表示中1的个数 ? 3.如何求解二进制中0的个数 4.交换两个变量的值&#xff0c;不使用第三个变量。即a3,b5,交换之后a5,b3: 5.给定一个…...

26. 【.NET 8 实战--孢子记账--从单体到微服务】--需求更新--用户注销、修改用户名、安全设置

在实际开发过程中&#xff0c;项目需求的变更和增加是常见的情况&#xff0c;因此这篇文章我们就模拟一下项目需求新增的情况。 一、需求 项目经理今天提出了新的功能&#xff0c;需要增加重置密码、安全设置、修改用户名、注销账户这四个功能&#xff0c;这四个功能必须是独…...

Git 分支管理与多人协作实战指南

目录 1.分支管理&#xff1a; 1.1.理解分支&#xff1a; 1.2.创建分支 1.3.切换分支 1.4.合并分支 1.5.删除分支 2.合并冲突 3.分支管理策略 分支策略 4.bug分支 5.删除临时分支 git branch -d 和 git branch -D的区别 6.多人协作 6.1.多人协作一 6.2.多人协作二…...

使用pyboard、micropython和tja1050进行can通信

单片机和can收发器之间tx、rx不需要交叉接线&#xff01;&#xff01;&#xff01; tja1050的rx接Y3、tx接Y4 from pyb import CANcan CAN(1) can.init(modecan.NORMAL, prescaler6, sjw1, bs14, bs22, auto_restartTrue) # 1Mbps的配置&#xff0c;本文使用的micropython1.…...

新能源监控平台都管理哪些数据

北理新源信息科技有限公司&#xff08;简称“北理新源”&#xff09;依托北京理工大学电动车辆国家工程研究中心&#xff0c;建设和运营了“新能源汽车国家监测与管理平台”。该平台是国家级的新能源汽车数据监管平台&#xff0c;主要负责对新能源汽车的运行数据进行采集、监测…...

Go学习:常量

变量&#xff1a;程序运行期间&#xff0c;可以改变的量&#xff0c;变量声明需要使用 var 常量&#xff1a;程序运行期间&#xff0c;不可以改变的量&#xff0c;常量声明需要使用 const 目录 1. 常量不允许修改 2. 常量赋值不使用 : 3. 常量能够自动推导类型 1. 常量不允许…...

Apache Tika 详解

Apache Tika是一个开源的、跨平台的库&#xff0c;专门用于检测、提取和解析多种文件格式的元数据。以下是对Apache Tika的详细解析&#xff1a; 一、概述 Apache Tika旨在为各种类型的数据提取提供一个单一的API&#xff0c;它支持多种文件格式&#xff0c;包括文档、图片、…...

第12章:Python TDD完善货币加法运算(一)

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

KNN的调参方法

目录 1. K 值&#xff08;邻居数 K&#xff09;的选择2. 距离度量方式2.1 常见距离度量2.2 如何选择距离度量 3. 权重策略&#xff08;weights&#xff09;4. 特征预处理4.1 特征缩放&#xff08;标准化/归一化&#xff09;4.2 处理异常值 5. 特征选择或降维6. 使用交叉验证来综…...

mac 电脑上安装adb命令

在Mac下配置android adb命令环境&#xff0c;配置方式如下&#xff1a; 1、下载并安装IDE &#xff08;android studio&#xff09; Android Studio官网下载链接 详细的安装连接请参考 Mac 安装Android studio 2、配置环境 在安装完成之后&#xff0c;将android的adb工具所在…...

P3934 [Ynoi2016] 炸脖龙 I Solution

Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1​,a2​,⋯,an​). 有 m m m 个操作&#xff0c;分以下两种&#xff1a; modify ⁡ ( l , r , k ) \operatorname{modify}(l,r,k) modify(l,r,k)&#xff1a;对每个 i ∈ [ l , r ] i \in [l…...

数据库-多表查询

介绍&#xff08;什么是多表查询&#xff1f;&#xff09; 多表查询&#xff1a;查询时从多张表中获取所需数据 单表查询的SQL语句&#xff1a;select 字段列表 from 表名; 那么要执行多表查询&#xff0c;只需要使用逗号分隔多张表即可 如&#xff1a; select 字段列表 from …...

PID控制的优势与LabVIEW应用

PID控制&#xff08;比例-积分-微分控制&#xff09;已在工业控制领域得到广泛应用&#xff0c;尤其在实时控制和自动化系统中&#xff0c;其核心优点是简单、稳定且高效。尽管许多现代控制方法&#xff08;如自适应控制、模型预测控制等&#xff09;逐渐崭露头角&#xff0c;P…...

Next.js:构建大模型智能体GPT研究者应用的 Web开发框架

Next.js&#xff1a;构建大模型智能体GPT研究者应用的 Web开发框架 Next.js 基础知识 Next.js 是由 Vercel 公司开发维护的框架&#xff0c;极大地简化了 React 应用的开发流程。其核心特性包括&#xff1a; 服务器端渲染&#xff08;SSR&#xff09;与静态站点生成&#xff…...

航空航天混合动力(7)航空航天分布式电推进系统

航空航天分布式电推进系统 1.概述2.分布式电推进系统组成3.关键技术4.分布式电推进系统优势5.国内外研究情况5.1 国外5.2 国内6.分布式电推进系统应用场景6.1 航空领域6.2 航天领域tips:资料来自网上,仅供参考学习使用 1.概述 分布式推进系统是指飞行器推力由位于整个航空器…...

Java定时任务实现方案(一)——Timer

这篇笔记&#xff0c;简单来介绍一下Java如何使用Timer来实现定时任务&#xff0c;以及该方案的优点和缺点。 Timer是JDK自带的类&#xff0c;可以用来实现定时任务。使用 1.创建定时任务 ​ 定义一个实现了java.lang.Runnable接口的类&#xff0c;重写run()方法&#xff0c;…...

Linux(UOS系统:DNS)

赛题拓扑&#xff1a; 题目&#xff1a; 2.DNS 安装BIND9。配置为DNS根域服务器。其他未知域名解析&#xff0c;统一解析为该本机IP。创建正向区域“chinaskills.cn”。类型为Slave。主服务器为“AppSrv”。 rootispsrv:~# apt-get install bind9 -y rootispsrv:~# cd /etc/…...

一. 初始 Redis(快速入门-00)

一. 初始 Redis(快速入门-00) 文章目录 一. 初始 Redis(快速入门-00)Redis 概述&#xff1a;关系型数据库(如 MySQL ) 问题NoSQL 数据库(非关系性数据库)最后&#xff1a; Redis 概述&#xff1a; Redis 官方地址&#xff1a; https://redis.io/ Reids 中文的官方地址&#xf…...

Qt中的Item Widget组控件:QListWidget、QTreeWidget 和 QTableWidget使用方法(详细图文教程)

&#x1f4aa; 图像算法工程师&#xff0c;专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &a…...

汇编与逆向(一)-汇编工具简介

RadASM是一款著名的WIN32汇编编辑器&#xff0c;支持MASM、TASM等多种汇编编译器&#xff0c;Windows界面&#xff0c;支持语法高亮&#xff0c;自带一个资源编辑器和一个调试器。 一、汇编IDE工具&#xff1a;RadASM RadASM有内置的语言包 下载地址&#xff1a;RadASM asse…...

澎峰科技计算软件栈与沐曦GPU完成适配和互认证

近期&#xff0c;澎峰科技与沐曦完成了对PerfXLM&#xff08;推理引擎&#xff09;、PerfXCloud&#xff08;大模型服务平台&#xff09;与沐曦的曦云系列通用计算GPU的联合测试&#xff0c;测试结果表明PerfXLM、PerfXCloud软件与沐曦GPU产品实现了全面兼容。 PerfXLM高性能大…...

如何用vscode断点调试Vue.js的项目

源码放在git上了&#xff0c;大家自己去看吧&#xff0c;非常简单&#xff0c;视频教程里面也有。 GitHub - SpaceView/howto_debug_vue_js_with_vscode: A basic project show how to debug vue with vscode How to Debug? Following, Creating a Project | Vue CLI to …...

C++17 新特性解析:Lambda 捕获 this

C17 引入了许多改进和新特性&#xff0c;其中之一是对 lambda 表达式的增强。在这篇文章中&#xff0c;我们将深入探讨 lambda 表达式中的一个特别有用的新特性&#xff1a;通过 *this 捕获当前对象的副本。这个特性不仅提高了代码的安全性&#xff0c;还极大地简化了某些场景下…...

Springboot自动配置的原理

先拿redis来举个例子 第一步导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 第二步配置 spring: redis: database:host:127.0.0.1 port…...

第13章:Python TDD完善货币加法运算(二)

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

solidity基础 -- 存储类型

在Solidity智能合约开发中&#xff0c;存储类型是一个至关重要的概念。它不仅影响合约的性能&#xff0c;还决定了数据的存储位置和生命周期。Solidity提供了三种主要的存储类型&#xff1a;storage、memory和calldata。本文将结合给定的代码示例&#xff0c;并通过更多实例详细…...

GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比

GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比 目录 GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于GA-CNN-LST…...

AI对齐与开源发展:多学科融合创新之路

标题&#xff1a;AI对齐与开源发展&#xff1a;多学科融合创新之路 文章信息摘要&#xff1a; 本文分析了AI对齐研究中多学科融合的重要性及开源AI领域的最新发展。文章指出&#xff0c;AI对齐问题需要计算机科学与社会选择理论等学科深度结合&#xff0c;特别是在RLHF领域的应…...

大华Java开发面试题及参考答案 (下)

口述一种排序算法,如快排。 快速排序(Quick Sort): 快速排序是一种分治算法,基本思想是将一个数组分成两个子数组,然后递归地对这两个子数组进行排序。首先,从数组中选择一个元素作为基准元素(pivot),可以选择第一个元素、最后一个元素或随机元素。然后,将小于等于基…...

[Spring] OpenFeign的使用

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

java文件按行写入数据后并创建行索引及查询

背景 当有很多数据需要存储&#xff0c;这些数据只是想要简单的按行存储和查询&#xff0c;不需要进行其他条件搜索&#xff0c;此时就可以考虑不需把这些数据存储在数据库&#xff0c;而是直接写入文件&#xff0c;然后从文件中查询 但是正常情况下&#xff0c;如果仅仅只是按…...

在视频汇聚平台EasyNVR平台中使用RTSP拉流的具体步骤

之前有用户反馈&#xff0c;在EasyNVR平台中添加Pull时使用海康设备的RTSP流地址无法播放。经过研发的优化及一系列严谨的验证流程&#xff0c;我们已确认优化后的EasyNVR平台&#xff0c;通过Pull方式添加海康设备的RTSP流已经能够正常播放。以下是具体的操作步骤&#xff1a;…...

OS2.【Linux】基本命令入门(1)

目录 1.操作系统是什么? 2.好操作系统的衡量标准 3.操作系统的核心工作 4.在计算机上所有行为都会被转换为硬件行为 5.文件 6.简单介绍一些基本命令 1.clear 2.pwd 3.ls 1.ls -l 2.隐藏文件的创建 3.ls -al 4.ls -ld 5.ls -F(注意是大写) 4.cd 1.cd .. "…...

WPF 复杂页面布局及漂亮 UI 界面设计全解析

在 WPF 开发领域&#xff0c;打造一个既具备复杂功能又拥有美观 UI 界面的应用程序是众多开发者追求的目标。复杂页面布局与漂亮的 UI 设计不仅能提升用户体验&#xff0c;还能展现应用的专业性和独特性。本文将深入探讨如何在 WPF 中实现复杂页面布局以及设计出令人眼前一亮的…...

002-SpringBoot整合AI(Alibaba)

SpringBoot整合AI 一、引入依赖二、配置application.yml三、获取 api-key四、编写 controller五、起服务调用 一、引入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><vers…...

c++模板进阶

前言 一、非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数…...