RHI_Shader Compare(HLSL、GLSL、MSL 、WGSL、OpenCL) Debug All

news2024/9/28 9:29:26

为了后续平台能够更好的封装跨平台Shader,本部分主要来看一下各平台Shader的语法特点、编译方式以及Debug方式等对比。
在这里插入图片描述

对于各类Shader语言还是先来看一下官方的文档,里边有具体的阐述,也是比较权威的文档:

  • HLSL官方文档
  • GLSL官方文档
  • MSL官方文档
  • WGSL官方文档
  • OpenCL官方文档

大家也可以去看看硬件执行着色器的具体原理,看完后你更是会恍然大悟,原来Shader中的每个数值都是根据硬件来匹配的,具体文章可以参照剖析虚幻渲染体系(16)- 图形驱动的秘密 、GPU架构与管线总结等等硬件架构相关文章,本文主要介绍应用层的相关原理。

我们先来看一下实时渲染中常用的着色器语言类别:

缩写名称全称图形API常用转换
HLSLHigh Level Shading LanguageDirectXHLSL → SPIR-V
GLSLOpenGL Shading LanguageVulkan / OpenGLGLSL → SPIR-V → HLSL
MSLMetal Shading LanguageMetalSPIR-V → MSL
WGSLWebGPU Shading LanguageWebGPUtint → SPIR-V

当然,除了上述常用着色器语言外,还有PlayStation Shading Language(PSL),Unity (Cg)等,此处便不一一介绍。

着色器语言因供应商和API不同语法虽有不同,但每种着色语言都与C语言非常相似,可以实现它们之间的切换。根据语言的不同,着色器代码可能存在特定于 API 的中间表示形式 (IR),并且每个供应商(AMD、NVIDIA、英特尔、高通等)在驱动程序级别将该 IR 转换为其机器代码。

IR描述适应API
DXILDirectX 中间语言DirectX 12
DXBCDirectX 字节码DirectX 11 / 12
SPIR-VVK、GL 中间语言Vulkan / OpenGL
RDNA2 ISAAMD 6000 系列指令集架构N/A
PTXNVIDIA并行线程执行N/A

我们主要来看一下 HLSL、GLSL、MSL 和 WGSL 中的顶点着色器语法(主要是布局等不同,TS、GS、PS大致相同):

  • 输入布局信息

  • 管线间数据传输

  • 常量缓冲数据

此外,我们还将介绍下每种语言的计算着色器语法:

  • 读取和写入缓冲区

  • 执行原子操作

  • 跨线程组共享数据

一、语言特点

几乎所有的着色语言都与 C 非常相似,并且具有与 C 相关的所有常见函数功能。

此外,着色语言具有全局命名空间中可用的内部函数标准库,用于执行常见的数学运算,这些标准功能包括:

  • 向量数学(矩阵乘法、向量加法、点积)。有些语言能够重载operator*,有些语言使用mul函数来执行计算;

  • 高阶运算(Sin,、Cos、tan、Log等);

  • 重载或者派生函数;

  • 逻辑操作(使用 all() 等函数检查布尔向量的所有成员);

  • GPGPU 显存同步,例如atomicAdd等

这些函数中的大多数函数名称相同,但有些略有不同(HLSL的与GLSL的),可以参照DirectX Shader Compiler (DXC)中的相关介绍、或者 Shader_GLSL、HLSL API异同对比

1.1 HLSL

High-Level Shading Language (HLSL) 高级着色语言可以说是编写着色器的最佳语言,因为它有这很好的语言拓展,也可以将采样器和纹理分开(与 GLSL 不同),并且支持以下通用语言功能:

  • 命名空间
  • 模板泛型
  • 可重载运算符(*)
  • #include

其余语言特性可以参照官方文章 HLSL 2021 。

有关 HLSL 语言的更多详细内容可以参照:

  • 内置变量与类型

  • 语义描述

  • 内置函数

VS Demo程序

//HLSL Vertex Shader

struct Constants
{
  row_major float4x4 modelViewProjection : packoffset(c0);
  float4x4 inverseTransposeModel : packoffset(c4);
  float4x4 view : packoffset(c8);
};

ConstantBuffer<Constants> constants : register(b0);

struct VertexInput
{
    float3 position : POSITION;
    float3 normal : NORMAL;
    float2 texCoord : TEXCOORD;
};

struct VertexOutput
{
    float4 position : SV_Position;
    float3 normal : NORMAL;
    float2 texCoord : TEXCOORD;

};

VertexOutput main(VertexInput vertexInput)
{
    float4 position = mul(float4(vertexInput.position, 1.0f), constants.modelViewProjection);
    float3 outNormal = mul(float4(vertexInput.normal, 1.0), constants.inverseTransposeModel).xyz;
    float2 outTexCoord = vertexInput.texCoord;

    VertexOutput output;
    output.position = position;
    output.normal = outNormal;
    output.texCoord = outTexCoord;

    return output;
}

如果需要使用全局可访问的着色器常量(如制服在旧 API 中的uniform变量),可以使用cbuffer关键字 ,使用demo如下:

cbuffer cb : register(b0)
{
    row_major float4x4 modelViewProjection : packoffset(c0);
    float3 origin : packoffset(c4);
    float time : packoffset(c5);
};

float4 position = mul(float4(vertexInput.position, 1.0f), modelViewProjection);

HLSL 着色器非常直观,具有输入和输出和明显的语义描述属性输入(如 float3 position : POSITION)。

现在看一下计算着色器的用法:

// HLSL Compute Shader
struct Constants
{
  float time : packoffset(c0);
};

ConstantBuffer<Constants> constants : register(b0);
Texture2D<float4> albedoTex : register(t1);
Texture2D<float4> pbrLutTex : register(t2);
SamplerState gSampler : register(s0);

RWTexture2D<float4> tOutput : register(u0);

groupshared float groupData[4];

namespace random
{
    float foo()
    {
        return 16.0;
    }
}

[numthreads(16, 16, 1)]
void main(uint3 groupThreadID : SV_GroupThreadID,
         uint3 groupID : SV_GroupID,
         uint  groupIndex : SV_GroupIndex,
         uint3 dispatchThreadID: SV_DispatchThreadID)
{
    tOutput[dispatchThreadID.xy] = float4( float(groupThreadID.x) / random::foo(), float(groupThreadID.y) / 16.0, dispatchThreadID.x / 1280.0, 1.0);
}

您可以将计算着色器内部值定义为 main 函数的参数,并有效的利用这些值来处理你想要的计算量,具体使用规则可以参照之前相关文章。

1.2 GLSL

OpenGL Shading Language (GLSL) 是 Khronos API 的标准着色器编程语言,例如 Vulkan、OpenGL 4.x,通过不同版本的 GLSL 和 WebGL 的可选扩展。但是GLSL 与其他语言之间存在一些本质区别:

  • 矢量类型前缀不一致(如,vec4 代替 float4 、mat4 代替 float4x4)

  • 采样器和纹理绑定在一起。

然而,GLSL在功能方面类似于HLSL,也支持通过可选扩展和类似#include的内部函数。

GLSL 代码以布局声明开头,这些布局声明准确定义每个结构和对象在内存中的布局方式。in 关键字表示此数据来自图形管线的输入程序集,out 关键字表示传递到图形管线下一步的数据(可以理解为传递引用)。

值得注意的是,GLSL ES 1.0适用于WebGL版本,GLSL ES 3.0可用于WebGL 2。

在main函数中,我们执行着色器逻辑并写入输出位置和可变变量。main关键字也可以设置为任何名称。

VS Demo程序

// GLSL Vertex Shader
#version 450

struct VertexInput
{
    vec3 position;
    vec3 normal;
    vec2 texCoord;
};

struct VertexOutput
{
    vec4 position;
    vec3 normal;
    vec2 texCoord;
};

struct Constants
{
    mat4 modelViewProjection;
    mat4 inverseTransposeModel;
    mat4 view;
};

layout(set = 0) uniform Constants constants;

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;

layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec2 outTexCoord;

void main()
{
    vec4 position =  constants.modelViewProjection * vec4(position, 1.0f);
    outNormal = (constants.inverseTransposeModel * vec4(normal, 1.0)).xyz;
    outTexCoord = texCoord;
    gl_Position = position;
}

计算着色器与 HLSL 大致相同,但是写入数据语法有点不一样,在HLSL中是通过数组语法完成,而GLSL则是通过函数来完成的。

具体可参见如下GLSL CS Shader:

// GLSL Compute Shader
#version 450
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;

layout(binding = 0, std140) uniform Constants
{
    float time;
} constants;

layout(binding = 0, rgba32f) uniform readonly writeonly image2D tOutput;

shared float groupData[4];

float foo()
{
    return 16.0;
}

void main()
{
    imageStore(tOutput, gl_GlobalInvocationID.xy,
               vec4(float(gl_SubgroupInvocationID.x) / foo(),
                    float(gl_SubgroupInvocationID.y) / 16.0,
                    gl_GlobalInvocationID.x / 1280.0, 1.0));
}

1.3 MSL

在Metal Shading Language (MSL) 中没有uniform关键字,缓冲区的所有内容都可以是uniform的。与 HLSL 类似,属性在 main 函数中作为参数传递,并使用指令来表示数据的来源与 HLSL 或 GLSL 不同,要传递到管道后期阶段的数据由 main 函数返回。

MSL中的向量类型的命名与HLSL相同,内部函数也几乎相同。

具体使用Demo如下:

// Metal Vertex Shader
#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Constants
{
    float4x4 modelViewProjection;
    float4x4 inverseTransposeModel;
    float4x4 view;
};

struct VertexOutput
{
    float3 normal [[user(locn0)]];
    float2 texCoord [[user(locn1)]];
    float4 position [[position]];
};

struct VertexInput
{
    float3 position [[attribute(0)]];
    float3 normal [[attribute(1)]];
    float2 texCoord [[attribute(2)]];
};

vertex VertexOutput main(VertexInput in [[stage_in]],
                         constant Constants& constants [[buffer(0)]],
                         uint gl_VertexID [[vertex_id]],
                         uint gl_InstanceID [[instance_id]])
{
    VertexOutput out = {};
    float4 position = constants.modelViewProjection * float4(in.position, 1.0);
    out.normal = (constants.inverseTransposeModel * float4(in.normal, 1.0)).xyz;
    out.texCoord = in.texCoord;
    out.position = position;
    return out;
}

Metal 的输入/输出模型比其他语言清晰明了,其中 main 函数显示这些绑定示意,计算着色器也是类似(用关键字kernel表示)。

//  Metal Compute Shader
#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Constants
{
    float time;
};

float foo()
{
    return 16.0;
}

kernel void main(
    uint3 groupThreadID [[ thread_position_in_threadgroup ]],
    uint3 groupID [[threadgroup_position_in_grid]],
    uint groupIndex [[thread_index_in_threadgroup]],
    uint3 dispatchThreadID [[thread_position_in_grid]],
    constant Constants& constants [[buffer(0)]],
    texture2d<float, access::read_write> tOutput [[texture(0)]])
{
    threadgroup float groupData[4];
    tOutput[dispatchThreadID.xy] = float4( float(groupThreadID.x) / foo(), float(groupThreadID.y) / 16.0, dispatchThreadID.x / 1280.0, 1.0);
}

1.4 WGSL

网络图形用户界面徽标

WebGPU Shading Language(WGSL)非常独特,其语法有点像JavaScript,Rust,C和Apple Metal,更像是Metal Shader语言和HLSL的混合体。

其中矢量类型是唯一的,它们类似于 HLSL 和 GLSL,但每种类型都有更明确定义的大小。

// WGSL Vertex Shader
struct Constants
{
  modelViewProjection: mat4x4<f32>;
  inverseTransposeModel: mat4x4<f32>;
  view: mat4x4<f32>;
};

struct VertexOutput
{
    @builtin(position) position: vec4<f32>;
    @location(0) normal: vec3<f32>;
    @location(1) uv: vec2<f32>;
};

@group(0) @binding(0) var<uniform> constants : Constants;

@stage(vertex)
fn main(@location(0) position: vec4<f32>,
        @location(1) uv: vec2<f32>) -> VertexOutput {
    var vsOut: VertexOutput;
    vsOut.position = constants.modelViewProjection * vec4<f32>(position, 1.0);
    vsOut.position = constants.inverseTransposeModel * vec4<f32>(normal, 1.0);
    vsOut.uv = uv;
    return vsOut;
}

计算着色器类似于 GLSL,内置值也具有相似的名称(如全局调用 ID 等):

// WGSL Compute Shader
struct constants
{
    f32 time;
};

@group(0) @binding(0) var<uniform> constants: Constants;
@group(0) @binding(1) var tOutput: texture_storage_2d<rgba8uint,read_write>;

fn foo() -> f32
{
    return 16.0;
}

@stage(compute) @workgroup_size(16, 16, 1)
fn main(@builtin(local_invocation_id) localInvocationID: vec3<u32>,
        @builtin(workgroup_id) workgroupID: vec3<u32>,
        @builtin(local_invocation_index) localInvocationIndex: u32,
        @builtin(global_invocation_id) globalInvocationID: vec3<u32>) {
    textureStore(tOutput, globalInvocationID.xy, vec4<f32>(f32(localInvocationID.x) / foo(), f32(localInvocationID.y) / 16.0, globalInvocationID.x / 1280.0, 1.0))
}

1.5 OpenCL

OpenCL与Apple Metal和OpenGL非常相似。虽然 OpenCL 中不存在图形管道的概念,但其他 API 中的计算内核本质上是一回事。

//C++
struct Constants
{
    float time;
    uint width;
    uint height;
};

float foo()
{
    return 16.0;
}

__kernel void main
(
    
    __constant Constants constants,
    __global float4* tOutput
)
{
    uint localId = get_local_id(0);
    uint workgroupId = get_group_id(0);
    uint globalId = get_global_id(0);

    int x = globalId % constants.width;
    int y = globalId / constants.width;

    if (x >= width || y >= constants.height)
    {
        return;
    }
    tOutput[pixel_idx] = (float4)((float)(x) / foo(), (float)(y) / 16.0, (float)(x) / 1280.0, 1.0);
}

二、编译方式

2.1 离线编译

一般为了性能考虑应始终将着色器提前编译为目标图形 API 的 IR,因为这样的话你就不再需要等待着色器编译才能提交命令。然而旧版本的OpenGL的GLSL(新版本可以使用SPIR-V了)或WebGPU着色语言(WGSL)不支持将着色器编译成IR。

HLSL

// DirectX
dxc.exe -T lib_6_3 -Fo assets/triangle.vert.dxil assets/triangle.vert.hlsl

//  Vulkan / OpenGL
dxc.exe -spirv -Fo assets/triangle.vert.spv assets/triangle.vert.hlsl

HLSL 着色器可以使用 DirectX Shader Compiler 离线编译为 DXIL。

如果要输出 SPIR-V,则需要使用-spirv标志并使用 SPIR-V 生成器处理 HLSL。

GLSL

// Vulkan / OpenGL
glslangValidator -V triangle.vert -o triangle.vert.spv

GLSLang Validator是Khronos的GLSL应用转换器,可以将其编译为SPIR-V。

Metal

// Metal
metallib triangle.vert.msl triangle.vert.mbc

metallib编译器在任意 MacOS 系统中命令行运行。

2.2 实时编译

Vulkan

// glslang.h
SH_IMPORT_EXPORT int ShCompile(
    const void* shHandle,
    const char* const shaderStrings[],
    const int numStrings,
    const int* lengths,
    const EShOptimizationLevel,
    const TBuiltInResource *resources,
    int debugOptions,
    int defaultVersion = 110,            // use 100 for ES environment, overridden by #version in shader
    bool forwardCompatible = false,      // give errors for use of deprecated features
    EShMessages messages = EShMsgDefault // warnings and errors
    );

OpenGL

GLuint shader = glCreateShader(VETEX_SHADER);

glShaderSource(shader, srcStr);

glCompileShader(shader);

GLint isCompiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
  GLint maxLength = 0;
  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
  std::vector<GLchar> errorLog(maxLength);
  glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);
}

OpenGL非常简单,你向它发送字符串并检查它是否有效。或者新版本的OpenGL允许你直接加载SPIR-V。

DirectX

HRESULT WINAPI D3DCompile(
  in      LPCVOID pSrcData,
  in      SIZE_T SrcDataSize,
  in_opt  LPCSTR pSourceName,
  in_opt  const D3D_SHADER_MACRO pDefines,
  in_opt  ID3DInclude pInclude,
  in_opt  LPCSTR pEntrypoint,
  in      LPCSTR pTarget,
  in      UINT Flags1,
  in      UINT Flags2,
  out     ID3DBlob ppCode,
  out_opt ID3DBlob ppErrorMsgs
);

DirectX也支持在运行时编译着色器,现在加载字节码或着色器字符串两者都支持。

Metal

id<MTLLibrary> library = [self.device newDefaultLibrary];
id<MTLFunction> vertexFunc = [library newFunctionWithName:@"vertex_main"];
id<MTLFunction> fragmentFunc = [library newFunctionWithName:@"fragment_main"];

在 Metal 中,可以创建着色器函数库并根据需要加载这些函数库,而不是自己管理着色器模块。如果需要获取给定库函数列表的主目录,则可以使用newFunctionWithName方法。

2.3 转译

只要着色器是用有效的 GLSL 或 HLSL 编写的,就可以使用 SPIRV-Cross 将其转译为 GLSL、HLSL 或 MSL。

具体转换demo如下:

// Compile shaders to SPIR-V binary
glslangValidator -V triangle.vert -o triangle.vert.spv
glslangValidator -V triangle.frag -o triangle.frag.spv

//  HLSL
spirv-cross triangle.vert.spv --hlsl --shader-model 50 --set-hlsl-vertex-input-semantic 0 POSITION --set-hlsl-vertex-input-semantic 1 COLOR --output triangle.vert.hlsl
spirv-cross triangle.frag.spv --hlsl --shader-model 50 --set-hlsl-vertex-input-semantic 0 COLOR --output triangle.frag.hlsl

// OpenGL ES 3.1
spirv-cross triangle.vert.spv --version 310 --es --output triangle.vert.glsl
spirv-cross triangle.frag.spv --version 310 --es --output triangle.frag.glsl

//  Metal
spirv-cross triangle.vert.spv --msl --output triangle.vert.msl
spirv-cross triangle.frag.spv --msl --output triangle.frag.msl

此外,WGSL 编译器还可以直接转译:

// Mozilla Naga
// https://github.com/gfx-rs/naga

//  Convert the WGSL to GLSL vertex stage under ES 3.20 profile
cargo run my_shader.wgsl my_shader.vert --profile es310

// Convert the SPV to Metal
cargo run my_shader.spv my_shader.metal

综上,着色语言彼此相似,关键字略有不同,底层设计理念不同(例如 GLSL 中采样器和纹理的联合,或 Metal 的缓冲区属性模型)。不过,解决HLSL,GLSL,MSL和WGSL之间的差距并不难。

还有其他的一些差异如:

  • 光线追踪着色器 - DirectX 12 和 Vulkan 共享相同类型的光线追踪着色器,但 Metal 采用了更独特的方法。

  • Meshlet Shaders - 目前仅限于DirectX 12和Vulkan,可以查看以前文章。

三、Debug工具

说完了着色器之间的差别,最重要的来了,就是除了颜色输出大法外,如何可视化实时调试Shader,根据不同平台和不同语言,可以使用如下调试工具(以下工具不止与调试Shader,性能分析也是很有用)。

以下给出自己比较常用的图形Debug工具:

  • RenderDoc
  • NVIDIA NSight Graphics (NVIDIA GPUs)
  • Intel Graphics Performance Analyser (Intel GPUs)
  • Microsoft PIX (DirectX 11/12)
  • Microsoft GPUView
  • VS图形调试器
  • Spector.js (WebGL)
  • AMD Radeon GPU Developer Tools Suite (AMD GPUs)
  • Qualcom Snapdragon Profiler
  • XCode Graphics Debugger (Metal)
  • Chrome’s Structural Profiler (WebGL)

以上工具都具有基础的图形Debug能力,如:

  • 命令分析支持。

  • 帧缓冲区附件分析。

  • 网格可视化。

  • 缓冲区显示

  • 渲染性能分析。

  • 着色器编辑与实时查看功能。

其中,GPU供应商提供的特定图形分析工具也是很好用,如AMD的Radeon GPU Profiler,NVIDIA的 NSight Graphics,Intel的 GPA,他们更倾向于分析有关其平台的图形分析信息,当然常规功能也是该有的都有。NVIDIA NSight Graphics 还具有C++项目生成器,非常适合学习给定应用程序的渲染架构。Microsoft PIX是为数不多的可用于Windows 10 UWP应用程序的调试工具之一。

简而言之,以上都是应用型介绍与使用示意,如果你有兴趣还是建议你能够先把显卡硬件的架构与执行流程了解透彻,这样的话你看以上内容的话会豁然开朗。

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

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

相关文章

sftp的基本使用

写在前面 在工作和学习中我们经常需要在linux和本地之间上传和下载文件&#xff0c;本文就一起来看下。 1&#xff1a;连接ftp 在window执行命令sftp 用户名IP,这里的用户名是linux服务器的用户名&#xff0c;IP是linux服务器的IP&#xff0c;如下&#xff1a; [c:\~]$ sft…

mysql统计查询和一行转多行(列转行)--- help_topic

mysql.help_topic help_topic本身是Mysql一个帮助解释注释表&#xff0c;用于解释Mysql各种专有名词&#xff0c;由于这张表数据ID是从0顺序增加的&#xff0c;方便我们用于计数&#xff0c;但是8.0.17版本的只有656条数据&#xff0c;超过这个数字&#xff0c;我们就需要己自定…

【王道操作系统】1.1.1 操作系统的概念、功能和目标(系统资源的管理者、提供接口、作为扩充机器、虚拟机)

操作系统的概念、功能、目标(系统资源的管理者、提供接口、作为扩充机器) 文章目录操作系统的概念、功能、目标(系统资源的管理者、提供接口、作为扩充机器)1.常见的操作系统举例2.操作系统的层次结构3.操作系统的概念4.操作系统的功能和目标4.1 作为计算机系统资源的管理者4.2…

LeetCode题解 二叉树(七):222 完全二叉树的节点个数;110 平衡二叉树;257 二叉树的所有路径

前言 阳过之后&#xff0c;已经有一周多没有接触过一道题目了 从今日开始恢复每日一小时的刷题日常 二叉树 222 完全二叉树的节点个数 medium 无论是深度遍历&#xff08;前中后都好&#xff09;还是层序遍历&#xff0c;都可以用于求解这道题&#xff0c;只需要使用一个额…

【电力系统综合能源】“双碳“背景下|综合能源系统中的经济-二氧化碳排放协调最优调度和敏感性分析研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2022年度回顾|在Jina AI社区连接、分享、共创

在 Jina AI 社区&#xff0c;每天都有来自世界各地的开发者加入&#xff0c;因技术产生连接&#xff0c;因连接带动分享&#xff0c;因分享促进共创。2022 的若干个闪亮的高光时刻&#xff0c;都有来自社区的支持和贡献&#xff1a;在春天&#xff0c;我们发布了 Jina 3.0&…

M1 ARM架构下, linux安装mysql的方式及潜在问题解决

下载: 1. 下载压缩包: 由于m1/m2芯片得使用aarch64架构, 所以普通的x86架构这里就完全无法使用了, 这里推荐在清华镜像网下载对应的aarch64版本: 安装包下载地址 2. Linux系统准备 默认的CentOS是自带mariadb, 和mysql的安装相冲突 , 所以需要提前删除 rpm -qa | grep mari…

Python 三种方法实现截图【详解+完整代码】

人生苦短 我用python 如何用python实现截屏&#xff1f; 一、方法一 PIL中的ImageGrab模块 使用PIL中的ImageGrab模块简单&#xff0c;但是效率有点低 PIL是Python Imaging Library&#xff0c; 它为python解释器提供图像编辑函数能力。 ImageGrab模块可用于将屏幕或剪贴板…

《Linux运维总结:Centos7.6部署redis6.2.8 cluster集群》

一、redis cluster集群规划 Centos7.6部署redis6.2.8 cluster集群资源包 环境信息如下&#xff1a; 主机IP操作系统Redis版本CPU架构端口角色192.168.1.191Centos7.66.2.8x86_647001master192.168.1.192Centos7.66.2.8x86_647002master192.168.1.193Centos7.66.2.8x86_647003m…

如何快速打造一个高权重的短视频账号?短视频运营推广日记(2)

之前做的短视频账号流量一直不好&#xff0c;终于狠下心来注销了&#xff0c;准备重新来过 趁现在账号注销期&#xff0c;好好了解一下短视频账号从0打造的内容&#xff0c;我赢的高权重账号打造内容反复阅读了9遍&#xff0c;终于总结出了属于自己的内容。 看过很多人说要养…

51. CPU和GPU

1. 你的GPU电脑 2. 提升CPU利用率的第一个方法 3. 样例分析 如果一个矩阵是按行存储&#xff0c;访问一行会比访问一列要快 CPU一次读取64字节&#xff08;缓存栈&#xff09;CPU会“聪明的”提前读取下一个&#xff08;缓存栈&#xff09; 4. 提升CPU利用率的第二个方法 高端…

字节一面:服务端挂了,客户端的 TCP 连接还在吗?

服务端进程崩溃&#xff0c;客户端会发生什么&#xff1f; TCP 的连接信息是由内核维护的&#xff0c;所以当服务端的进程崩溃后&#xff0c;内核需要回收该进程的所有 TCP 连接资源&#xff0c;于是内核会发送第一次挥手 FIN 报文&#xff0c;后续的挥手过程也都是在内核完成…

Linux 快照 (snapshot) 原理与实践(二) 快照功能实践

文章目录 0. 概要1. 准备演示数据2. 创建 snapshot-origin 目标3. 创建 snapshot 目标4. 验证 COW 操作4.1 第一次写数据4.2 第二次写数据5. 验证 ROW 操作5.1 第一次写数据5.2 第二次写数据6. 创建 snapshot-merge 目标7. 验证 merge 操作8. 后记0. 概要 上一篇《Linux 快照 …

【修改按钮的大小 Objective-C语言】

一、修改按钮的大小 1.还是上篇文章那个例子 点击加号的时候,使上面的图片按钮变大, 点击减号的时候,使上面的图片按钮变小 2.首先,需要给“加”按钮,注册单击事件 怎么办,拖线吧 右键点击这个列表中的“加”按钮,把这个按钮的Touch Up Inside右边的小圆圈,拖到Vi…

《计算机体系结构量化研究方法》附录B.1 B.2 缓存性能

一、缓存 1、基本知识 &#xff08;1&#xff09;缓存是指可以进行高速数据交换的存储器&#xff0c;它先于内存与CPU交换数据&#xff0c;因此速率很快。&#xff08;from百度&#xff09; &#xff08;2&#xff09;如果处理器在缓存中找到了所需求的数据项&#xff0c;那么…

java 瑞吉外卖优化day1 缓存短信验证 git分支开发 缓存套餐数据 SpringCache

缓存优化 我们将之前写的瑞吉项目push到gitee上&#xff0c;然后新建一个分支v1.0&#xff0c;在v1.0上进行优化&#xff0c;并且push上去 环境搭建 host跟ip都要写自己对应的 &#xff0c;如果没有设置密码 就不用写密码配置 新建RedisConfig配置类 控制不让key序列化&#xf…

springboot入门篇

SpringBoot 文档更新日志 版本更新日期操作描述v1.02021/11/14A基础篇 前言 ​ 很荣幸有机会能以这样的形式和互联网上的各位小伙伴一起学习交流技术课程&#xff0c;这次给大家带来的是Spring家族中比较重要的一门技术课程——SpringBoot。一句话介绍这个技术&#xff0c;应…

Android音乐播放器(高分课设)

实现功能&#xff1a; 1&#xff1a;启动动画&#xff08;运行程序出现一个2秒钟的视频&#xff09;&#xff0c;2秒钟后进入下一界面&#xff01; 2&#xff1a;登录注册&#xff08;账号和密码采用了MD5Utile加密&#xff09;&#xff0c;输入正确的账号和密码进入主界面&a…

新的一年嘚拥有新的壁纸了,python批量采集高清壁纸

前言 大家早好、午好、晚好吖 ❤ ~ 新的一年不得需要新的壁纸&#xff1f;今天我们就来采集一下 环境使用: Python 3.8 解释器 Pycharm 编辑器 第三方模块 import requests >>> pip install requests 如何安装python第三方模块: win R 输入 cmd 点击确定, 输入…

ubuntu 20.04 安装谷歌输入法

目标&#xff1a; 快速安装谷歌输入法 步骤&#xff1a; 安装fcitx-googlepinyin&#xff1a; sudo apt-get install fcitx-googlepinyin 在应用程序里的语言支持中配置language support&#xff1a; 点开语言支持后会提示未完全安装&#xff0c;点击完整安装&#xff1a;…