当前位置: 首页 > news >正文

那个网站做国外售货最好的推广平台排名

那个网站做国外售货,最好的推广平台排名,3g手机网站源码,wordpress自定义结构空白页jump label机制进入Linux内核已经很多很多年了,它的目的是 消除分支。 为了达到这个目的,jump label的手段是 修改分支处的代码。 ~把代码当做数据,代码和数据在冯诺伊曼计算机中得到了统一~ 本质上,jump…

jump label机制进入Linux内核已经很多很多年了,它的目的是 消除分支。 为了达到这个目的,jump label的手段是 修改分支处的代码。

~把代码当做数据,代码和数据在冯诺伊曼计算机中得到了统一~

本质上,jump label作用于下面的逻辑:

var = false;
...
if vardo_true
elsedo_false

静态拆分成了下面的两个逻辑,其一是:

jmp l_true
do_false
ret
l_true:do_true

或者,其二是:

nop
do_false
ret
l_true:do_true

但二者不能同时共存。 显然,这破坏了通用性和灵活性,带来了高效!

这相当于一个硬熔断,具体详情参见:
https://blog.csdn.net/dog250/article/details/6123517
【PS:这篇文章是我上周找到的,看完了才发现,竟然是我自己写的】


本文来一点可以看得见的东西,演示一下真实的jump label & static key。

先看下面的C代码:

#include <stdio.h>int main(int argc, char **argv)
{int E1, E2;E1 = atoi(argv[1]);E2 = atoi(argv[2]);if (E1) {printf("condition 1 is true\n");} else {printf("condition 1 is false\n");}if (E2) {printf("condition 2 is true\n");} else {printf("condition 2 is false\n");}return 0;
}

很简单的代码,也很正确。然而, 如果main函数是一个高频调用的函数,并且在E1,E2是不随着代码逻辑而发生变化,仅仅参数设定的情况下, 那么if语句尽量消除以消除不必要的分支预测,而这正是jump label的用武之地!

我们下面用jump label机制来重写上面的代码,请看:

// jump_label_demo.c
// gcc -DJUMP_LABEL -O jump_label_demo.c -o demo -g
#include <stdio.h>
#include <sys/mman.h>#ifdef JUMP_LABEL
struct entry {unsigned long code;unsigned long target;unsigned long key;
};#define MAX	2struct entry base __attribute__ ((section ("__jump_table"))) = {0};
void update_branch(int key)
{int i;char *page;struct entry *e = (struct entry *)((char *)&base - MAX*sizeof(struct entry));for (i = 0; i < MAX; i++) {e = e + i;if (e->key == key) {// 修改代码段unsigned int *code = (int *)((char *)e->code + 1);unsigned int offset = (unsigned int)(e->target - e->code - 5);page = (char *)((unsigned long)code & 0xffffffffffff1000);mprotect((void *)page, 4096, PROT_WRITE|PROT_READ|PROT_EXEC);*code = offset;mprotect((void *)page, 4096, PROT_READ|PROT_EXEC);break;}}
}#define STATIC_KEY_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t"
static __attribute__((always_inline)) inline static_branch_true(int enty)
{int ent = enty;asm goto ("1:"STATIC_KEY_INITIAL_NOP".pushsection __jump_table,  \"aw\" \n\t"// 定义三元组{本函数内联后标号1的地址,本函数内联后标号l_yes的地址,参数enty}".quad 1b, %l[l_yes], %c0\n\t"  ".popsection \n\t":: "i"(ent):: l_yes);return 0;
l_yes:return 1;
}
#endifint main(int argc, char **argv)
{int E1, E2;E1 = atoi(argv[1]);E2 = atoi(argv[2]);
#ifdef JUMP_LABELint e1 = 0x11223344;int e2 = 0xaabbccdd;printf("Just Jump label\n");if (E1) {update_branch(e1);}if (E2) {update_branch(e2);}
#endif#ifdef JUMP_LABELif (static_branch_true(e1)) {
#elseif (E1) {
#endifprintf("condition 1 is true\n");} else {printf("condition 1 is false\n");}
#ifdef JUMP_LABELif (static_branch_true(e2)) {
#elseif (E2) {
#endifprintf("condition 2 is true\n");} else {printf("condition 2 is false\n");}return 0;
}

定义JUMP_LABEL宏编译之,看看效果:

[root@localhost checker]# gcc -DJUMP_LABEL -O jump_label_demo.c -o demo -g
[root@localhost checker]# ./demo 1 0
Just Jump label
condition 1 is true
condition 2 is false
[root@localhost checker]# ./demo 0 1
Just Jump label
condition 1 is false
condition 2 is true

如何做到的呢?static_branch_true内联函数是如何判断true or false的呢?

事实上,jump label逻辑修改了代码段,取消了条件判断!这一切都是在update_branch中发生的。我们看下update_branch调用之前,main函数的汇编码:

(gdb) disassemble main
Dump of assembler code for function main:...0x0000000000400662 <+74>:	callq  0x4005ad <update_branch>// 0x0000000000400667 <+79> 记住这里的指令吧!0x0000000000400667 <+79>:	jmpq   0x40066c <main+84>0x000000000040066c <+84>:	jmp    0x40067a <main+98>0x000000000040066e <+86>:	mov    $0x400750,%edi0x0000000000400673 <+91>:	callq  0x400470 <puts@plt>

在执行了update_branch之后,main函数发生了变化:

(gdb) b main
Breakpoint 1 at 0x400618: file jump_label_demo.c, line 56.
(gdb) r 1 0
Starting program: /root/checker/./demo 1 0Breakpoint 1, main (argc=3, argv=0x7fffffffe428) at jump_label_demo.c:56
56	{
(gdb) next
59		E1 = atoi(argv[1]);
(gdb) next
60		E2 = atoi(argv[2]);
(gdb)
65		printf("Just Jump label\n");
(gdb)
Just Jump label
66		if (E1) {
(gdb)
67			update_branch(e1);
(gdb)
69		if (E2) {
(gdb) disassemble main
Dump of assembler code for function main:... 0x0000000000400662 <+74>:	callq  0x4005ad <update_branch>// 0x0000000000400667 <+79> 指令已经被修改为jmpq   0x40066e0x0000000000400667 <+79>:	jmpq   0x40066e <main+86>0x000000000040066c <+84>:	jmp    0x40067a <main+98>0x000000000040066e <+86>:	mov    $0x400750,%edi0x0000000000400673 <+91>:	callq  0x400470 <puts@plt>

看样子就是这么回事!

之所以这件事可以发生得如此简单,多亏了一个新的section,即__jump_table,我们通过objdump看看__jump_table的内容:

Contents of section __jump_table:601040 67064000 00000000 6e064000 00000000  g.@.....n.@.....601050 44332211 00000000 84064000 00000000  D3".......@.....601060 8b064000 00000000 ddccbbaa ffffffff  ..@.............601070 00000000 00000000 00000000 00000000  ................601080 00000000 00000000

通过jump_label_demo.c的struct entry结构体,我们直到这个section中包含了多个3元组,包含3个字段:

  • 需要修改的代码地址。
  • 需要jmp到的代码地址。
  • 匹配健。

我们看67064000 00000000按照小端就是0x400667,它就是需要修改的代码地址,而6e064000 00000000按照小端则是0x40066e:

400667:   e9 00 00 00 00          jmpq   40066c <main+0x54>
40066c:   eb 0c                   jmp    40067a <main+0x62>
40066e:   bf 50 07 40 00          mov    $0x400750,%edi

看来,这个__jump_table的item会将jmpq 40066c修改为jmpq 40066e,从而实现了 永久静态分支。

最后,__jump_table的内容就是在每一个内联的static_branch_true函数中被填充的,该参数的参数是一个key,它指示了branch entry三元组中的最后一个字段。

static_branch_true函数的内联非常重要,它实现了将branch entry三元组数据直接插入到__jump_table section,而不是共享同一个函数体。

总之,如果你看代码还是觉得别扭,手敲一遍我上面的示例程序,就理解了,内核里面的也就这么回事,总结一句话:

  • 依靠运行时修改代码而不是依靠状态数据来控制执行流。

我不知道这对于所谓的 通用计算机程序设计 是不是反其道而行之,但在效果上,它确实是一匹好马。不禁感叹, 硬编码读起来是丑陋的,但执行起来却是高效的!

灵活性换高效率,得不偿失,我是这样以为。jump label的本质在于, 将同时刻存在的一套代码沿着时间线在可预期的固定时间点上分割成逻辑相反的两套代码。

硬件性能的提升将会证明jump label就是个笑话。

说两句好话,Linux内核参数,sysctl变量基本上就可以通过jump label来运作,从而替代if判断。

周末了,杭州的纯流民要回嘉定了,大巴上写点东西。


浙江温州皮鞋湿,下雨进水不会胖!

http://www.lbrq.cn/news/2374003.html

相关文章:

  • 四川网站建设方案指数平滑法
  • 合肥企业网站seo网站排名优化服务
  • app在线开发网站建设网站收录软件
  • 上海武汉阳网站建设免费域名注册官网
  • 郴州吧百度seo详解
  • 做图片视频的网站有哪些问题吗北京网站制作建设公司
  • 公司网站报价今天国际新闻
  • 蚌埠市建设工程质监站网站制作网站的基本流程
  • 网站做的好的公司名称好搜网惠州seo
  • 产品的营销渠道有哪些seo网络推广哪家专业
  • 推广是什么百度禁止seo推广
  • 大连网站建设那家好深圳营销推广引流公司
  • 国泰君安建设工程官方网站企业网站推广渠道有哪些
  • 网站pv uv是什么意思互联网营销师培训内容
  • 西安cms建站网站搭建工具
  • 网站建设服务公司有用吗百度公司注册地址在哪里
  • 泰州网站建设托管谷歌优化排名公司
  • 做长海报的网站济南网络推广公司
  • 一般可以建些什么种类的网站百度荤seo公司
  • 荔湾区网站建设免费推广引流怎么做
  • 有投标功能的网站怎么做东莞网络营销公司
  • 一般给公司做网站怎么收费自媒体营销代理
  • 公司设计网站需要注意哪些网站优化分析
  • 苏州建设网站制作目前推广软件
  • 27岁女生学前端开发晚吗长沙优化官网服务
  • 上海手机网站建设网络营销成功案例3篇
  • 什么网站可以接活在家做高级seo培训
  • 做一个购物网站价格站长查询站长工具
  • 大屏可视化ui设计重庆seo顾问服务
  • 系统开发软件有哪些重庆seo务
  • RuoYi-Cloud 定制微服务
  • 创建项目:使用Spring Initializr初始化你的第一个应用程序
  • MailAgentProcess.getInstance
  • Java学习--JVM(2)
  • 解决“Windows 无法启动服务”问题指南
  • FCN语义分割笔记(1)