最后
既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?
就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。
如果觉得图片不够清晰,也可来找小编分享原件的xmind文档!
且除此份微服务体系大纲外,我也有整理与其每个专题核心知识点对应的最强学习笔记:
-
出神入化——SpringCloudAlibaba.pdf
-
SpringCloud微服务架构笔记(一).pdf
-
SpringCloud微服务架构笔记(二).pdf
-
SpringCloud微服务架构笔记(三).pdf
-
SpringCloud微服务架构笔记(四).pdf
-
Dubbo框架RPC实现原理.pdf
-
Dubbo最新全面深度解读.pdf
-
Spring Boot学习教程.pdf
-
SpringBoo核心宝典.pdf
-
第一本Docker书-完整版.pdf
-
使用SpringCloud和Docker实战微服务.pdf
-
K8S(kubernetes)学习指南.pdf
另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!
分段输入插值。分段输入在渲染阶段由着色器核心进行插值。着色器核心有一个专用的分段输入插值器。这个是比较固定和高精度的功能。我们能优化的点不多,如下图所示:
尽可能的移除传递给分段着色器的顶点属性。
▐ 内存带宽
内存带宽也是影响我们GPU性能的一个重要因素。如果在GPU性能计数器的内存带宽模块看到一个很高的值。我们就应该如下图所示来进行优化:
如果纹理和缓存区也同样显示比较高的值,那优化优先级应该排到第一位。优化方案也是较少Working Set的大小。此外,我们应该只加载当前渲染过程需要的数据,只存储未来渲染过程需要的数据。然后就是确保使用纹理压缩。
▐ Occupancy
如果我们看到整体利用率比较低,这意味着Shader可能已经耗尽了一些内部资源,比如tile或者threadgroup内存。也可能是线程完成执行的速度比GPU创建新线程的速度快。
▐ 避免重复绘制
我们通过GPU计数器可以统计到重复绘制的区域,我们应该高效使用HSR来避免这样的重绘。我们可以如图所示的顺序来进行绘制。
Build GPU binaries with Metal
这一章主要给开发者们介绍了一种使用Metal的编程工作流,可以通过优化Metal的渲染编译模型来增强渲染管线,这个优化可以在应用程序启动,特别是首次启动时大大减少PSO(管线状态对象)的加载时间。可以让我们的图形渲染更加的高效。整个章节主要分为四个部分:
▐ Metal的Shader编译模型概述
众所周知,Metal Shading Language是Apple为开发者提供的Shader编程语言,Metal会将编程语言编译成为一个叫做AIR的中间产物,然后AIR会在设备上进一步编译,生成每个GPU所需的特定的机器码。整个过程如下图所示:
上述过程在每个管线的生命周期中都会发生,当前Apple为了加速管线的重新编译和重新创建流程,会缓存一些Metal的方法变体,但是这个过程还是会造成屏幕的加载耗时过长。而且在当前的这个编译模型中,应用程序不能在不同的PSO(管线状态对象)中重用之前生成的机器码子程序。
所以我们需要一种方法来减少这个整个管线编译(即源代码->AIR->GPU二进制代码)的时间成本,还需要一种机制来支持不同PSO之间共享子程序和方法,这样就不需要将相同的代码多次编译或者是多次加载到内存中。这样开发者们就可以使用这套工具来优化App首次的启动体验。
▐ Metal二进制文件介绍
Metal二进制文件就是解决上述需求的方法之一,现在开发者们可以直接使用Metal为二进制文件来控制PSO的缓存。开发者可以收集已编译的PSO,然后将它们存储到设备中,甚至可以分发到其他兼容的设备中(同样的GPU和同样的操作系统),这种二进制文件可以看做一种Asset。下面是一些例程和示意图:
//创建一个空的二进制文件
let descriptor = MTLBinaryArchiveDescriptor()
descriptor.url = nil
let binaryArchive = try device.makeBinaryArchive(descriptor:descriptor)
//Populating an archive
// Render pipelines
try binaryArchive.addRenderPipelineFunctions(with: renderPipelineDescriptor)
// Compute pipelines
try binaryArchive.addComputePipelineFunctions(with: computePipelineDescriptor)
// Tile render pipelines
try binaryArchive.addTileRenderPipelineFunctions(with: tileRenderPipelineDescriptor)
//重用已编译的方法
// Reusing compiled functions to build a pipeline state object from a file
let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
// …
renderPipelineDescriptor.binaryArchives = [ binaryArchive ]
let renderPipeline = try device.makeRenderPipelineState(descriptor:
renderPipelineDescriptor)
//序列化
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let archiveURL = documentsURL.appendingPathComponent(“binaryArchive.metallib”)
try binaryArchive.serialize(to: NSURL.fileURL(withPath: archiveURL))
//反序列化
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let serializeURL = documentsURL.appendingPathComponent(“binaryArchive.metallib”)
let descriptor = MTLBinaryArchiveDescriptor()
descriptor.url = NSURL.fileURL(withPath: serializeURL)
let binaryArchive = try device.makeBinaryArchive(descriptor: descriptor)
总的来说就是这个Metal二进制文件可以提供开发者手动管理管线缓存的方法,这样就可以从一个设备中获取这些文件并部署到其他兼容的设备上,在iOS环境下,极大地减少了第一次安装游戏或应用以及设备重启后的管道创建时间。可以优化应用的首次启动体验和冷启动体验。
▐ Metal对动态库的支持
动态库将允许开发者编写可重用的库代码,却可以减少重新编译程序的时间和内存成本,这个特性将会允许开发者将计算着色器和程序库动态链接。而且和二进制文件一样,动态库也是可序列化和可转移的。这也是解决上述需求的方案之一。
在PSO生成的时候,每个应用程序都需要为程序library生成机器码,而且使用相同的程序库编译多个管线会导致生成重复的机器码。由于大量的编译和内存的增加,这个可能会导致更长的管线加载时间。而动态库就可以解决这个问题。
Metal Dynamic Library允许开发者以机器码的形式动态链接,加载和共享工具方法。代码可以在多个计算管线中重用,消除了重复编译和多个相同子程序的存储。而且这个 MTLDynamicLibrary是可序列化的,可以作为应用程序的Asset使用。MTLDynamicLibrary其实就是多个计算管线调用的导出方法的集合。
大致的工作流程如下:我们首先创建一个MTLLibrary作为我们指定的动态库,这个可以将我们的metal代码编译为AIR。然后我们调用方法makeDynamicLibrary,这个方法需要指定一个唯一的installname,在管线创建时,linker将会使用这个名字来加载动态库。这个方法可以将我们的动态库编译成为机器码。这就完成了动态库的创建。
对于动态库的使用来说:通过设置MTLCompileOptions里的libraries参数,就可以完成动态库的加载和使用了。代码如下:
//使用动态库进行编译
let options = MTLCompileOptions()
options.libraries = [ utilityDylib ]
let library = try device.makeLibrary(source: kernelStr, options: options)
▐ 开发工具介绍
这个部分主要介绍了构建Metal二进制文件和构建动态库的具体工具和方法。以视频的形式可能会更好的表现,详情可见:Build GPU binaries with Metal (从22:51开始)
Debug GPU-side errors in Metal
这一章主要介绍的是GPU侧的bug,当前如果我们的应用程序出现了GPU侧的bug,他的错误日志常常都不能让开发者很直观的定位到错误的代码范围和调用栈。所以在最新的Xcode中,增强了关于GPU侧的debug机制。可以像在代码侧发成的错误一样不但能定位到错误原因,还有错误的调用堆栈和各种信息都可以详细的查看到。让开发者能更好的修复代码造成的GPU侧的渲染错误。
▐ Enhanced Command Buffer Errors
这是当前的错误日志上报,我们可以看到GPU侧的错误日志不像Api的错误日志一样可以让开发者很快的定位到错误原因和错误的代码位置。
而最新的Metal debugging工具就增强了这方面的能力,让Shader的code也可以像Api代码一样提供错误定位和分类能力。
我们通过以下代码便可以启用增强版的commandbuffer错误机制
//启用增强版的commandbuffer错误机制
let desc = MTLCommandBufferDescriptor()
desc.errorOptions = .encoderExecutionStatus
let commandBuffer = commandQueue.makeCommandBuffer(descriptor: desc)
错误一共有五种状态:
我们也可以通过以下代码来打印error:
//打印commandbuffer的错误
if let error = commandBuffer.error as NSError? {
if let encoderInfos =
error.userInfo[MTLCommandBufferEncoderInfoErrorKey]
as? [MTLCommandBufferEncoderInfo] {
for info in encoderInfos {
print(info.label + info.debugSignposts.joined())
if info.errorState == .faulted {
print(info.label + " faulted!")
}
}
}
}
开发者可以在开发时和测试时启用优化版的错误机制
▐ Shader Validation
如上图所示,这个功能可以在GPU侧发生渲染错误时自动定位和catch到错误并定位到代码,以及获取回溯栈帧。
我们可以在Xcode中按照以下流程来开启这个功能:
1.开启Metal中的两个Validation选项
2.开启issue自动断点开关并配置类型和分类等选项
Video中用了一个demo来展示整个工作流,具体参见Debug GPU-side errors in Metal(11:25~14:45)大致流程如下图所示:
这是一个Demo应用程序,很明显它在渲染上出现了一些异常,但是因为是GPU侧的问题,所以开发者很难定位。但是通过上述的工作流开启Shader Validation之后。
Xcode会自动断点到发生异常的地方,并展示出异常信息,这样就可以极大的提升开发者的错误修复效率。
Gain insights into your Metal app with Xcode 12
感受:
其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。
特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。
也祝愿各位同学,都能找到自己心动的offer。
分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档
de 12**
感受:
其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。
特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。
也祝愿各位同学,都能找到自己心动的offer。
分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档
[外链图片转存中…(img-xw7ge9sQ-1714923643931)]