Python的ACM模式输出入
输入 1. 单行输入多个整数 12nums = list(map(int, input().split()))print(sum(nums)) 2.多行输入(行数n未知) 12345678910111213# 方法1while True: try: nums = list(map(int, input().split())) print(sum(nums)) except EOFError: break# 方法2import sysfor line in sys.stdin: nums = list(map(int, line.split())) print(sum(nums)) 3.多行输入(行数n已知) 1234t = int(input())for _ in range(t): nums = list(map(int, input().split())) print(sum(nums)) 4. 多个测试用例,每个测试用例包含多行数据 123456t = int(input())for _ in...
常用设计模式讲解
单例设计模式 ⭐ 定义 单例模式是一种创建型设计模式,它的核心思想是保证一个类只有一个实例,并提供一个全局访问点来访问这个实例。 优点 1.全局控制:保证只有一个实例,这样就可以严格的控制客户怎样访问它以及何时访问它,简单的说就是对唯一实例的受控访问。 2. 节省资源:也正是因为只有一个实例存在,就避免多次创建了相同的对象,从而节省了系统资源,而且多个模块还可以通过单例实例共享数据。 3. 懒加载:单例模式可以实现懒加载,只有在需要时才进行实例化,这无疑会提高程序的性能。 基本要求(规则) 私有的构造函数:防止外部代码直接创建类的实例。 私有的静态实例变量:保存该类的唯一实例。 公有的静态方法:通过公有的静态方法来获取类的实例。 种类 饿汉模式 不管是否需要使用这个实例,直接先创建好实例,然后当需要使用的时候,直接调方法就可以使用了。 1234567891011121314151617class Singleton{private: // 静态成员变量在类加载时初始化 static Singleton...
常见手撕算子——一维数组的softmax
SoftMax Softmax 的 CPU 和 CUDA 写法均是高频考察。面试时有可能会让任选一种写法进行书写,此时自己可以先写 CPU(C++、Python) 版本,然后再写 CUDA 版本。 Softmax公式如下:softmax(xi)=exi∑jexjsoftmax(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}} softmax(xi)=∑jexjexi 一般为了避免溢出,需要减去最大值,所以通常采用下面这个公式:softmax(xi)=exi−max(x)∑jexj−max(x)softmax(x_i) = \frac{e^{x_i - max(x)}}{\sum_j e^{x_j - max(x)}} softmax(xi)=∑jexj−max(x)exi−max(x) 1. CPU(C++、Python) 版本 1234567891011void softmax(float* input, float* output, int N){ float max_value =...
常见手撕算子-elementwise
elementwise elementwise 是最简单的一类算子,其指的是对数据进行逐元素操作,例如将两个等长的数组对应元素相加(add)。另外在深度学习中,激活函数会对输入数据的每个元素求对应激活值,故激活函数也算在 elementwise 范围内。 add 1234567891011121314151617181920212223242526272829303132333435363738394041// 1. 向上取整#define CEIL(a, b) ((a + b - 1) / (b))// 2. FLOAT4,用于向量化访存,以下两种都可以// c写法#define FLOAT4(value) *(float4*)(&(value))// c++写法#define FLOAT4(value) (reinterpret_cast<float4*>(&(value))[0])//naive版int block_size = 1024;int grid_size = CEIL(N,...
常见手撕算子-reduce
Reduce 算子是指通过对数组中的每个元素进行操作,得到一个输出值的过程。常见的操作包括求和(sum)、取最大值(max)、取最小值(min)等。在 CUDA 中,优化 Reduce 算子可以显著提高计算效率。 1. naive实现 1234567//累加__global__ void reduce_v0(float* d_in, float* d_out, int N) { int idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < N) { atomicAdd(d_out, d_in[idx]); }} 2. 使用warp级并行进行数组归约 12345678910111213141516171819202122232425262728293031323334353637383940414243444546#include <cuda_runtime.h>#include...
常见手撕算子——sgemm(单精度矩阵乘法)
1. cpu: 矩阵乘法 1234567891011121314151617181920212223242526272829// 二维矩阵void matrixMultiply(const float** A, const float** B, float** C, int m, int p, int n) { // A is m x p, B is p x n, C is m x n for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { float sum = 0.0; for (int k = 0; k < p; ++k) { sum += A[i][k] * B[k][j]; } C[i][j] = sum; } }}// 二维矩阵展开成一维void...
常见手撕算子——transformer的softmax_matrix
1.cpu: 计算每行的softmax 12345678910111213141516void softmax_row(float* input, float* output, int M, int N) { for (int row = 0; row < M; row++) { // 第row行 float* input_tmp = input + row * N; float* output_tmp = output + row * N; float max_val = *(std::max_element(input_tmp, input_tmp + N)); // 计算输入数组的最大值 float sum = 0; for (int i = 0; i < N; i++) { output_tmp[i] = std::exp(input_tmp[i] - max_val); //...
常见手撕算子-transpose
naive版本 1234567__global__ void transpose_v0(float* input, float* output, int M, int N){ int row = blockIdx.y * blockDim.y + threadIdx.y; int col = blockIdx.x * blockDim.x + threadIdx.x; if(row < M && col < N){ output[col * M + row] = input[row * N + col]; }} 优化版本1:shared memory 思路: 先将数据从global memory拷贝到shared memory中 通过shared memory进行转置 通过shared memory将数据拷贝到global memory中 1234567891011121314151617template <int TILE_SIZE>__global__...
C++面试手撕题
使用C++实现一个读写锁 实现一个uniqued_ptr 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980#include <utility> // 用于std::movetemplate <typename T>class unique_ptr {private: T* ptr; // 指向管理的对象public: // 构造函数,接受原始指针 explicit unique_ptr(T* p = nullptr) : ptr(p) {} // 析构函数,释放管理的对象 ~unique_ptr() { delete ptr; } // 禁止拷贝构造函数(独占所有权不能被拷贝) ...
计算机网络八股文
第1章 计算机网络体系结构 第2章 物理层 第3章 数据链路层 第4章 网络层 NAT 的作用是什么? NAT(Network Address Translation,网络地址转换) 主要用于在不同网络之间转换 IP 地址。它允许将私有 IP 地址(如在局域网中使用的 IP 地址)映射为公有 IP 地址(在互联网中使用的 IP 地址)或者反向映射,从而实现局域网内的多个设备通过单一公有 IP 地址访问互联网。 NAT 不光可以缓解 IPv4...










