热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一文看懂深度学习模型压缩和加速

点击上方“小白学视觉”,选择加星标或“置顶”重磅干货,第一时间送达本文转自:opencv学堂1前言近年来深度学习模型在计算机视觉、自然

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

本文转自:opencv学堂

1 前言

近年来深度学习模型在计算机视觉、自然语言处理、搜索推荐广告等各种领域,不断刷新传统模型性能,并得到了广泛应用。随着移动端设备计算能力的不断提升,移动端AI落地也成为了可能。相比于服务端,移动端模型的优势有:

  1. 减轻服务端计算压力,并利用云端一体化实现负载均衡。特别是在双11等大促场景,服务端需要部署很多高性能机器,才能应对用户流量洪峰。平时用户访问又没那么集中,存在巨大的流量不均衡问题。直接将模型部署到移动端,并在置信度较高情况下直接返回结果,而不需要请求服务端,可以大大节省服务端计算资源。同时在大促期间降低置信度阈值,平时又调高,可以充分实现云端一体负载均衡。

  2. 实时性好,响应速度快。在feed流推荐和物体实时检测等场景,需要根据用户数据的变化,进行实时计算推理。如果是采用服务端方案,则响应速度得不到保障,且易造成请求过于密集的问题。利用端计算能力,则可以实现实时计算。

  3. 稳定性高,可靠性好。在断网或者弱网情况下,请求服务端会出现失败。而采用端计算,则不会出现这种情况。在无人车和自动驾驶等可靠性要求很高的场景下,这一点尤为关键,可以保证在隧道、山区等场景下仍能稳定运行。

  4. 安全性高,用户隐私保护好。由于直接在端上做推理,不需要将用户数据传输到服务端,免去了网络通信中用户隐私泄露风险,也规避了服务端隐私泄露问题

移动端部署深度学习模型也有很大的挑战。主要表现在,移动端等嵌入式设备,在计算能力、存储资源、电池电量等方面均是受限的。故移动端模型必须满足模型尺寸小、计算复杂度低、电池耗电量低、下发更新部署灵活等条件。因此模型压缩和加速就成为了目前移动端AI的一个热门话题。

模型压缩和加速不仅仅可以提升移动端模型性能,在服务端也可以大大加快推理响应速度,并减少服务器资源消耗,大大降低成本。结合移动端AI模型和服务端模型,实现云端一体化,是目前越来越广泛采用的方案。

模型压缩和加速是两个不同的话题,有时候压缩并不一定能带来加速的效果,有时候又是相辅相成的。压缩重点在于减少网络参数量,加速则侧重在降低计算复杂度、提升并行能力等。模型压缩和加速可以从多个角度来优化。总体来看,个人认为主要分为三个层次:

  1. 算法层压缩加速。这个维度主要在算法应用层,也是大多数算法工程师的工作范畴。主要包括结构优化(如矩阵分解、分组卷积、小卷积核等)、量化与定点化、模型剪枝、模型蒸馏等。

  2. 框架层加速。这个维度主要在算法框架层,比如tf-lite、NCNN、MNN等。主要包括编译优化、缓存优化、稀疏存储和计算、NEON指令应用、算子优化等

  3. 硬件层加速。这个维度主要在AI硬件芯片层,目前有GPU、FPGA、ASIC等多种方案,各种TPU、NPU就是ASIC这种方案,通过专门为深度学习进行芯片定制,大大加速模型运行速度。

下面也会分算法层、框架层和硬件层三个方面进行介绍。

2 算法层压缩加速

2.1 结构优化

2.1.1 矩阵分解

举个例子&#xff0c;将M*N的矩阵分解为M*K &#43; K*N&#xff0c;只要让K<

其中M为词表长度&#xff0c;也就是vocab_size&#xff0c;典型值为21128。N为隐层大小&#xff0c;典型值为1024&#xff0c;也就是hidden_size。K为我们设置的低维词嵌入空间&#xff0c;可以设置为128。

  1. 分解前&#xff1a;矩阵参数量为 (M * N)

  2. 分解后&#xff1a;参数量为 (M*K &#43; K*N)

  3. 压缩量&#xff1a;(M * N) / (M*K &#43; K*N), 由于M远大于N&#xff0c;故可近似为 N / k&#xff0c;当N&#61;2014&#xff0c;k&#61;128时&#xff0c;可以压缩8倍

2.1.2 权值共享

相对于DNN全连接参数量过大的问题&#xff0c;CNN提出了局部感受野和权值共享的概念。在NLP中同样也有类似应用的场景。比如ALBert中&#xff0c;12层共用同一套参数&#xff0c;包括multi-head self attention和feed-forward&#xff0c;从而使得参数量降低到原来的1/12。这个方案对于模型压缩作用很大&#xff0c;但对于推理加速则收效甚微。因为共享权值并没有带来计算量的减少。

2.1.3 分组卷积

在视觉模型中应用较为广泛&#xff0c;比如shuffleNet&#xff0c;mobileNet等。我们以mobileNet为例。对于常规的M输入通道&#xff0c;N输出通道&#xff0c;dk*dk的kernel size的卷积&#xff0c;需要参数量为 M*N*dk*dk。这是因为每个输入通道&#xff0c;都会抽取N种特征&#xff08;对应输出通道数&#xff09;&#xff0c;不同的输入通道需要不同的kernel来做抽取&#xff0c;然后叠加起来。故M个输入通道&#xff0c;N个输出通道&#xff0c;就需要M*N个kernel了。

mobileNet对常规卷积做了优化&#xff0c;每个输入通道&#xff0c;仅需要一个kernel做特征提取&#xff0c;这叫做depth wise。如此M个通道可得到M个feature map。但我们想要的是N通道输出&#xff0c;怎么办呢&#xff1f;mobileNet采用一个常规1*1卷积来处理这个连接&#xff0c;从而转化到N个输出通道上。总结下来&#xff0c;mobileNet利用一个dk*dk的depth wise卷积和一个1*1的point wise卷积来实现一个常规卷积。

  1. 分组前&#xff1a;参数量 (M*N*dk*dk)

  2. 分组后&#xff1a;参数量 (M*dk*dk &#43; M*N*1*1)

  3. 压缩量&#xff1a;(M*dk*dk &#43; M*N*1*1) / (M*N*dk*dk)&#xff0c;近似为 1/(dk*dk)。dk的常见值为3&#xff0c;也就是3*3卷积&#xff0c;故可缩小约9倍

如下图所示&#xff1a;

2.1.4 分解卷积

  1. 使用两个串联小卷积核来代替一个大卷积核。InceptionV2中创造性的提出了两个3x3的卷积核代替一个5x5的卷积核。在效果相同的情况下&#xff0c;参数量仅为原先的 3x3x2 / 5x5 &#61; 18/25

  2. 使用两个并联的非对称卷积核来代替一个正常卷积核。InceptionV3中将一个7x7的卷积拆分成了一个1x7和一个7x1, 卷积效果相同的情况下&#xff0c;大大减少了参数量&#xff0c;同时还提高了卷积的多样性。

2.1.5 其他

  1. 全局平均池化代替全连接层。这个才是大杀器&#xff01;AlexNet和VGGNet中&#xff0c;全连接层几乎占据了90%的参数量。inceptionV1创造性的使用全局平均池化来代替最后的全连接层&#xff0c;使得其在网络结构更深的情况下&#xff08;22层&#xff0c;AlexNet仅8层&#xff09;&#xff0c;参数量只有500万&#xff0c;仅为AlexNet的1/12

  2. 1x1卷积核的使用。1x1的卷积核可以说是性价比最高的卷积了&#xff0c;没有之一。它在参数量为1的情况下&#xff0c;同样能够提供线性变换&#xff0c;relu激活&#xff0c;输入输出channel变换等功能。VGGNet创造性的提出了1x1的卷积核

  3. 使用小卷积核来代替大卷积核。VGGNet全部使用3x3的小卷积核&#xff0c;来代替AlexNet中11x11和5x5等大卷积核。小卷积核虽然参数量较少&#xff0c;但也会带来特征面积捕获过小的问题。inception net认为越往后的卷积层&#xff0c;应该捕获更多更高阶的抽象特征。因此它在靠后的卷积层中使用的5x5等大面积的卷积核的比率较高&#xff0c;而在前面几层卷积中&#xff0c;更多使用的是1x1和3x3的卷积核。

2.2 量化

2.2.1 伪量化

深度学习模型参数通常是32bit浮点型&#xff0c;我们能否使用16bit&#xff0c;8bit&#xff0c;甚至1bit来存储呢&#xff1f;答案是肯定的。常见的做法是保存模型每一层时&#xff0c;利用低精度来保存每一个网络参数&#xff0c;同时保存拉伸比例scale和零值对应的浮点数zero_point。推理阶段&#xff0c;利用如下公式来网络参数还原为32bit浮点&#xff1a;

这个过程被称为伪量化。

伪量化之所以得名&#xff0c;是因为存储时使用了低精度进行量化&#xff0c;但推理时会还原为正常高精度。为什么推理时不仍然使用低精度呢&#xff1f;这是因为一方面框架层有些算子只支持浮点运算&#xff0c;需要专门实现算子定点化才行。另一方面&#xff0c;高精度推理准确率相对高一些。伪量化可以实现模型压缩&#xff0c;但对模型加速没有多大效果。

2.2.2 聚类与伪量化

一种实现伪量化的方案是&#xff0c;利用k-means等聚类算法&#xff0c;步骤如下&#xff1a;

  1. 将大小相近的参数聚在一起&#xff0c;分为一类。

  2. 每一类计算参数的平均值&#xff0c;作为它们量化后对应的值。

  3. 每一类参数存储时&#xff0c;只存储它们的聚类索引。索引和真实值&#xff08;也就是类内平均值&#xff09;保存在另外一张表中

  4. 推理时&#xff0c;利用索引和映射表&#xff0c;恢复为真实值。

过程如下图所示&#xff0c;

从上可见&#xff0c;当只需要4个类时&#xff0c;我们仅需要2bit就可以实现每个参数的存储了&#xff0c;压缩量达到16倍。推理时通过查找表恢复为浮点值&#xff0c;精度损失可控。结合霍夫曼编码&#xff0c;可进一步优化存储空间。一般来说&#xff0c;当聚类数为N时&#xff0c;我们压缩量为 log(N) / 32。

2.2.3 定点化

与伪量化不同的是&#xff0c;定点化在推理时&#xff0c;不需要还原为浮点数。这需要框架实现算子的定点化运算支持。目前MNN、XNN等移动端AI框架中&#xff0c;均加入了定点化支持。

2.3 剪枝

2.3.1 剪枝流程

剪枝归纳起来就是取其精华去其糟粕。按照剪枝粒度可分为突触剪枝、神经元剪枝、权重矩阵剪枝等。总体思想是&#xff0c;将权重矩阵中不重要的参数设置为0&#xff0c;结合稀疏矩阵来进行存储和计算。通常为了保证performance&#xff0c;需要一小步一小步地进行迭代剪枝。步子大了&#xff0c;容易那个啥的&#xff0c;大家都懂的哈。

常见迭代剪枝流程如下图所示

  1. 训练一个performance较好的大模型。

  2. 评估模型中参数的重要性。常用的评估方法是&#xff0c;越接近0的参数越不重要。当然还有其他一些评估方法&#xff0c;这一块也是目前剪枝研究的热点。

  3. 将不重要的参数去掉&#xff0c;或者说是设置为0。之后可以通过稀疏矩阵进行存储。比如只存储非零元素的index和value。

  4. 训练集上微调&#xff0c;从而使得由于去掉了部分参数导致的performance下降能够尽量调整回来。

  5. 验证模型大小和performance是否达到了预期&#xff0c;如果没有&#xff0c;则继续迭代进行。

2.3.2 突触剪枝

突触剪枝剪掉神经元之间的不重要的连接。对应到权重矩阵中&#xff0c;相当于将某个参数设置为0。常见的做法是&#xff0c;按照数值大小对参数进行排序&#xff0c;将大小排名最后的k%置零即可&#xff0c;k%为压缩率。具体流程可以参考下面的图例&#xff1a;

2.3.3 神经元剪枝

神经元剪枝则直接将某个节点直接去掉。对应到权重矩阵中&#xff0c;相当于某一行和某一列置零。常见做法是&#xff0c;计算神经元对应的一行和一列参数的平方和的根&#xff0c;对神经元进行重要性排序&#xff0c;将大小排名最后的k%置零。具体流程可以参考下面的图例&#xff1a;

2.3.4 权重矩阵剪枝

除了将权重矩阵中某些零散的参数&#xff0c;或者整行整列去掉外&#xff0c;我们能否将整个权重矩阵去掉呢&#xff1f;答案是肯定的&#xff0c;目前也有很多这方面的研究。NeurIPS 2019有篇文章&#xff0c;Are Sixteen Heads Really Better than One?&#xff0c;深入分析了BERT多头机制中每个头到底有多大用&#xff0c;结果发现很多头其实没啥卵用。他在要去掉的head上&#xff0c;加入mask&#xff0c;来做每个头的重要性分析。

作者先分析了单独去掉每层每个头&#xff0c;WMT任务上BLEU的改变。发现&#xff0c;大多数head去掉后&#xff0c;对整体影响不大。如下图所示

然后作者分析了&#xff0c;每层只保留一个最重要的head后&#xff0c;ACC的变化。可见很多层只保留一个head&#xff0c;performance影响不大。如下图所示

由此可见&#xff0c;直接进行权重矩阵剪枝&#xff0c;也是可行的方案。相比突触剪枝和神经元剪枝&#xff0c;压缩率要大很多。

2.4 蒸馏

2.4.1 蒸馏流程

蒸馏本质是student对teacher的拟合&#xff0c;从teacher中汲取养分&#xff0c;学到知识&#xff0c;不仅仅可以用到模型压缩和加速中。蒸馏常见流程如下图所示

  1. 老师和学生可以是不同的网络结构&#xff0c;比如BERT蒸馏到BiLSTM网络。但一般相似网络结构&#xff0c;蒸馏效果会更好。

  2. 总体loss为 soft_label_loss &#43; hard_label_loss。soft_label_loss可以用KL散度或MSE拟合

  3. soft label为teacher模型的要拟合的对象。可以是模型预测输出&#xff0c;也可以是embeddings, 或者hidden layer和attention分布。

针对软标签的定义&#xff0c;蒸馏的方案也是百花齐放&#xff0c;下面分享两篇个人认为非常经典的文章。

2.4.2 distillBERT

DistillBERT: A distilled version of BERT: smaller, faster, cheaper and lighter

DistillBERT由大名鼎鼎的HuggingFace出品。主要创新点为&#xff1a;

  1. Teacher 12层&#xff0c;student 6层&#xff0c;每两层去掉一层。比如student第二层对应teacher第三层

  2. Loss&#61; 5.0 * Lce&#43;2.0 * Lmlm&#43;1.0 * Lcos

  • Lce: soft_label 的KL散度

  • Lmlm: mask LM hard_label 的交叉熵

  • Lcos&#xff1a;hidden state 的余弦相似度

DistilBERT 比 BERT 快 60%&#xff0c;体积比 BERT 小 60%。在glue任务上&#xff0c;保留了 95% 以上的性能。在performance损失很小的情况下&#xff0c;带来了较大的模型压缩和加速效果。

2.4.3 TinyBERT

TinyBERT: Distilling BERT for Natural Language Understanding

总体结构

重点来看下 TinyBERT&#xff0c;它是由华为出品&#xff0c;非常值得深入研究。TinyBERT 对 embedding 层&#xff0c;transformer层&#xff08;包括hidden layer和attention&#xff09;和 prediction 层均进行了拟合。如下图所示。

TinyBERT 蒸馏过程

其中Embeddings采用MSE, Prediction采用KL散度, Transformer层的hidden layer和attention&#xff0c;均采用MSE。loss如下

其中m为层数。

效果分析

表2: glue任务上的performance。在glue任务上&#xff0c;可达到bert-base的96%&#xff0c;几乎无损失。表3: tinyBERT模型大小和推理速度。缩小7.5倍&#xff0c;加速9.4倍。压缩和加速效果十分明显。

消融分析

表6&#xff1a;分析embedding、prediction、attention、hidden layer软标签作用&#xff0c;其中attention和hidden layer作用最大。这个也很好理解&#xff0c;transformer层本来就是整个BERT中最关键的部分。
表7&#xff1a;分析老师学生不同层对应方法的效果&#xff0c;uniform为隔层对应&#xff0c;top为全部对应老师顶部几层&#xff0c;bottom为全部对应老师底部几层。Uniform效果明显好很多。这个也很好理解&#xff0c;浅层可以捕捉低阶特征&#xff0c;深层可以捕捉高阶特征。全是低阶或者高阶显然不合适&#xff0c;我们要尽量荤素搭配。

3 框架层加速

3.1 手机端AI能力

目前移动端AI框架也比较多&#xff0c;包括谷歌的tf-lite&#xff0c;腾讯的NCNN&#xff0c;阿里的MNN&#xff0c;百度的PaddleLite, 小米的MACE等。他们都不同程度的进行了模型压缩和加速的支持。特别是端上推理的加速。这个可以参考“手机端AI性能排名“。

3.2 端侧AI框架加速优化方法

个人总结的主要方法如下&#xff0c;可能有遗漏哈&#xff0c;各位看官请轻拍&#xff1a;

  1. 基于基本的C&#43;&#43;编译器优化。

    1. 打开编译器的优化选项&#xff0c;选择O2等加速选项。

    2. 小函数内联&#xff0c;概率大分支优先&#xff0c;避免除法&#xff0c;查表空间换时间&#xff0c;函数参数不超过4个等。

  2. 利用C&#xff0c;而不是C&#43;&#43;&#xff0c;C&#43;&#43;有不少冗余的东西。

  3. 缓存优化

    1. 小块内存反复使用&#xff0c;提升cache命中率&#xff0c;尽量减少内存申请。比如上一层计算完后&#xff0c;接着用作下一层计算。

    2. 连续访问&#xff0c;内存连续访问有利于一次同时取数&#xff0c;相近位置cache命中概率更高。比如纵向访问数组时&#xff0c;可以考虑转置后变为横向访问。

    3. 对齐访问&#xff0c;比如224*224的尺寸&#xff0c;补齐为256*224&#xff0c;从而提高缓存命中率。

    4. 缓存预取&#xff0c;CPU计算的时候&#xff0c;preload后面的数据到cache中。

  4. 多线程。

    1. 为循环分配线程。

    2. 动态调度&#xff0c;某个子循环过慢的时候&#xff0c;调度一部分循环到其他线程中。

  5. 稀疏化

    1. 稀疏索引和存储方案&#xff0c;采用eigen的sparseMatrix方案。

  6. 内存复用和提前申请

    1. 扫描整个网络&#xff0c;计算每层网络内存复用的情况下&#xff0c;最低的内存消耗。推理刚开始的时候就提前申请好。避免推理过程中反复申请和释放内存&#xff0c;避免推理过程中因为内存不足而失败&#xff0c;复用提升内存访问效率和cache命中率。

  7. ARM NEON指令的使用&#xff0c;和ARM的深度融合。NEON可以单指令多取值&#xff08;SIMD&#xff09;&#xff0c;感兴趣可针对学习&#xff0c;这一块水也很深。

  8. 手工汇编&#xff0c;毕竟机器编译出来的代码还是有不少冗余的。可以针对运行频次特别高的代码进行手工汇编优化。当然如果你汇编功底惊天地泣鬼神的强&#xff0c;也可以全方位手工汇编。

  9. 算子支持&#xff1a;比如支持GPU加速&#xff0c;支持定点化等。有时候需要重新开发端侧的算子。

4 硬件层加速

硬件层加速比较硬核&#xff0c;小编就连半瓢水都达不到了&#xff0c;为了保证整个方案的全面性&#xff0c;还是硬着头皮东施效颦下。目前AI芯片厂家也是百花齐放&#xff0c;谁都想插一脚&#xff0c;不少互联网公司也来赶集&#xff0c;如下图所示。

AI 芯片目前三种方案。GPU目前被英伟达和AMD牢牢把控。ASIC目前最火&#xff0c;TPU、NPU等属于ASIC范畴。

5 总结

这篇文章我们对深度学习模型压缩和加速的几类常用的方法进行了介绍&#xff0c;如果有读者对模型压缩加速也感觉兴趣的话&#xff0c;欢迎一起来讨论。

参考文献

  1. ALBERT: A Lite BERT for Self-supervised Learning of Language Representations

  2. MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications

  3. Are Sixteen Heads Really Better than One?

  4. DistillBERT: A distilled version of BERT: smaller, faster, cheaper and lighter

  5. TinyBERT: Distilling BERT for Natural Language Understanding

  6. 手机端AI性能排名

下载1&#xff1a;OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复&#xff1a;扩展模块中文教程&#xff0c;即可下载全网第一份OpenCV扩展模块教程中文版&#xff0c;涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2&#xff1a;Python视觉实战项目52讲

在「小白学视觉」公众号后台回复&#xff1a;Python视觉实战项目&#xff0c;即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目&#xff0c;助力快速学校计算机视觉。

下载3&#xff1a;OpenCV实战项目20讲

在「小白学视觉」公众号后台回复&#xff1a;OpenCV实战项目20讲&#xff0c;即可下载含有20个基于OpenCV实现20个实战项目&#xff0c;实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流&#xff0c;目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群&#xff08;以后会逐渐细分&#xff09;&#xff0c;请扫描下面微信号加群&#xff0c;备注&#xff1a;”昵称&#43;学校/公司&#43;研究方向“&#xff0c;例如&#xff1a;”张三 &#43; 上海交大 &#43; 视觉SLAM“。请按照格式备注&#xff0c;否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告&#xff0c;否则会请出群&#xff0c;谢谢理解~



推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 网卡工作原理及网络知识分享
    本文介绍了网卡的工作原理,包括CSMA/CD、ARP欺骗等网络知识。网卡是负责整台计算机的网络通信,没有它,计算机将成为信息孤岛。文章通过一个对话的形式,生动形象地讲述了网卡的工作原理,并介绍了集线器Hub时代的网络构成。对于想学习网络知识的读者来说,本文是一篇不错的参考资料。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • Nginx Buffer 机制引发的下载故障
    Nginx ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
author-avatar
林君滨__
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有