lxx 发布的文章

性能优化之编译优化


本文主要分享总结一下工作过程中用到有关于编译优化方面的性能优化手段。

1.反馈式编译PGO

本文使用冒泡排序作为例子来介绍PGO的使用,冒泡排序代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>

void bubble_sort(std::vector<int> &nums)
{
    int n = nums.size();
    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            if (nums[j] < nums[i]) {
                std::swap(nums[i], nums[j]);
            }
        }
    }
}

int main()
{
    srand(time(nullptr));
    int n = 30000;
    std::vector<int> nums(30000);
    for (int i = 0; i < 30000; ++i) {
        nums[i] = rand();
    }
    bubble_sort(nums);
    return 0;
}

编译时使用-fprofile-generate,运行程序进行训练,生成profile(.gcda文件)
2022-05-09T15:35:52.png
注:通常是在接近真实生产运行环境中进行训练,达到一定训练时间后,需要手动调用call (void)__gcov_flush()函数,否则不会生成
.gcda文件(正常需要程序终止才能生成)。

使用profile(*.gcda文件)进行再次编译
-fprofile-use
2022-05-09T15:36:12.png

进行反汇编:
2022-05-09T15:36:53.png

原函数反汇编:

0000000000400740 <_Z11bubble_sortRSt6vectorIiSaIiEE>:
  400740:   4c 8b 07                mov    (%rdi),%r8
  400743:   48 8b 47 08             mov    0x8(%rdi),%rax
  400747:   4c 29 c0                sub    %r8,%rax
  40074a:   48 c1 f8 02             sar    $0x2,%rax
  40074e:   89 c7                   mov    %eax,%edi
  400750:   85 c0                   test   %eax,%eax
  400752:   7e 44                   jle    400798 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x58>
  400754:   4c 89 c6                mov    %r8,%rsi
  400757:   44 8d 50 ff             lea    -0x1(%rax),%r10d
  40075b:   45 31 c9                xor    %r9d,%r9d
  40075e:   66 90                   xchg   %ax,%ax
  400760:   4c 89 c8                mov    %r9,%rax
  400763:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  400768:   41 8b 0c 80             mov    (%r8,%rax,4),%ecx
  40076c:   8b 16                   mov    (%rsi),%edx
  40076e:   39 d1                   cmp    %edx,%ecx
  400770:   7d 06                   jge    400778 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x38>
  400772:   89 0e                   mov    %ecx,(%rsi)
  400774:   41 89 14 80             mov    %edx,(%r8,%rax,4)
  400778:   48 83 c0 01             add    $0x1,%rax
  40077c:   39 c7                   cmp    %eax,%edi
  40077e:   7f e8                   jg     400768 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x28>
  400780:   49 8d 41 01             lea    0x1(%r9),%rax
  400784:   48 83 c6 04             add    $0x4,%rsi
  400788:   4d 39 d1                cmp    %r10,%r9
  40078b:   74 0b                   je     400798 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x58>
  40078d:   49 89 c1                mov    %rax,%r9
  400790:   eb ce                   jmp    400760 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x20>
  400792:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  400798:   c3                      retq   
  400799:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

PGO优化后反汇编:

0000000000400650 <_Z11bubble_sortRSt6vectorIiSaIiEE>:
  400650:   48 8b 37                mov    (%rdi),%rsi
  400653:   48 8b 47 08             mov    0x8(%rdi),%rax
  400657:   45 31 c9                xor    %r9d,%r9d
  40065a:   48 29 f0                sub    %rsi,%rax
  40065d:   4c 8d 56 04             lea    0x4(%rsi),%r10
  400661:   48 c1 f8 02             sar    $0x2,%rax
  400665:   41 89 c3                mov    %eax,%r11d
  400668:   44 8d 40 ff             lea    -0x1(%rax),%r8d
  40066c:   45 39 cb                cmp    %r9d,%r11d
  40066f:   7e 42                   jle    4006b3 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x63>
  400671:   44 89 c2                mov    %r8d,%edx
  400674:   48 89 f0                mov    %rsi,%rax
  400677:   44 29 ca                sub    %r9d,%edx
  40067a:   4c 01 ca                add    %r9,%rdx
  40067d:   49 8d 3c 92             lea    (%r10,%rdx,4),%rdi
  400681:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  400688:   8b 0e                   mov    (%rsi),%ecx
  40068a:   8b 10                   mov    (%rax),%edx
  40068c:   39 ca                   cmp    %ecx,%edx
  40068e:   7d 18                   jge    4006a8 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x58>
  400690:   89 16                   mov    %edx,(%rsi)
  400692:   48 83 c0 04             add    $0x4,%rax
  400696:   89 48 fc                mov    %ecx,-0x4(%rax)
  400699:   48 39 f8                cmp    %rdi,%rax
  40069c:   75 ea                   jne    400688 <_Z11bubble_sortRSt6vectorIiSaIiEE+0x38>
  40069e:   49 83 c1 01             add    $0x1,%r9
  4006a2:   48 83 c6 04             add    $0x4,%rsi
  4006a6:   eb c4                   jmp    40066c <_Z11bubble_sortRSt6vectorIiSaIiEE+0x1c>
  4006a8:   48 83 c0 04             add    $0x4,%rax
  4006ac:   48 39 f8                cmp    %rdi,%rax
  4006af:   75 d9                   jne    40068a <_Z11bubble_sortRSt6vectorIiSaIiEE+0x3a>
  4006b1:   eb eb                   jmp    40069e <_Z11bubble_sortRSt6vectorIiSaIiEE+0x4e>
  4006b3:   c3                      retq   

这种方式的缺点:
1.需要训练数据。如何保证训练数据与实际生产环境是相匹配的
2.配置文件生成开销大

第二种方法AutoFDO
1.使用perf record -b
2.使用autofdo tool(available on github)
create_gcov --binary=xxx --profile=perf.data --gcov=xxx.gcov --gcov-version=1
3.gcc xxx.cpp -g -O2 -fauto-profile=xxx.gcov -o xxx

2.编译选项优化

使用可以优化性能的编译选项,本文主要介绍项目过程中使用到的inline优化,实际生产环境中收益比较可观。

1.给只在本文件中调用的函数添加static前缀,打开-finlie-functions-called-once选项
2.-finline-function
3.f-inline-small-function


如何美化博客备案号页脚样式?


博客主题自带的备案号页脚样式不够美观,一直看不太顺眼,所以就有了这篇教程。如何美化备案号页脚?

css样式

.github-badge {
    display: inline-block;
    border-radius: 4px;

    text-shadow: none;
    font-size: 12px;
    color: #fff;
    line-height: 15px;

    background-color: #ABBAC3;

    margin-bottom: 5px;
}

.github-badge .badge-subject {
    display: inline-block;
    background-color: #4D4D4D;
    padding: 4px 4px 4px 6px;
    border-top-left-radius: 4px;
    border-bottom-left-radius: 4px;
}

.github-badge .badge-value {
    display: inline-block;
    padding: 4px 6px 4px 4px;
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
}

.github-badge .bg-brightgreen {
    background-color: #4c1 !important;
}
.github-badge .bg-green {
    background-color: #97CA00 !important;
}
.github-badge .bg-yellow {
    background-color: #dfb317 !important;
}
.github-badge .bg-yellowgreen {
    background-color: #a4a61d !important;
}
.github-badge .bg-orange {
    background-color: #fe7d37 !important;
}
.github-badge .bg-red {
    background-color: #e05d44 !important;
}
.github-badge .bg-blue {
    background-color: #007ec6 !important;
}
.github-badge .bg-grey, .github-badge .bg-gray {
    background-color: #555 !important;
}
.github-badge .bg-lightgrey, .github-badge .bg-lightgray {
    background-color: #9f9f9f !important;
}

css样式添加方法

以下方法仅针对使用typecho handsome主题的小伙伴,其它还需自己酌情操作。
打开Typecho网站后台->外观->设置外观->开发者设置->自定义CSS,添加以上CSS样式。
添加自定义css

html代码

<div>
    <div class="github-badge">
        <span class="badge-subject">build</span><span class="badge-value bg-brightgreen">passing</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">build</span><span class="badge-value bg-red">failure</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">tests</span><span class="badge-value bg-green">185 passed, 7 skipped</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">tests</span><span class="badge-value">inaccessible</span>
    </div></div><div>
    <div class="github-badge">
        <span class="badge-subject">npm</span><span class="badge-value bg-blue">v5.5.1</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">node</span><span class="badge-value bg-brightgreen">&gt;=0.4.0</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">gem</span><span class="badge-value bg-orange">v0.2.5</span>
    </div></div><div>
    <div class="github-badge">
        <span class="badge-subject">stars</span><span class="badge-value bg-brightgreen">☆☆☆☆☆</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">node</span><span class="badge-value bg-yellowgreen">★★★☆☆</span>
    </div></div><div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-brightgreen">brightgreen</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-green">green</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-yellowgreen">yellowgreen</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-yellow">yellow</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-orange">orange</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-red">red</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-lightgrey">lightgrey</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value">grey</span>
    </div>
    <div class="github-badge">
        <span class="badge-subject">color</span><span class="badge-value bg-blue">blue</span>
    </div></div>

handsome主题使用方法

修改footer.php如下代码

<div class="wrapper bg-light">
     <span class="pull-right hidden-xs text-ellipsis">
      <?php $this->options->BottomInfo(); ?>

      </span>

      <span class="text-ellipsis">
      <?php $this->options->BottomleftInfo(); ?>

        <a class="github-badge">
         <span class="badge-subject">Copyright</span>
         <span class="badge-value bg-brightgreen">&copy;&nbsp;<?php echo date("Y");?></span>
        </a>
        <a class="github-badge" target="_blank" href="http://www.beian.miit.gov.cn">
         <span class="badge-subject">赣ICP备</span>
         <span class="badge-value bg-brightgreen">20009527号</span>
        </a>

        <a class="github-badge" target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo">
         <span class="badge-subject">赣公网安备</span>
         <span class="badge-value bg-brightgreen">36100202000255号</span>
        </a>

      </span>
    </div>

效果

修改后效果如下,顺眼多了
请输入图片描述


如何在备案期间不关闭网站?


博主最近想把服务器迁移到国内,自然就免不了要备案了。那么遇到一个头疼的问题,就是备案期间,管局要求网站不能访问。一般来说,备案的周期还是挺长的,关闭这么长时间还是对网站有不小的影响的。

那么有没有什么方法能够在备案期间不关闭网站,把影响降低到最小呢?答案是肯定的,继续往下看。

通常来说,备案主要涉及两个方面的审核,第一个是云服务器厂商的初审,第二个则是管局的审核。那么我想到的解决办法就是,只屏蔽这两个地区的ip即可。这样可以把影响降低到最小。那么接下来看如何实现屏蔽某个特定地区的ip(可精确到市级)。

废话不多说,直接上代码

<?php
    function get_client_ip() {
        $ip = $_SERVER['REMOTE_ADDR'];
        if (isset($_SERVER['HTTP_X_REAL_FORWARDED_FOR']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_REAL_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        }
        return $ip;
    }

    $ip = get_client_ip(); //获取访客IP
    $antecedents = $_SERVER['HTTP_REFERER']; //访客来路地址

    $verification1 = '江西省'; //需要屏蔽IP的省份
    $result1 = file_get_contents("http://ip-api.com/json/".$ip."?lang=zh-CN"); //IP数据库来自ip-api.com。
    $address1 = json_decode($result1, true);
    // echo("<script>console.log('".$address1['regionName']."');</script>");

    $verification2 = '江西'; //需要屏蔽IP的省份
    $result2 = file_get_contents("http://freeapi.ipip.net/".$ip); //IP数据库来自ipip.net。
    $address2 = json_decode($result2, true);
    // echo("<script>console.log('".$address2[1]."');</script>");

    // 判断访客IP是否属于江西省,是否来自百度,是否来自谷歌
    if (($address1['regionName'] == $verification1 || $address2[1] == $verification2) && strpos($antecedents, 'baidu') === false && strpos($antecedents, 'google') === false) {
        sleep(99999999); // 设置一个999999秒的等待。
        Header("HTTP/1.1 204 No Content");
        exit;
    }
?>

上面的代码是先获取用户的ip地址,然后利用ip地址库查询对应ip的国家,省份,城市等信息。ip-api.com的结果不是特别准确,所以又加上了ipip.net的免费api(还是比较准确的,就是免费api只有3个信息)。对api感兴趣的小伙伴可以直接去官网查看api使用说明。

将以上代码放在首页index.php的开头即可,然后对应地区就打不开首页了。


七大站长平台,助力SEO


七大站长平台

百度站长平台

百度站长平台可以说是目前国内站长使用最多的站长工具平台,当然这跟百度搜索强大的搜索流量直接挂钩,算是目前国内站长平台功能最完善的一个站长平台,对于网站管理和网站数据监测具有一定的参考意义,在国内站长平台这块算是排在首位。

百度站长平台入口:https://ziyuan.baidu.com/

谷歌站长平台

谷歌站长平台是全球最大搜索巨头谷歌推出的站长工具平台,跟百度站长平台一样功能基本很完善,算法更新也很频繁,虽然目前谷歌搜索退出了国内搜索市场,但是对于站长们来说,谷歌站长平台绝对是一个不可忽略的存在。

谷歌站长平台入口:https://www.google.com/webmasters/

360 站长平台

360 站长平台是依托于 360 搜索推出的站长平台,在国内勉强排上第二,相较于百度站长平台 36 站长很多功能不够细化,并且最近几年平台规则和算法更新也是偶尔来那么一下,很多站长对于它多少有点失望。

360 站长平台:http://zhanzhang.so.com/

头条站长平台

头条站长平台是是搜索行业新杀入的“黑马”头条搜索推出的,由于上线不久,平台很多功能处于不完善状态,处于开发阶段,不过虽然刚入行,但是头条搜索盯上就是业内的第一把交椅,跟百度搜索呛了好几回,站长们对于这个刚入行头条搜索也是抱以很大期望。

头条站长平台入口:https://zhanzhang.toutiao.com/

搜狗站长平台

搜狗站长平台是继百度和 360 之后上线的一个站长平台,功能相比前两家堪称简洁,只有一些基础的网站优化功能提供,再加上这几年优化行业有点不景气,搜狗搜索的流量也不上,搜狗站长平台几乎很少更新,目前站长学院的知识分享还停留在 17 年,有点落寞!

搜狗站长平台入口:http://zhanzhang.sogou.com/

神马站长平台

神马站长平台是依托 UC 浏览器和神马搜索衍生出的一个站长平台,背靠阿里,而因为流量来源大部分来自移动端因此神马搜索以及神马站长平台很多功能都偏向于移动端也是只有基础功能,跟搜狗一样神马站长平台平时几乎也没啥算法和优化通知。

神马站长平台入口:https://zhanzhang.sm.cn/

必应站长平台

必应站长平台是微软搜索旗下必应搜索推出的站长平台,因为一些原因在国内使用的站长不多,连带必应搜索在国内市场也一般。

必应站长平台入口:https://www.bing.com/toolbox/webmaster/


一个 JS 脚本实现网站预加载,提升页面加载速度


instant.page使用即时预加载技术,在用户点击之前预先加载页面。当用户的鼠标悬停在一个链接上超过 65 毫秒时,浏览器会对此页面进行预加载,当用户点击链接后,就从预加载的缓存中直接读取页面内容,从而达到缩短页面加载时间的目的。

以我博客为例,使用了这项技术后,当鼠标在一个链接停留超过 65 毫秒时,Network 里可以看见相关文章已经预加载出来了,而停留时间过短就不会预加载(红色部分,状态为 canceled)

使用方法:
将以下HTML代码放在</ body> 之前即可:
<script src="//instant.page/5.1.0" type="module" integrity="sha384-by67kQnR+pyfy8yWP4kPO12fHKRLHZPfEsiSXR8u2IKcTdxD805MGUXBzVPnkLHw"></script>

但是此脚本是官方的,储存在国外服务器,对国内访问不太友好,可以将该JS脚本储存到自己的服务器上,点此获取该JS脚本,然后再根据以下格式在</ body> 之前引用:
<script src="存放路径/instant.js" type="module"></script>

也可以直接使用我的,使用 jsDeliver CDN 加速,速度还可以:
<script src="https://cdn.jsdelivr.net/gh/smallmocha/BlogAssets/assets/instant.js" type="module"></script>