├── _data ├── links.yml └── brume.yml ├── assets ├── CNN.png ├── linker_1.png ├── linker_2.png ├── linker_3.png ├── linker_4.png ├── linker_5.png ├── linker_6.png ├── linker_7.png ├── linker_8.png ├── linker_9.png ├── de_dy_h_1.png ├── de_dy_h_2.png ├── linker_10.png ├── ImageNet-CNN.png ├── convnet_y_h_1.png ├── convnet_y_h_2.png ├── convnet_y_h_3.png ├── convnet_y_h_4.png ├── cuttingstock.pdf ├── convnet_backpro.png ├── convnet_dE_dw_k_1.png ├── convnet_dE_dw_k_2.png ├── convnet_dE_dw_k_3.png ├── convnet_dE_dw_k_4.png ├── convnet_dE_dw_k_5.png ├── convnet_dE_dw_k_6.png ├── convnet_dE_dw_k_7.png ├── convnet_dE_dw_k_8.png ├── convnet_dE_dw_k_9.png ├── convnet_sampling_1.png ├── convnet_sampling_2.png ├── deep-learning-evolution.doc ├── deep-learning-graphic.jpg └── deep_learning_vision_plan.ppt ├── push ├── public ├── images │ ├── eagle.png │ ├── flower.png │ ├── logo.png │ └── favicon.ico ├── css │ ├── responsive.gs.12col.css │ ├── main.css │ ├── _syntax.scss │ ├── main.scss │ └── animate.min.css └── js │ └── jquery.fitvids.js ├── _draft ├── sorting.md ├── python-extension.md └── data-structure.md ├── .gitignore ├── _layouts ├── page.html ├── post.html └── default.html ├── _config.yml ├── _includes ├── navigation.html └── head.html ├── package.json ├── about └── index.md ├── _posts ├── 2014-10-23-skynet-rwlock.md ├── 2014-05-05-convnet-subsampling-forward.md ├── 2014-04-02-pointer-and-reference.md ├── 2014-04-14-linux-user-management.md ├── 2014-03-28-cpp-type.md ├── 2014-05-08-convnet-subsampling-backward.md ├── 2014-04-30-convnet-convolutional-forward.md ├── 2014-04-12-makefile.md ├── 2014-04-15-deep-learning-vision-overview.md ├── 2014-05-07-convnet-convolutional-backward.md └── 2014-05-11-linker.md ├── 404.html ├── feed.xml ├── LICENSE.md ├── gulpfile.js ├── index.html └── README.md /_data/links.yml: -------------------------------------------------------------------------------- 1 | - url: / 2 | title: Home 3 | 4 | - url: /about 5 | title: About -------------------------------------------------------------------------------- /assets/CNN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/CNN.png -------------------------------------------------------------------------------- /assets/linker_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_1.png -------------------------------------------------------------------------------- /assets/linker_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_2.png -------------------------------------------------------------------------------- /assets/linker_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_3.png -------------------------------------------------------------------------------- /assets/linker_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_4.png -------------------------------------------------------------------------------- /assets/linker_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_5.png -------------------------------------------------------------------------------- /assets/linker_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_6.png -------------------------------------------------------------------------------- /assets/linker_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_7.png -------------------------------------------------------------------------------- /assets/linker_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_8.png -------------------------------------------------------------------------------- /assets/linker_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_9.png -------------------------------------------------------------------------------- /push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | git add --all 4 | git commit -a -m "post" 5 | git push origin master 6 | -------------------------------------------------------------------------------- /assets/de_dy_h_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/de_dy_h_1.png -------------------------------------------------------------------------------- /assets/de_dy_h_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/de_dy_h_2.png -------------------------------------------------------------------------------- /assets/linker_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/linker_10.png -------------------------------------------------------------------------------- /assets/ImageNet-CNN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/ImageNet-CNN.png -------------------------------------------------------------------------------- /assets/convnet_y_h_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_y_h_1.png -------------------------------------------------------------------------------- /assets/convnet_y_h_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_y_h_2.png -------------------------------------------------------------------------------- /assets/convnet_y_h_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_y_h_3.png -------------------------------------------------------------------------------- /assets/convnet_y_h_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_y_h_4.png -------------------------------------------------------------------------------- /assets/cuttingstock.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/cuttingstock.pdf -------------------------------------------------------------------------------- /public/images/eagle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/public/images/eagle.png -------------------------------------------------------------------------------- /public/images/flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/public/images/flower.png -------------------------------------------------------------------------------- /public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/public/images/logo.png -------------------------------------------------------------------------------- /assets/convnet_backpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_backpro.png -------------------------------------------------------------------------------- /public/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/public/images/favicon.ico -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_1.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_2.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_3.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_4.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_5.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_6.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_7.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_8.png -------------------------------------------------------------------------------- /assets/convnet_dE_dw_k_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_dE_dw_k_9.png -------------------------------------------------------------------------------- /assets/convnet_sampling_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_sampling_1.png -------------------------------------------------------------------------------- /assets/convnet_sampling_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/convnet_sampling_2.png -------------------------------------------------------------------------------- /_draft/sorting.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "排序算法杂记" 4 | description: "" 5 | category: 6 | tags: ["c/c++"] 7 | --- 8 | -------------------------------------------------------------------------------- /assets/deep-learning-evolution.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/deep-learning-evolution.doc -------------------------------------------------------------------------------- /assets/deep-learning-graphic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/deep-learning-graphic.jpg -------------------------------------------------------------------------------- /_data/brume.yml: -------------------------------------------------------------------------------- 1 | name: Rolexye 2 | author: Aigars Dzerviniks 3 | description: It's simple. It's easy to use. It's a Jekyll theme. 4 | -------------------------------------------------------------------------------- /assets/deep_learning_vision_plan.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roles/roles.github.com/master/assets/deep_learning_vision_plan.ppt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _site/* 2 | _theme_packages/* 3 | 4 | Thumbs.db 5 | .DS_Store 6 | 7 | !.gitkeep 8 | 9 | .rbenv-version 10 | .rvmrc 11 | *.swp 12 | -------------------------------------------------------------------------------- /_draft/python-extension.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "编写python的c++扩展模块" 4 | description: "" 5 | category: 6 | tags: ["c/c++", "python"] 7 | --- 8 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |

{{ page.title }}

7 | 8 | {{ content }} 9 |
10 | -------------------------------------------------------------------------------- /_draft/data-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "实用数据结构(一)——优先队列" 4 | description: "" 5 | category: 6 | tags: ["c/c++", "python"] 7 | --- 8 | 9 | -- 10 | 优先队列实现多路归并 11 | -- 12 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | #markdown: kramdown 2 | markdown: redcarpet 3 | pygments: true 4 | permalink: /:title 5 | 6 | url: http://roles.github.com 7 | baseurl: 8 | 9 | redcarpet: 10 | extensions: [strikethrough, tables] 11 | -------------------------------------------------------------------------------- /_includes/navigation.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "gulp-concat": "*", 4 | "gulp-uglify": "*", 5 | "gulp-util": "*", 6 | "gulp": "*", 7 | "gulp-sass": "*", 8 | "gulp-minify-css": "*", 9 | "gulp-coffee": "*", 10 | "gulp-autoprefixer": "*" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | 7 |

{{ page.title }}

8 | 9 | {{ content }} 10 |
11 | -------------------------------------------------------------------------------- /about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: About 4 | --- 5 | 6 | 叶永盛,C/C++程序员,deep learner 7 | 8 | 履历: 9 | 10 | + 2009-2013:华中科技大学电信系学士 11 | + 2013- :华中科技大学互联网中心硕士 12 | 13 | 研究方向:深度学习算法在文本处理,生物信息,计算机视觉的应用,GPU编程,Linux服务器运维 14 | 15 | github: [github/roles](http://github.com/roles) 16 | -------------------------------------------------------------------------------- /_posts/2014-10-23-skynet-rwlock.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "skynet源码分析-读写锁rwlock" 4 | description: "" 5 | category: 6 | tags: ["c/c++", "skynet"] 7 | --- 8 | 9 | ## GCC的原子操作 10 | 11 | 参考自https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html 12 | 13 | * full内存屏障:双向屏障,屏障之前的读写操作全部执行之后,再执行屏障之后的读写操作 14 | * acquire内存屏障:单向屏障,保证其后的读写操作不会提前到屏障之前 15 | * release内存屏障:单向屏障,保证之前的读写操作已经生效 16 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: none 3 | title: Limbo 4 | --- 5 | 6 | 7 | 8 | 9 | {% include head.html %} 10 | 11 | 12 |
13 |

404

14 |

15 | Did You steal the content from me? No?! Well, somebody did, and you're the only one here. 16 |

17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /_posts/2014-05-05-convnet-subsampling-forward.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "卷积神经网络GPU实现(二):采样层" 4 | description: "" 5 | category: 6 | tags: ["deep learning"] 7 | --- 8 | 9 | 采样层的任务是将32\*32的feature map每一个4*4的块求其均值映射到sample map上 10 | 11 | block的结构为32\*8,每一个block负责一个feature map的归约计算, 12 | 在threadx方向上,**每四个thread共同负责一个4\*4块的归约计算** 13 | 14 | 15 | screenshot 16 | 17 | 18 | 以左上角黄色的四个thread为例: 19 | 20 | 1. 四个thread分别将4\*4块的4列归约到第一行, 21 | 2. 然后载入到share memory的第一列,全部线程都完成后,64\*4的share memory载入完成, 22 | 3. 然后针对share memory将四行归约到第一行,即可得到64个subsampling target, 对应到8\*8的sampling map上 23 | 24 | 25 | screenshot 26 | 27 | -------------------------------------------------------------------------------- /_posts/2014-04-02-pointer-and-reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "指针和引用" 4 | description: "" 5 | category: 6 | tags: ["c/c++"] 7 | --- 8 | `返回值为引用`如果函数返回的是引用,调用者的处理方式跟其声明有关 9 | 10 | {% highlight c++ %} 11 | string& foo(string& x){ 12 | x = "hello " + x; 13 | return x; 14 | } 15 | 16 | int main(){ 17 | string x{"rolex"}; 18 | string& y = foo(x); 19 | y += " test"; 20 | cout << "x : " << x << endl; 21 | cout << "y : " << y << endl; 22 | return 0; 23 | } 24 | {% endhighlight %} 25 | 26 | 这种情况下y是x的引用,对y的修改会影响x,因此输出为 27 | >x : hello rolex test 28 | >y : hello rolex test 29 | 30 | {% highlight c++ %} 31 | string& foo(string& x){ 32 | x = "hello " + x; 33 | return x; 34 | } 35 | 36 | int main(){ 37 | string x{"rolex"}; 38 | string y{foo(x)}; 39 | y += " test"; 40 | cout << "x : " << x << endl; 41 | cout << "y : " << y << endl; 42 | return 0; 43 | } 44 | {% endhighlight %} 45 | 46 | 这种情况下y是x的引用来进行初始化,对y的修改不会影响x,因此输出为 47 | >x : hello rolex 48 | >y : hello rolex test 49 | -------------------------------------------------------------------------------- /_posts/2014-04-14-linux-user-management.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "linux用户管理" 4 | description: "" 5 | category: 6 | tags: ["linux"] 7 | --- 8 | ##文件和目录的权限 9 | 10 | 每个文件和目录都有9为权限符,如`rwxr-x---(750)`,所有者以及所有者用户组 11 | 前三位表示所有者用户的权限为读写和执行 12 | 中间三位表示所有者用户组的权限为读和执行 13 | 最后三位表示其他用户的权限为不可读写执行 14 | 15 | 对于目录而言,写权限即所有涉及修改目录内文件结构的操作 16 | 执行权限则为能否进入该目录成为工作目录 17 | 18 | 修改的命令主要有`chmod,chgrp,chown` 19 | 20 | ##添加和修改用户信息 21 | 22 | 在/etc/passwd中保存了用户的信息 23 | 如dmtsai:x:503:504::/home/dmtsai:/bin/bash表示 24 | 用户名为dmtsai 25 | UID为503 26 | GID为504 27 | 工作目录为/home/dmtsai 28 | 默认shell为/bin/bash 29 | 30 | 一个用户可以同时属于多个组,但初始分组是当用户登录时设定的分组 31 | {% highlight bash %} 32 | #创建分组 33 | groupadd data 34 | 35 | #添加用户,创建/home/yys作为其默认目录 36 | useradd -g data yys 37 | 38 | #添加用户,不创建目录,以/home/yys为目录并且以data为初始分组,www为有效分组 39 | useradd -g data -G www -M -d /home/yys yys 40 | 41 | #设定用户密码,root执行 42 | passwd yys 43 | 44 | #添加heatmap作为有效分组 45 | usermod -G heatmap yys 46 | 47 | #查看用户信息 48 | finger yys 49 | id yys 50 | 51 | #切换当前用户的主分组为www 52 | newgrp www 53 | {% endhighlight %} 54 | -------------------------------------------------------------------------------- /feed.xml: -------------------------------------------------------------------------------- 1 | --- 2 | layout: none 3 | --- 4 | 5 | 6 | 7 | {{ site.data.brume.name }} 8 | {{ site.url }} 9 | 10 | {{ site.data.brume.description }} 11 | en-us 12 | {{ site.time | date: "%a, %d %b %Y %H:%M:%S %z" }} 13 | {{ site.time | date: "%a, %d %b %Y %H:%M:%S %z" }} 14 | 15 | {% for post in site.posts limit: 10 %} 16 | 17 | {{ post.title }} 18 | {{ site.url }}{{ site.baseurl }}{{ post.url }} 19 | {{ post.date | date: "%a, %d %b %Y %H:%M:%S %z" }} 20 | {{ site.data.brume.author}} 21 | {{ post.content | xml_escape }} 22 | 23 | {% endfor %} 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /_posts/2014-03-28-cpp-type.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "C++类型探究" 4 | description: "" 5 | category: 6 | tags: ["c/c++"] 7 | --- 8 | ## char类型的转换 9 | 10 | 字符类型有三种基本的类型`char`, `unsigned char`, `signed char`。 11 | 一般来说,`char`就是`signed char`,至少是8bit 12 | 13 | {% highlight c++ %} 14 | char c = 255; 15 | int i = c; 16 | {% endhighlight %} 17 | 18 | 上面这段程序的结果会根据不同的c++实现不同有差异, 19 | 如果char默认为signed char,则i的值为-1,如果char默认为unsigned char, 20 | i的值为255 21 | 22 | 根据计算机的存储方式,255的字节表示为0xFF,在char转换到int的过程中, 23 | 最高位1被作为符号为保留到i中,在扩展的位置上补1, 24 | 如果char为unsigned char,则会在扩展的时候补0. 25 | 26 | ## 原码,反码,补码 27 | 28 | **原码** 29 | 正数的原码是其自身,以8bit为例,+1的原码为`0000 0001`, 30 | 负数的原码是其最高位置1的后,-1的原码为`1000 0001` 31 | 32 | **反码** 33 | 负数的反码是符号位不变,其余各位置反, 34 | -1的反码为`1111 1110` 35 | 36 | **补码** 37 | 负数的补码是反码+1,-1的补码为`1111 1111` 38 | 39 | 在计算机内部对于符号数的存储均为其补码 40 | 41 | ## char类型的字面量赋值 42 | 43 | {% highlight c++ %} 44 | signed char sc = -140; 45 | cout << sc; 46 | {% endhighlight %} 47 | 48 | 符号型的char范围是-127到127,-140超过了这个范围,故在进行赋值操作是会进行截取. 49 | 50 | -140的16bit原码为`10000000 140`,补码为`11111111 116`,116由255-140+1得到, 51 | 故最终sc的值为116,输出't' 52 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Aigars 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | gutil = require('gulp-util'), 3 | uglify = require('gulp-uglify'), 4 | concat = require('gulp-concat'), 5 | coffee = require('gulp-coffee'), 6 | sass = require('gulp-sass'), 7 | minify = require('gulp-minify-css'), 8 | prefix = require('gulp-autoprefixer'); 9 | 10 | var paths = { 11 | scripts: ['public/js/*.coffee'], 12 | stylesheets: ['public/css/*.scss'] 13 | }; 14 | 15 | gulp.task('scripts', function () { 16 | gulp.src(paths.scripts) 17 | .pipe(coffee({ bare: true }).on('error', gutil.log)) 18 | .pipe(uglify()) 19 | .pipe(concat('main.js')) 20 | .pipe(gulp.dest('./public/js')); 21 | }); 22 | 23 | gulp.task('stylesheets', function () { 24 | gulp.src(paths.stylesheets) 25 | .pipe(sass()) 26 | .pipe(prefix("last 1 version")) 27 | .pipe(minify()) 28 | .pipe(gulp.dest('public/css')); 29 | }); 30 | 31 | gulp.task('watch', function () { 32 | gulp.watch(paths.scripts, ['scripts']); 33 | gulp.watch(paths.stylesheets, ['stylesheets']); 34 | }); 35 | 36 | gulp.task('default', ['scripts', 'stylesheets', 'watch']); 37 | -------------------------------------------------------------------------------- /_posts/2014-05-08-convnet-subsampling-backward.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "卷积神经网络GPU实现(五):采样层反馈" 4 | description: "" 5 | category: 6 | tags: ["deep learning"] 7 | --- 8 | 9 | 采样层反馈的任务是采样层的逆过程,**将8\*8的dE\_dy\_i扩展到32\*32的dE\_dy\_h(乘1/16)** 10 | 11 | ###数据录入 12 | 13 | 由于在dE\_dy\_i的计算中用到了cublas库,因此**dE\_dy\_i是column major的** 14 | 15 | - dE\_dy\_i的内存布局为**numCases \* numFilters \* 8 \* 8**,这里不妨假设numFilters=16 16 | - grid的布局与dE\_dy\_i是一致的,**gridDim.x = numFilters \* 8 \* 8**,**gridDim.y = numCases / 16** 17 | - block结构是16 \* 16,**一张图片的计算会分在4个block中进行**(如图所示, 8\*8=16\*4) 18 | 19 | screenshot 20 | 21 | 如上图所示,在数据的录入过程中,每个block会将其在dE\_dy\_i所对应的数据载入到share memory中(shDerivs) 22 | 23 | ###扩展计算 24 | 25 | - 每个block的计算的都会涉及到16张图的1/4的计算 26 | - 计算的过程中,**threadIdx.x方向相邻的4个thread为一组**共同进行shDerivs中4个点的扩展计算(如下图黄色的部分涉及到image1,5,9,13) 27 | - 在一次计算中,4个thread分别将shDerivs中的一个点扩展到对应image中的4列 28 | - 蓝色部分表示tidx为60-63的4个线程,它们与黄色部分都在处理同一张image 29 | 30 | screenshot 31 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head.html %} 5 | 6 | 7 |
8 |
9 |
10 | 11 | 13 |
14 | {% include navigation.html %} 15 |
16 | 17 | {{ content }} 18 | 19 | 24 |
25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Home 4 | --- 5 | 6 |
7 | {% for post in site.posts %} 8 | {% unless post.next %} 9 | 10 | {% unless forloop.first %}{% endunless %} 11 | 12 |
13 |

{{ post.date | date: '%Y' }}

14 |
15 | 16 | {% else %} 17 | {% capture year %}{{ post.date | date: '%Y' }}{% endcapture %} 18 | {% capture nyear %}{{ post.next.date | date: '%Y' }}{% endcapture %} 19 | {% if year != nyear %} 20 | 21 | {% unless forloop.first %}
{% endunless %} 22 | 23 |
24 |

{{ post.date | date: '%Y' }}

25 |
26 | {% endif %} 27 | {% endunless %} 28 | 29 | 35 | 36 | {% if forloop.last %}
{% endif %} 37 | 38 | {% endfor %} 39 |
40 | -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{ page.title }} · {{ site.data.brume.name }} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% if site.paginate %} 26 | 27 | 28 | {% endif %} 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /_posts/2014-04-30-convnet-convolutional-forward.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "卷积神经网络GPU实现(一):卷积层" 4 | description: "" 5 | category: 6 | tags: ["deep learning"] 7 | --- 8 | 9 | ###存储结构 10 | 11 | 原图是32\*32大小的图片,有3个颜色channel,存储格式为: 12 | 13 | screenshot 14 | 15 | filter为8\*8大小的块,为了使经过卷积层之后的feature map也是32\*32便于后面的计算 16 | 在原图的基础上进行了补白(padding): 17 | 18 | screenshot 19 | 20 | ###数据录入 21 | 22 | grid的结构是numCases\*numFilters,即**每一个block负责一张图片针对一个filter的卷积计算** 23 | block的结构是32\*8,share memory中保存图片的数组shImg结构是39\*16,因此数据的录入和计算的过程都分为四个部分,如下图所示(阴影为载入share memory的部分): 24 | 25 | screenshot 26 | 27 | ###计算过程 28 | 29 | 分别以左上角的**threadA(threadIdx.x=0, threadIdx.y=0)**和右下角的**threadB(threadIdx.x=31, threadIdx.y=7)**的计算和对应原图和share memory的关系来说明: 30 | 31 | screenshot 32 | 33 | - threadA在四个子过程分别计算图示中feature map中的四个点,share memory中始终对应左上角8\*8的区域,对应到原图为四个阴影块的计算 34 | - threadB同理为对应的右下角 35 | -------------------------------------------------------------------------------- /_posts/2014-04-12-makefile.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Makefile基本概念" 4 | description: "" 5 | category: 6 | tags: ["c/c++"] 7 | --- 8 | ##基本命令 9 | 10 | {% highlight make %} 11 | #最基本的makefile命令,target会自动查询其依赖文件(depA,depB) 12 | #寻找依赖文件的显式规则,尝试其符合的隐式规则,执行相应的命令进行编译 13 | 14 | target: depA depB 15 | command 16 | command 17 | 18 | #多个target会进行分解,下面两个是等价的 19 | 20 | targetA targetB: depA depB 21 | command 22 | command 23 | 24 | targetA: depA depB 25 | command 26 | command 27 | 28 | targetB: depA depB 29 | command 30 | command 31 | {% endhighlight %} 32 | 33 | ##Makefile的执行 34 | 35 | {% highlight make %} 36 | CC=g++ 37 | CS106LIB=../lib/cs106lib.a 38 | LDFLAGS=-lm $(CS106LIB) 39 | CPPFLAGS=-g -I../include -std=c++0x 40 | VPATH=../include ../lib 41 | PROG=warmupA warmupB recursion 42 | 43 | all: $(PROG) 44 | 45 | $(PROG): % : %.o lexicon.o $(CS106LIB) 46 | $(CC) $^ $(LDFLAGS) -o $@ 47 | 48 | .PHONY: clean 49 | clean: 50 | rm -f *.o $(PROG) 51 | {% endhighlight %} 52 | 53 | 首先直接敲make,默认执行的是第一个target,在这里是all 54 | all的依赖是$PROG变量定义的,所以在执行all之前都会更新$PROG定义的target 55 | 56 | make是一个自顶向下寻找依赖,自底向上逐步编译的过程 57 | all依赖warmupA,warmupA会找其符合的编译规则 58 | `$(PROG): % : %.o lexicon.o $(CS106LIB)` 59 | 这一句是指%匹配$PROG当中的项,匹配成功则以其为值,替代之后的% 60 | 因此,warmupA实际的规则是 61 | `warmupA : warmupA.o lexicon.o ../lib/cs106lib.a` 62 | 63 | 执行的编译语句中设计到了一些通配符 64 | - $@ 当前target 65 | - $^ 规则中所有依赖文件 66 | - $< 规则中第一个依赖文件 67 | 68 | `$(CC) $^ $(LDFLAGS) -o $@`这一句的实际效果是 69 | `g++ warmupA.o lexicon.o ../lib/cs106lib.a -o warmupA` 70 | 71 | 为了生成warmupA.o和lexicon.o,make继续寻找.o文件的生成规则 72 | 但是这个在Makefile中没有定义,因此make会执行内置的隐式规则: 73 | `$(COMPILE.c) $(OUTPUT_OPTION) $<`且有 74 | `COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c`和 75 | `OUTPUT_OPTION = -o $@`,从而会调用到这些编译规则 76 | 77 | .PHONY指明一个target是伪target,不会生成一个对象的 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # brume 2 | 3 | I am not a designer so I cannot impress you with breathtaking Jekyll themes, but brume is something that just came to my mind and I had to build it. It is a clean and simple theme, which has an index page that lists all your blog posts divided by year and an about page. brume uses redcarpet as the Markdown processor with strikethrough extension enabled by default (so you can use ~~ to strike out words). 4 | 5 | This is how the "Home" page looks like. 6 | 7 | ![Home](https://dl.dropboxusercontent.com/u/9924988/Screen%20Shot%202014-02-26%20at%2018.48.57.png) 8 | 9 | And this is a single post. 10 | 11 | ![Home](https://dl.dropboxusercontent.com/u/9924988/Screen%20Shot%202014-04-06%20at%2012.56.08.png) 12 | 13 | ## Usage 14 | 15 | **Important:** The latest version of brume uses `site.baseurl` for links, therefore, if you want to put your site in a subdirectory, update the *_config.yml* file! 16 | 17 | - Download the ZIP file and extract it's contents. 18 | - Open *_config.yml* file and enter your site's URL and add additional configuration or update the existing one if needed. 19 | - Open *_data/brume.yml* file and fill in values for site name (site title), author (your name) and description (blog description). This file contains all the custom information about your page. You can access it using `site.data.brume` object. 20 | - Open *about/index.md* file and add information about you or your site. You can delete this file and directory if not needed. 21 | - Open *_data/links.yml* and add additional links or update the existing ones that you want to be displayed in the navigation menu. 22 | - If you don't want to use CC BY-NC 4.0 licence for the content, then you should change the footer text, which is located in *_layouts/default.html*. 23 | - Generate your site and be happy! 24 | 25 | ## Theme customization 26 | 27 | This theme has 4 predefined colors that can be used for links: 28 | 29 | - azul 30 | - ruby 31 | - amber 32 | - avocado 33 | 34 | ![Color Examples](https://dl.dropboxusercontent.com/u/9924988/colors_new.png) 35 | 36 | By default it uses *azure*, but if you want to select another one just change the second class of `container` div in *_layouts/default.html* to one of the provided names. 37 | 38 | Express your thoughts about brume on Twitter [@aigarsdz](http://twitter.com/aigarsdz), and help me make it better! 39 | -------------------------------------------------------------------------------- /_posts/2014-04-15-deep-learning-vision-overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "deep learning视觉应用概述" 4 | description: "deep learning视觉应用概述" 5 | category: 6 | tags: ["deep learning"] 7 | --- 8 | ##神经网络算法 9 | 10 | 经典的神经网络算法在构造多层网络时,用梯度下降的方法, 11 | 往往会在训练的过程中陷入到局部最小值难以跳出, 12 | 而浅层结构又难以得到high level的特征 13 | 同时,如果简单的将图像作为一个像素vector来输入, 14 | 又会忽略了图像本身邻近像素点的关联性 15 | 16 | 1998年,Lecun提出了卷积神经网络的算法应用于手写体识别(`Gradient-Based Learning Applied to Document Recognition`) 17 | 其模型结构大致如下: 18 | 19 | 20 | screenshot 21 | 22 | 23 | `卷积层` 每一个`feature map`选取一个filter(5\*5),一个filter共用其权重值W 24 | filter作为滑动窗口一样选取原图中的一定区域像素点进行线性运算(h=Wx) 25 | 通过遍历整张原始图片,即可得到一个feature map 26 | 设定多个feature map,作为对不同特征的提取 27 | 28 | `采样层` 对feature中的一个小区域(2\*2)再进行聚合操作(线性组合,取最大值等) 29 | 得到一个更小的feature 30 | 31 | ##卷积玻尔兹曼机 32 | 33 | 随着deep learning的流行,玻尔兹曼机的无监督预训练得到了广泛的应用 34 | 在图像应用中,卷积算法与玻尔兹曼机的结合对unlabel image的特征提取取得了很好的效果 35 | 36 | Lee和Andrew Ng的论文(`Unsupervised Learning of Hierarchical Representations with Convolutional Deep Belief Networks`) 37 | 用三层的玻尔兹曼机分别得到了人脸中不同层次的特征提取 38 | 39 | 40 | screenshot 41 | 42 | 43 | ##大规模无监督训练 44 | 45 | 很多研究者则通过提供更多的训练样本,训练更大规模的模型 46 | 47 | 2012年,Stanford和Google的一次合作(`Building High-level Features Using Large Scale Unsupervised Learning`), 48 | 尝试用1000台机器,16000个核来进行集群计算,训练10亿个参数的网络 49 | 50 | 而如此庞大的计算机集群研究者一般很难做到,因此提出了利用GPU进行高性能计算的方案 51 | hinton在(`ImageNet Classification with Deep Convolutional Neural Networks`)针对ImageNet中海量的图片 52 | 用单机双GPU的方式实现了一个多重CNN,进行图片分类,其模型如下: 53 | 54 | screenshot 55 | 56 | 57 | 进一步改进的方案是使用多机多GPU的集群方式进行计算,但其中也涉及到一些难点: 58 | - GPU服务器之间的通信瓶颈 59 | - 控制计算和多GPU通信的复杂算法设计 60 | 61 | Coates和Andrew Ng(`Deep learning with COTS HPC systems`)使用了Infiniband进行集群机器的内部通信 62 | 解决了以太网的数据传输瓶颈,同时利用MPI和GPU计算的框架,有效的简化了对集群数据通信的控制 63 | 最终以3台4GPU的机器实现了2012年Google 1000台CPU集群的效果 64 | 65 | [工作规划](/assets/deep_learning_vision_plan.ppt) 66 | -------------------------------------------------------------------------------- /public/css/responsive.gs.12col.css: -------------------------------------------------------------------------------- 1 | /* 12 COLUMN : RESPONSIVE GRID SYSTEM 2 | DEVELOPER : DENIS LEBLANC 3 | URL : http://responsive.gs 4 | VERSION : 3.0 5 | LICENSE : GPL & MIT */ 6 | 7 | 8 | /* SET ALL ELEMENTS TO BOX-SIZING : BORDER-BOX */ 9 | * { 10 | -webkit-box-sizing: border-box; 11 | -moz-box-sizing: border-box; 12 | box-sizing: border-box; 13 | *behavior: url(/scripts/boxsizing.htc); 14 | /* If you need support for IE7 and lower make 15 | sure the boxsizing.htc file is linked properly. 16 | More info here: https://github.com/Schepp/box-sizing-polyfill */ 17 | } 18 | 19 | 20 | /* MAIN CONTAINER 21 | Set the width to whatever you want the width of your site to be. */ 22 | .container { 23 | max-width: 800px; 24 | margin: 0 auto; 25 | } 26 | 27 | 28 | 29 | /* SELF CLEARING FLOATS - CLEARFIX METHOD */ 30 | .container:after, 31 | .row:after, 32 | .col:after, 33 | .clr:after, 34 | .group:after { 35 | content: ""; 36 | display: table; 37 | clear: both; 38 | } 39 | 40 | /* DEFAULT ROW STYLES 41 | Set bottom padding according to preference */ 42 | .row { padding-bottom: 0em; 43 | } 44 | 45 | 46 | /* DEFAULT COLUMN STYLES */ 47 | .col { 48 | display: block; 49 | float: left; 50 | width: 100%; 51 | } 52 | 53 | @media ( min-width : 768px ) { 54 | 55 | .gutters .col { 56 | margin-left: 2%; 57 | } 58 | 59 | .gutters .col:first-child { 60 | margin-left: 0; 61 | } 62 | } 63 | 64 | 65 | 66 | 67 | /* COLUMN WIDTH ON DISPLAYS +768px 68 | You might need to play with media queries here to suite your design. */ 69 | @media ( min-width : 768px ) { 70 | .span_1 { width: 8.33333333333%; } 71 | .span_2 { width: 16.6666666667%; } 72 | .span_3 { width: 25%; } 73 | .span_4 { width: 33.3333333333%; } 74 | .span_5 { width: 41.6666666667%; } 75 | .span_6 { width: 50%; } 76 | .span_7 { width: 58.3333333333%; } 77 | .span_8 { width: 66.6666666667%; } 78 | .span_9 { width: 75%; } 79 | .span_10 { width: 83.3333333333%; } 80 | .span_11 { width: 91.6666666667%; } 81 | .span_12 { width: 100%; } 82 | 83 | .gutters .span_1 { width: 6.5%; } 84 | .gutters .span_2 { width: 15.0%; } 85 | .gutters .span_3 { width: 23.5%; } 86 | .gutters .span_4 { width: 32.0%; } 87 | .gutters .span_5 { width: 40.5%; } 88 | .gutters .span_6 { width: 49.0%; } 89 | .gutters .span_7 { width: 57.5%; } 90 | .gutters .span_8 { width: 66.0%; } 91 | .gutters .span_9 { width: 74.5%; } 92 | .gutters .span_10 { width: 83.0%; } 93 | .gutters .span_11 { width: 91.5%; } 94 | .gutters .span_12 { width: 100%; } 95 | } -------------------------------------------------------------------------------- /_posts/2014-05-07-convnet-convolutional-backward.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "卷积神经网络GPU实现(四):卷积层反馈" 4 | description: "" 5 | category: 6 | tags: ["deep learning"] 7 | --- 8 | 9 | 卷积层反馈主要的任务是根据已经求得的feature map(`z`)的倒数,推导出对filter中各权重值的导数,如下图: 10 | 11 | screenshot 12 | 13 | 对卷积filter权重(w[0][0]和w[7][7]为例)的导数计算为: 14 | 15 | screenshot 16 | 17 | screenshot 18 | 19 | 相应的图示为,**32\*32红色区域对应项相乘再求和**: 20 | 21 | screenshot 22 | 23 | screenshot 24 | 25 | - 每个block是8\*8\*8的结构,负责计算16个filter权重值的导数,按threadIdx.z分为8层,每层是一个8\*8的plate,负责相邻两个filter的计算(**即每个线程负责两个相邻filter的同一位置点的计算**) 26 | - 每个plate是8\*8,刚好与filter的大小对应,因此plate中每一个线程负责filter中一个权重值的计算 27 | 28 | 下面以w[0][0]和w[7][7]的导数计算为例说明: 29 | 30 | - 对一张图片的计算分8次进行,每次隔4行将11行的image数据载入到share memory中去 31 | - 由于share memory的大小为16\*4,因此一次计算又分两次载入feature map的导数到share memory中 32 | 33 | screenshot 34 | 35 | screenshot 36 | 37 | 数据载入完成后,即可针对share memory中的部分进行对应相乘求和的计算 38 | 39 | w[0][0]的导数计算: 40 | screenshot 41 | 42 | w[7][7]的导数计算: 43 | screenshot 44 | -------------------------------------------------------------------------------- /public/js/jquery.fitvids.js: -------------------------------------------------------------------------------- 1 | /*global jQuery */ 2 | /*jshint browser:true */ 3 | /*! 4 | * FitVids 1.1 5 | * 6 | * Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com 7 | * Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ 8 | * Released under the WTFPL license - http://sam.zoy.org/wtfpl/ 9 | * 10 | */ 11 | 12 | (function( $ ){ 13 | 14 | "use strict"; 15 | 16 | $.fn.fitVids = function( options ) { 17 | var settings = { 18 | customSelector: null 19 | }; 20 | 21 | if(!document.getElementById('fit-vids-style')) { 22 | // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js 23 | var head = document.head || document.getElementsByTagName('head')[0]; 24 | var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}'; 25 | var div = document.createElement('div'); 26 | div.innerHTML = '

x

'; 27 | head.appendChild(div.childNodes[1]); 28 | } 29 | 30 | if ( options ) { 31 | $.extend( settings, options ); 32 | } 33 | 34 | return this.each(function(){ 35 | var selectors = [ 36 | "iframe[src*='player.vimeo.com']", 37 | "iframe[src*='youtube.com']", 38 | "iframe[src*='youtube-nocookie.com']", 39 | "iframe[src*='kickstarter.com'][src*='video.html']", 40 | "object", 41 | "embed" 42 | ]; 43 | 44 | if (settings.customSelector) { 45 | selectors.push(settings.customSelector); 46 | } 47 | 48 | var $allVideos = $(this).find(selectors.join(',')); 49 | $allVideos = $allVideos.not("object object"); // SwfObj conflict patch 50 | 51 | $allVideos.each(function(){ 52 | var $this = $(this); 53 | if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } 54 | var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(), 55 | width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(), 56 | aspectRatio = height / width; 57 | if(!$this.attr('id')){ 58 | var videoID = 'fitvid' + Math.floor(Math.random()*999999); 59 | $this.attr('id', videoID); 60 | } 61 | $this.wrap('
').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%"); 62 | $this.removeAttr('height').removeAttr('width'); 63 | }); 64 | }); 65 | }; 66 | // Works with either jQuery or Zepto 67 | })( window.jQuery || window.Zepto ); 68 | -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | .highlight .c{color:#c2b680;background-color:#272822}.highlight .err,.highlight .g{color:#dcdccc;background-color:#272822}.highlight .k{color:#ff6651;font-weight:700}.highlight .l,.highlight .n,.highlight .o,.highlight .p,.highlight .x{color:#dcdccc;background-color:#272822}.highlight .cm{color:#c2b680;background-color:#272822}.highlight .cp{color:#c2aed0;background-color:#272822}.highlight .c1{color:#75715e;background-color:#272822}.highlight .cs{color:#c2b680;background-color:#272822}.highlight .gd{color:#dcdccc;background-color:#8b0000}.highlight .ge{color:#d4b064;text-decoration:underline;background-color:#272822}.highlight .gr{color:#f07070;background-color:#272822}.highlight .gh{color:#f7f7f1;font-weight:700;background-color:#000}.highlight .gi{color:#dcdccc;background-color:#008b00}.highlight .go{color:#9f8f80;font-weight:700;background-color:#272822}.highlight .gp,.highlight .gs{color:#dcdccc;background-color:#272822}.highlight .gu{color:#f7f7f1;font-weight:700;background-color:#000}.highlight .gt{color:#f07070;font-weight:700;background-color:#272822}.highlight .kc{color:#e0af91;font-weight:700;background-color:#272822}.highlight .kd{color:#77d8eb;font-weight:700;background-color:#272822}.highlight .kn,.highlight .kp,.highlight .kr{color:#e0af91;font-weight:700;background-color:#272822}.highlight .kt{color:#dabfa5;font-weight:700;background-color:#272822}.highlight .ld,.highlight .m{color:#dcdccc;background-color:#272822}.highlight .s{color:#e6db6f}.highlight .na{color:#b5df5e}.highlight .nb{color:#dcdccc}.highlight .nc{color:#dcdccc;background-color:#272822}.highlight .no{color:#afe091;background-color:#272822}.highlight .nd{color:#dcdccc;background-color:#272822}.highlight .ni{color:#d4b064;background-color:#272822}.highlight .ne,.highlight .nf,.highlight .nl,.highlight .nn{color:#dcdccc;background-color:#272822}.highlight .nx{color:#ff6651;background-color:#272822}.highlight .py{color:#dcdccc;background-color:#272822}.highlight .nt{color:#ff6651;font-weight:700}.highlight .nv{color:#ff6651;background-color:#272822}.highlight .ow,.highlight .w{color:#dcdccc;background-color:#272822}.highlight .mf{color:#c2a4f8;background-color:#272822}.highlight .mh{color:#dcdccc;background-color:#272822}.highlight .mi{color:#c2a4f8;background-color:#272822}.highlight .mo,.highlight .sb,.highlight .sc,.highlight .sd{color:#dcdccc;background-color:#272822}.highlight .s2{color:#e6db6f;background-color:#272822}.highlight .se,.highlight .sh,.highlight .si,.highlight .sx{color:#dcdccc;background-color:#272822}.highlight .sr{color:#e6db6f;background-color:#272822}.highlight .s1{color:#dcdccc;background-color:#272822}.highlight .ss{color:#e6db6f;background-color:#272822}.highlight .bp{color:#dcdccc;background-color:#272822}.highlight .vc,.highlight .vg,.highlight .vi{color:#dabfa5;background-color:#272822}.highlight .il{color:#dcdccc;background-color:#272822}*{margin:0;padding:0;-moz-box-sizing:border-box;box-sizing:border-box}body{background-color:#f5f5f5;border-top:5px solid #333;font-family:'Source Sans Pro',sans-serif;color:#333;font-weight:400;line-height:1.5;-webkit-font-smoothing:antialiased}.fluid-width-video-wrapper,.highlight,blockquote,dl,h1,h2,h3,h4,h5,h6,hr,img,ol,p,table,ul{margin-bottom:20px}blockquote{padding:0 30px;border-left:2px solid #cfcfcf}ol,ul{margin-left:40px}img{max-width:100%;height:auto;border:0;outline:0}a{text-decoration:none}hr{border:0;height:25px;background:url(/public/images/eagle.png) center center no-repeat}code{font-family:Consolas,"Liberation Mono",Courier,monospace;font-size:.8rem}p code{padding:0 5px;border:1px solid #ddd;background-color:#f8f8f8;border-radius:3px;white-space:nowrap}table{border-collapse:collapse;border:1px solid #333}table td,table th{border:1px solid #333;padding:5px 10px}table thead{background-color:#dcdcdc}dt{float:left;width:30%;font-weight:700}dd{float:right;width:70%}footer{font-size:.8rem;text-align:center}.azul a{color:#0070bb}.azul a:hover{color:#035}.ruby a{color:#e0115f}.ruby a:hover{color:#810a38}.amber a{color:#ff7e00}.amber a:hover{color:#994a00}.avocado a{color:#568203}.avocado a:hover{color:#141e01}.highlight{padding:30px;border-radius:6px;background-color:#272822;color:#f8f8f2;line-height:1}.highlight code{font-size:.7rem}.container{max-width:750px;padding:0 20px}.center{text-align:center}.right{float:right;margin:0 0 20px 20px}.left{float:left;margin:0 20px 20px 0}.top-navbar{margin-bottom:40px;height:110px}.top-navbar a{display:inline-block;color:#333;padding:66px 20px 25px;margin-right:10px;margin-top:-5px;text-transform:uppercase;border-radius:0 0 5px 5px;border-bottom:1px solid #4d4d4d;transition:all ease-in-out .3s}.top-navbar a.current-page,.top-navbar a:hover{color:#f5f5f5;border-bottom:0}.top-navbar a:hover{background-color:#333;-webkit-transform:translateY(5px);transform:translateY(5px)}.top-navbar a.current-page{background-color:#333}.archive,.single{margin-bottom:100px}.single{font-size:1.125rem;line-height:28px}.single time{color:#999;font-size:.9rem}.bundle{border-top:1px solid #b3b3b3;padding-top:10px;margin-bottom:10px}.post-date{text-align:right}.not-found{margin-top:150px;text-align:center;font-size:2rem}.not-found h1{font-size:8rem}.clearfix:after,.clearfix:before,dl{content:" ";display:table}.clearfix:after,dl{clear:both}#logo{display:inline-block;height:110px;width:110px;background-size:90px 90px;background-position:left center;background-repeat:no-repeat}@media screen and (max-width:767px){.top-navbar{height:35px;text-align:center;margin-top:40px}.top-navbar a{padding:5px 10px;margin:5px;border-radius:0;border:1px solid #333;transition:none}.top-navbar a:hover{-webkit-transform:none;transform:none}.bundle,.post-date{text-align:center}.bundle article{margin-bottom:30px}#logo{background-position:center center}} -------------------------------------------------------------------------------- /public/css/_syntax.scss: -------------------------------------------------------------------------------- 1 | .highlight .c { color: #c2b680; background-color: #272822 } /* Comment */ 2 | .highlight .err { color: #dcdccc; background-color: #272822 } /* Error */ 3 | .highlight .g { color: #dcdccc; background-color: #272822 } /* Generic */ 4 | .highlight .k { color: #ff6651; font-weight: bold } /* Keyword */ 5 | .highlight .l { color: #dcdccc; background-color: #272822 } /* Literal */ 6 | .highlight .n { color: #dcdccc; background-color: #272822 } /* Name */ 7 | .highlight .o { color: #dcdccc; background-color: #272822 } /* Operator */ 8 | .highlight .x { color: #dcdccc; background-color: #272822 } /* Other */ 9 | .highlight .p { color: #dcdccc; background-color: #272822 } /* Punctuation */ 10 | .highlight .cm { color: #c2b680; background-color: #272822 } /* Comment.Multiline */ 11 | .highlight .cp { color: #c2aed0; background-color: #272822 } /* Comment.Preproc */ 12 | .highlight .c1 { color: #75715e; background-color: #272822 } /* Comment.Single */ 13 | .highlight .cs { color: #c2b680; background-color: #272822 } /* Comment.Special */ 14 | .highlight .gd { color: #dcdccc; background-color: #8b0000 } /* Generic.Deleted */ 15 | .highlight .ge { color: #d4b064; text-decoration: underline; background-color: #272822 } /* Generic.Emph */ 16 | .highlight .gr { color: #f07070; background-color: #272822 } /* Generic.Error */ 17 | .highlight .gh { color: #f7f7f1; font-weight: bold; background-color: #000000 } /* Generic.Heading */ 18 | .highlight .gi { color: #dcdccc; background-color: #008b00 } /* Generic.Inserted */ 19 | .highlight .go { color: #9f8f80; font-weight: bold; background-color: #272822 } /* Generic.Output */ 20 | .highlight .gp { color: #dcdccc; background-color: #272822 } /* Generic.Prompt */ 21 | .highlight .gs { color: #dcdccc; background-color: #272822 } /* Generic.Strong */ 22 | .highlight .gu { color: #f7f7f1; font-weight: bold; background-color: #000000 } /* Generic.Subheading */ 23 | .highlight .gt { color: #f07070; font-weight: bold; background-color: #272822 } /* Generic.Traceback */ 24 | .highlight .kc { color: #e0af91; font-weight: bold; background-color: #272822 } /* Keyword.Constant */ 25 | .highlight .kd { color: #77d8eb; font-weight: bold; background-color: #272822 } /* Keyword.Declaration */ 26 | .highlight .kn { color: #e0af91; font-weight: bold; background-color: #272822 } /* Keyword.Namespace */ 27 | .highlight .kp { color: #e0af91; font-weight: bold; background-color: #272822 } /* Keyword.Pseudo */ 28 | .highlight .kr { color: #e0af91; font-weight: bold; background-color: #272822 } /* Keyword.Reserved */ 29 | .highlight .kt { color: #dabfa5; font-weight: bold; background-color: #272822 } /* Keyword.Type */ 30 | .highlight .ld { color: #dcdccc; background-color: #272822 } /* Literal.Date */ 31 | .highlight .m { color: #dcdccc; background-color: #272822 } /* Literal.Number */ 32 | .highlight .s { color: #e6db6f } /* Literal.String */ 33 | .highlight .na { color: #b5df5e; } /* Name.Attribute */ 34 | .highlight .nb { color: #dcdccc; } /* Name.Builtin */ 35 | .highlight .nc { color: #dcdccc; background-color: #272822 } /* Name.Class */ 36 | .highlight .no { color: #afe091; background-color: #272822 } /* Name.Constant */ 37 | .highlight .nd { color: #dcdccc; background-color: #272822 } /* Name.Decorator */ 38 | .highlight .ni { color: #d4b064; background-color: #272822 } /* Name.Entity */ 39 | .highlight .ne { color: #dcdccc; background-color: #272822 } /* Name.Exception */ 40 | .highlight .nf { color: #dcdccc; background-color: #272822 } /* Name.Function */ 41 | .highlight .nl { color: #dcdccc; background-color: #272822 } /* Name.Label */ 42 | .highlight .nn { color: #dcdccc; background-color: #272822 } /* Name.Namespace */ 43 | .highlight .nx { color: #ff6651; background-color: #272822 } /* Name.Other */ 44 | .highlight .py { color: #dcdccc; background-color: #272822 } /* Name.Property */ 45 | .highlight .nt { color: #ff6651; font-weight: bold } /* Name.Tag */ 46 | .highlight .nv { color: #ff6651; background-color: #272822 } /* Name.Variable */ 47 | .highlight .ow { color: #dcdccc; background-color: #272822 } /* Operator.Word */ 48 | .highlight .w { color: #dcdccc; background-color: #272822 } /* Text.Whitespace */ 49 | .highlight .mf { color: #c2a4f8; background-color: #272822 } /* Literal.Number.Float */ 50 | .highlight .mh { color: #dcdccc; background-color: #272822 } /* Literal.Number.Hex */ 51 | .highlight .mi { color: #c2a4f8; background-color: #272822 } /* Literal.Number.Integer */ 52 | .highlight .mo { color: #dcdccc; background-color: #272822 } /* Literal.Number.Oct */ 53 | .highlight .sb { color: #dcdccc; background-color: #272822 } /* Literal.String.Backtick */ 54 | .highlight .sc { color: #dcdccc; background-color: #272822 } /* Literal.String.Char */ 55 | .highlight .sd { color: #dcdccc; background-color: #272822 } /* Literal.String.Doc */ 56 | .highlight .s2 { color: #e6db6f; background-color: #272822 } /* Literal.String.Double */ 57 | .highlight .se { color: #dcdccc; background-color: #272822 } /* Literal.String.Escape */ 58 | .highlight .sh { color: #dcdccc; background-color: #272822 } /* Literal.String.Heredoc */ 59 | .highlight .si { color: #dcdccc; background-color: #272822 } /* Literal.String.Interpol */ 60 | .highlight .sx { color: #dcdccc; background-color: #272822 } /* Literal.String.Other */ 61 | .highlight .sr { color: #e6db6f; background-color: #272822 } /* Literal.String.Regex */ 62 | .highlight .s1 { color: #dcdccc; background-color: #272822 } /* Literal.String.Single */ 63 | .highlight .ss { color: #e6db6f; background-color: #272822 } /* Literal.String.Symbol */ 64 | .highlight .bp { color: #dcdccc; background-color: #272822 } /* Name.Builtin.Pseudo */ 65 | .highlight .vc { color: #dabfa5; background-color: #272822 } /* Name.Variable.Class */ 66 | .highlight .vg { color: #dabfa5; background-color: #272822 } /* Name.Variable.Global */ 67 | .highlight .vi { color: #dabfa5; background-color: #272822 } /* Name.Variable.Instance */ 68 | .highlight .il { color: #dcdccc; background-color: #272822 } /* Literal.Number.Integer.Long */ 69 | -------------------------------------------------------------------------------- /public/css/main.scss: -------------------------------------------------------------------------------- 1 | @import 'syntax'; 2 | 3 | $site-background-color: #f5f5f5; 4 | $contrast-color: #333; 5 | 6 | $azul-accent-color: #0070bb; 7 | $ruby-accent-color: #e0115f; 8 | $amber-accent-color: #ff7e00; 9 | $avocado-accent-color: #568203; 10 | 11 | /*============================================================================*/ 12 | * { 13 | margin: 0; 14 | padding: 0; 15 | box-sizing: border-box; 16 | } 17 | 18 | body { 19 | background-color: $site-background-color; 20 | border-top: 5px solid $contrast-color; 21 | font-family: 'Source Sans Pro', sans-serif; 22 | color: $contrast-color; 23 | font-weight: 400; 24 | line-height: 1.5; 25 | 26 | -webkit-font-smoothing: antialiased; 27 | } 28 | 29 | h1, h2, h3, h4, h5, h6, p, ul, ol, dl, 30 | blockquote, 31 | table, 32 | img, 33 | hr, 34 | .fluid-width-video-wrapper, 35 | .highlight { 36 | margin-bottom: 20px; 37 | } 38 | 39 | blockquote { 40 | padding: 0 30px; 41 | border-left: 2px solid darken($site-background-color, 15%); 42 | } 43 | 44 | ul, ol { 45 | margin-left: 40px; 46 | } 47 | 48 | img { 49 | max-width: 100%; 50 | height: auto; 51 | border: none; 52 | outline: none; 53 | } 54 | 55 | a { 56 | text-decoration: none; 57 | } 58 | 59 | hr { 60 | border : 0; 61 | height: 25px; 62 | background : url(/public/images/eagle.png) center center no-repeat; 63 | } 64 | 65 | code { 66 | font-family: Consolas, "Liberation Mono", Courier, monospace; 67 | font-size: .8rem; 68 | } 69 | 70 | p code { 71 | padding: 0px 5px; 72 | border: 1px solid #ddd; 73 | background-color: #f8f8f8; 74 | border-radius: 3px; 75 | white-space: nowrap; 76 | } 77 | 78 | table { 79 | border-collapse: collapse; 80 | border: 1px solid $contrast-color; 81 | 82 | td, th { 83 | border: 1px solid $contrast-color; 84 | padding: 5px 10px; 85 | } 86 | 87 | thead { 88 | background-color: darken($site-background-color, 10%); 89 | } 90 | } 91 | 92 | // TODO: make dt smaller 93 | dt { 94 | float: left; 95 | width: 30%; 96 | font-weight: bold; 97 | } 98 | 99 | dd { 100 | float: right; 101 | width: 70%; 102 | } 103 | 104 | footer { 105 | font-size: .8rem; 106 | text-align: center; 107 | } 108 | 109 | /*============================================================================*/ 110 | .azul { a { color: $azul-accent-color; 111 | &:hover { color: darken($azul-accent-color, 20%); 112 | }}} 113 | 114 | .ruby { a { color: $ruby-accent-color; 115 | &:hover { color: darken($ruby-accent-color, 20%); 116 | }}} 117 | 118 | .amber { a { color: $amber-accent-color; 119 | &:hover { color: darken($amber-accent-color, 20%); 120 | }}} 121 | 122 | .avocado { a { color: $avocado-accent-color; 123 | &:hover { color: darken($avocado-accent-color, 20%); 124 | }}} 125 | 126 | /*----------------------------------------------------------------------------*/ 127 | 128 | .highlight { 129 | padding: 30px; 130 | border-radius: 6px; 131 | background-color: #272822; 132 | color: #f8f8f2; 133 | line-height: 1; 134 | 135 | code { 136 | font-size: .7rem; 137 | } 138 | } 139 | 140 | .container { 141 | max-width: 750px; 142 | padding: 0 20px; 143 | } 144 | 145 | .center { 146 | text-align: center; 147 | } 148 | 149 | .right { 150 | float: right; 151 | margin: 0 0 20px 20px; 152 | } 153 | 154 | .left { 155 | float: left; 156 | margin: 0 20px 20px 0; 157 | } 158 | 159 | .top-navbar { 160 | margin-bottom: 40px; 161 | height: 110px; 162 | 163 | a { 164 | display: inline-block; 165 | color: $contrast-color; 166 | padding: 66px 20px 25px; 167 | margin-right: 10px; 168 | margin-top: -5px; 169 | text-transform: uppercase; 170 | border-radius: 0 0 5px 5px; 171 | border-bottom: 1px solid lighten($contrast-color, 10%); 172 | transition: all ease-in-out .3s; 173 | 174 | &:hover, 175 | &.current-page { 176 | color: $site-background-color; 177 | border-bottom: none; 178 | } 179 | 180 | &:hover { 181 | background-color: $contrast-color; 182 | transform: translateY(5px); 183 | } 184 | 185 | &.current-page { 186 | background-color: $contrast-color; 187 | } 188 | } 189 | } 190 | 191 | .archive, 192 | .single { 193 | margin-bottom: 100px; 194 | } 195 | 196 | .single { 197 | font-size: 1.125rem; 198 | line-height: 28px; 199 | } 200 | 201 | .single time { 202 | color: #999; 203 | font-size: .9rem; 204 | } 205 | 206 | .bundle { 207 | border-top: 1px solid lighten($contrast-color, 50%); 208 | padding-top: 10px; 209 | margin-bottom: 10px; 210 | } 211 | 212 | .post-date { 213 | text-align: right; 214 | } 215 | 216 | .not-found { 217 | margin-top: 150px; 218 | text-align: center; 219 | font-size: 2rem; 220 | } 221 | 222 | .not-found h1 { 223 | font-size: 8rem; 224 | } 225 | 226 | dl, 227 | .clearfix:before, 228 | .clearfix:after { 229 | content: " "; 230 | display: table; 231 | } 232 | 233 | dl, 234 | .clearfix:after { 235 | clear: both; 236 | } 237 | 238 | /*============================================================================*/ 239 | #logo { 240 | display: inline-block; 241 | height: 110px; 242 | width: 110px; 243 | background-size: 90px 90px; 244 | background-position: left center; 245 | background-repeat: no-repeat; 246 | } 247 | 248 | /*============================================================================*/ 249 | @media screen and (max-width: 767px) { 250 | .top-navbar { 251 | height: 35px; 252 | text-align: center; 253 | margin-top: 40px; 254 | 255 | a { 256 | padding: 5px 10px; 257 | margin: 5px; 258 | border-radius: 0; 259 | border: 1px solid $contrast-color; 260 | transition: none; 261 | 262 | &:hover { 263 | transform: none; 264 | } 265 | } 266 | } 267 | 268 | .bundle, 269 | .post-date { 270 | text-align: center; 271 | } 272 | 273 | .bundle article { 274 | margin-bottom: 30px; 275 | } 276 | 277 | #logo { 278 | background-position: center center; 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /_posts/2014-05-11-linker.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "深入理解计算机系统:链接" 4 | description: "" 5 | category: 6 | tags: ["c/c++"] 7 | --- 8 | 9 | ###链接 10 | 11 | 链接是一个将不同的代码和数据收集并组合乘一个文件,能够加载到内存中并且能够被执行 12 | 13 | 链接在软件工程中非常重要,因为它使得各个模块可以独立编译 14 | 15 | ###编译驱动器 16 | 17 | 很多编译系统都提供一个编译驱动器,能够调用__语言预处理器__,__编译器__,__汇编器__,__链接器__(如GNU gcc和g++) 18 | 19 | 以下面的main.c和swap.c为例: 20 | 21 | {% highlight c++ %} 22 | /* main.c */ 23 | void swap(); 24 | 25 | int buf[2] = {1, 2}; 26 | 27 | int main(){ 28 | swap(); 29 | return 0; 30 | } 31 | {% endhighlight %} 32 | 33 | {% highlight c++ %} 34 | /* swap.c */ 35 | extern int buf[]; 36 | 37 | int *bufp0 = &buf[0]; 38 | int *bufp1; 39 | 40 | void swap(){ 41 | int temp; 42 | bufp1 = &buf[1]; 43 | temp = *bufp0; 44 | *bufp0 = *bufp1; 45 | *bufp1 = temp; 46 | } 47 | {% endhighlight %} 48 | 49 | 执行一下的命令进行编译: 50 | 51 | {% highlight bash %} 52 | 53 | unix> gcc -O2 -g -o p main.c swap.c 54 | 55 | {% endhighlight %} 56 | 57 | 其实整个过程可以分为如下的部分: 58 | 59 | ![编译过程](/assets/linker_1.png) 60 | 61 | {% highlight bash %} 62 | 63 | #用c预处理器cpp将源文件main.c翻译为ASCII中间文件main.i 64 | unix> cpp [other arguments] main.c /tmp/main.i 65 | 66 | #用c编译器cc1将main.i翻译成汇编文件main.s 67 | unix> cc1 /tmp/main.i main.c -O2 -o /tmp/main.s 68 | 69 | #用汇编器as将main.s编译成可重定向目标文件(relocatable object file) main.o 70 | unix> as -o /tmp/main.o /tmp/main.s 71 | 72 | #对swap.c相应地重复上面的操作 73 | #最后用链接器ld将两个可重定向目标文件main.o和swap.o组合成可执行文件p 74 | unix> ld -o p [system obejct files and args] /tmp/main.o /tmp/swap.o 75 | 76 | {% endhighlight %} 77 | 78 | ###静态链接 79 | 80 | 静态链接器主要执行两个主要任务: 81 | 82 | - __符号解析__:目标文件会定义和引用符号(函数,变量等),符号解析是为了将 83 | 每一个__符号引用__关联到其唯一对应的__符号定义__ 84 | 85 | - __重定向__:编译器和汇编器产生的代码块和数据块(code section, data section) 86 | 都是以0为起始地址的。链接器重定向这些块,通过给每一个__符号定义__关联一个 87 | 内存位置,然后修改所有的__符号引用__使其指向这个内存位置 88 | 89 | ###可重定向目标文件 90 | 91 | 可重定向目标文件的结构如下图: 92 | 93 | ![可重定向目标文件的结构](/assets/linker_2.png) 94 | 95 | 一些块的作用: 96 | 97 | - __.text__:编译程序的机器代码 98 | - __.data__:初始化的c全局变量 99 | - __.bss__:未初始化的c全局变量,实际上不会占用任何磁盘空间 100 | - __.symtab__:符号表,包含了程序中的函数和全局变量定义和引用的信息, 101 | 但并不包含局部变量项 102 | - __.rel.text__:.text块中的一些位置,需要在与其他目标文件共同编译时修改。 103 | 具体而言,调用外部函数或者引用全局变量的指令需要修改, 104 | 只调用本地函数的指令则不需要修改 105 | - __.rel.data__:全局变量的重定向信息 106 | - __.strtab__:字符串表,用于记录.symtab和.debug中定义的项的名字, 107 | 是一个null-terminated字符串数组 108 | 109 | ###符号和符号表.symtab 110 | 111 | 模块m符号表中主要有三种不同类型的符号: 112 | 113 | - 由模块m定义的全局符号,可以被其他模块引用,一般是非静态c函数和非静态c全局变量 114 | - 在模块m中引用到的全局符号,而在其他模块中定义,如有extern的c全局变量 115 | - 只在模块m中定义和引用的局部符号,如static的函数和全局变量以及函数中定义的static变量 116 | 117 | 符号表是__汇编器as__构建的,每个符号表项的格式如下定义: 118 | 119 | ![符号表项的定义](/assets/linker_3.png) 120 | 121 | - __name__是字符串表.strtab的字节偏置,记录符号的名字 122 | - __value__对于重定向模块是从其定义的块开始的偏置,对于可执行文件则为运行时的绝对地址 123 | - __size__是该对象的字节数 124 | - __type__一般有Object和Func两种 125 | - __binding__表示该符号是local还是global的 126 | - __section__表示该符号属于哪一个块,如果存在,则记录该section的index, 127 | UNDEF表示引用的在其他模块定义的符号,COMMON表示未初始化的数据对象 128 | 129 | 下面是用readelf工具查看main.o和swap.o的结果: 130 | 131 | ![main.o的符号表](/assets/linker_4.png) 132 | 133 | ![swap.o的符号表](/assets/linker_5.png) 134 | 135 | ###符号解析 136 | 137 | 当编译器遇到一个没有在本模块定义的符号时,会假定在其他模块中定义,并产生一个链接符号表项交给链接器处理 138 | 139 | 链接器如果在其他模块中找不到引用的符号定义,则会报"undefined reference"错误 140 | 141 | ####解决多重定义的全局变量 142 | 143 | 编译器会告诉汇编器每一个全局变量是强或弱 144 | 145 | 函数和初始化的全局变量是强符号,没有初始化的全局变量是弱符号 146 | 147 | 解决重复定义的符号依据以下规则: 148 | 149 | - 规则1:多重强符号是不允许的 150 | - 规则2:给定一个强符号和若干弱符号,选择强符号 151 | - 规则3:给定多个弱符号,选择其中的任意一个 152 | 153 | 由于规则3的定义,当不同模块的同一弱符号有不同类型时,很容易产生错误 154 | 155 | 可以通过声明-fno-common以便编译器发现多重定义全局符号时报错 156 | 157 | ####链接静态库 158 | 159 | 将相关的目标模块打包成一个静态库,可以作为链接器的输入 160 | 161 | 当用其构建一个可执行文件时,链接器只会拷贝应用程序中引用到的目标模块 162 | 163 | 考虑将addvec.c和multvec.c打包成一个归档文件 164 | 165 | {% highlight c++ %} 166 | /* addvec.c */ 167 | void addvec(int *x, int *y, int *z, int n){ 168 | int i; 169 | for(i = 0; i < n; i++) 170 | z[i] = x[i] + y[i]; 171 | } 172 | {% endhighlight %} 173 | 174 | {% highlight c++ %} 175 | /* multvec.c */ 176 | void multvec(int *x, int *y, int *z, int n){ 177 | int i; 178 | for(i = 0; i < n; i++) 179 | z[i] = x[i] * y[i]; 180 | } 181 | {% endhighlight %} 182 | 183 | {% highlight bash %} 184 | unix> ar rcs libvector.a addvec.o multvec.o 185 | {% endhighlight %} 186 | 187 | 使用归档文件的编译过程如下图: 188 | 189 | ![使用归档文件编译](/assets/linker_6.png) 190 | 191 | ####使用静态链接库解决符号引用的过程 192 | 193 | 符号解析的过程中,链接器会从左到右扫描命令的输入模块 194 | 195 | 用E表示最终用到的可重定向目标文件,U表示未解决的符号,D表示已经定义的符号 196 | 197 | - 对于每一个输入文件f,链接器会先判断是目标文件还是归档文件。 198 | 如果是目标文件,则添加f到E,更新U和D来反映f中的符号定义和符号引用 199 | - 如果f是归档文件,则链接器会尝试将U中未解决的符号匹配归档成员的符号定义, 200 | 如果找到模块m解决了一个U中的引用,则将m添加到E,更新U和D 201 | - 上述两步一直进行,直到遍历了命令行中的所有文件, 202 | 如果结束是U依然非空,则打印错误信息,链接停止 203 | 204 | ###重定向 205 | 206 | 当完成符号解析,每个符号都有其唯一的定义,这时需要进行重定向, 207 | 给每一个符号指定一个运行时地址 208 | 209 | 在符号解析之后,链接器知道输入目标模块中的code和data块的大小,便可执行如下重定向过程: 210 | 211 | - __重定向section和符号定义__:将多个输入模块的同一类型section合并起来,给新的section分配运行时地址, 212 | 再给每一个__定义的符号__分配运行时地址 213 | - __重定向section内的符号引用__:链接器修改code和data section中的每一个符号引用, 214 | 使之指向正确的运行时地址 215 | 216 | ###可执行目标文件 217 | 218 | 完成重定向之后,链接器便生成了最终的可执行文件,文件结构如下: 219 | 220 | ![可执行文件结构](/assets/linker_7.png) 221 | 222 | .text,.data,.bss块跟可重定向目标文件是类似的,而由于可执行文件是全链接的,.rel不需要了 223 | 224 | 文件中主要是code segment和data segment,这两部分在程序运行时会加载到内存中,可以用objdump查看segment信息 225 | 226 | ![segment信息](/assets/linker_8.png) 227 | 228 | 在程序运行时,loader会将可执行文件的code和data会拷贝到内存中,并跳到程序的第一条指令 229 | 230 | 运行时程序的内存镜像如下: 231 | 232 | ![内存镜像](/assets/linker_9.png) 233 | 234 | 一般的32位linux系统的code段从0x08048000开始,然后是data段,然后是运行时堆, 235 | 栈一般从最大的用户地址grow down 236 | 237 | ###动态链接和动态库 238 | 239 | 由于一些常用的模块如printf.o会被很多程序使用,如果每个程序都有一份拷贝, 240 | 则会造成很大的冗余 241 | 242 | 动态库是一个可以在运行时,以任意内存地址加载,并且在内存中链接的目标模块 243 | 244 | shared有两重意义: 245 | 246 | - 只存在一个.so文件,所有引用它的可执行文件都共用其code和data,而无需拷贝再嵌入到可执行文件中 247 | - 只有一份.text存在内存中 248 | 249 | {% highlight bash %} 250 | unix> gcc -shared -fPIC -o libvector.so addvec.o multvec.o 251 | {% endhighlight %} 252 | 253 | 动态库程序的编译和加载: 254 | 255 | ![动态链接](/assets/linker_10.png) 256 | 257 | - 部分链接(partially linked)不会拷贝libc.so和libvector.so的data和code, 258 | 而是拷贝其符号表和重定向信息,写入到p2的.interp块中 259 | - loader加载程序时发现其.interp块,在运行时根据其重定向信息对libc.so和libvector.so 260 | 和p2的text和data进行重定向 261 | 262 | ####Linux系统定义的动态加载接口(钩子) 263 | 264 | {% highlight c++ %} 265 | #include 266 | 267 | void *dlopen(const char *filename, int flag); 268 | #Return ptr to handle if OK, NULL on error 269 | 270 | void *dlsym(void *handle, char *symbol); 271 | #Return ptr to symbol if OK, NULL on error 272 | 273 | int dlclose(void *handle); 274 | #Return 1 if OK, -1 on error 275 | {% endhighlight %} 276 | -------------------------------------------------------------------------------- /public/css/animate.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}@-webkit-keyframes bounce{0%,20%,50%,80%,100%{-webkit-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);transform:translateY(-15px)}}@keyframes bounce{0%,20%,50%,80%,100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}40%{-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);transform:translateY(-30px)}60%{-webkit-transform:translateY(-15px);-ms-transform:translateY(-15px);transform:translateY(-15px)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce}@-webkit-keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,100%{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.1);transform:scale(1.1)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes pulse{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}50%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}100%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);-ms-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);-ms-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);-ms-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);-ms-transform:rotate(-5deg);transform:rotate(-5deg)}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}}.swing{-webkit-transform-origin:top center;-ms-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9)rotate(-3deg);transform:scale(.9)rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1)rotate(3deg);transform:scale(1.1)rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1)rotate(-3deg);transform:scale(1.1)rotate(-3deg)}100%{-webkit-transform:scale(1)rotate(0);transform:scale(1)rotate(0)}}@keyframes tada{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}10%,20%{-webkit-transform:scale(.9)rotate(-3deg);-ms-transform:scale(.9)rotate(-3deg);transform:scale(.9)rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale(1.1)rotate(3deg);-ms-transform:scale(1.1)rotate(3deg);transform:scale(1.1)rotate(3deg)}40%,60%,80%{-webkit-transform:scale(1.1)rotate(-3deg);-ms-transform:scale(1.1)rotate(-3deg);transform:scale(1.1)rotate(-3deg)}100%{-webkit-transform:scale(1)rotate(0);-ms-transform:scale(1)rotate(0);transform:scale(1)rotate(0)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateX(0%);transform:translateX(0%)}15%{-webkit-transform:translateX(-25%)rotate(-5deg);transform:translateX(-25%)rotate(-5deg)}30%{-webkit-transform:translateX(20%)rotate(3deg);transform:translateX(20%)rotate(3deg)}45%{-webkit-transform:translateX(-15%)rotate(-3deg);transform:translateX(-15%)rotate(-3deg)}60%{-webkit-transform:translateX(10%)rotate(2deg);transform:translateX(10%)rotate(2deg)}75%{-webkit-transform:translateX(-5%)rotate(-1deg);transform:translateX(-5%)rotate(-1deg)}100%{-webkit-transform:translateX(0%);transform:translateX(0%)}}@keyframes wobble{0%{-webkit-transform:translateX(0%);-ms-transform:translateX(0%);transform:translateX(0%)}15%{-webkit-transform:translateX(-25%)rotate(-5deg);-ms-transform:translateX(-25%)rotate(-5deg);transform:translateX(-25%)rotate(-5deg)}30%{-webkit-transform:translateX(20%)rotate(3deg);-ms-transform:translateX(20%)rotate(3deg);transform:translateX(20%)rotate(3deg)}45%{-webkit-transform:translateX(-15%)rotate(-3deg);-ms-transform:translateX(-15%)rotate(-3deg);transform:translateX(-15%)rotate(-3deg)}60%{-webkit-transform:translateX(10%)rotate(2deg);-ms-transform:translateX(10%)rotate(2deg);transform:translateX(10%)rotate(2deg)}75%{-webkit-transform:translateX(-5%)rotate(-1deg);-ms-transform:translateX(-5%)rotate(-1deg);transform:translateX(-5%)rotate(-1deg)}100%{-webkit-transform:translateX(0%);-ms-transform:translateX(0%);transform:translateX(0%)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05);transform:scale(1.05)}70%{-webkit-transform:scale(.9);transform:scale(.9)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);-ms-transform:scale(.3);transform:scale(.3)}50%{opacity:1;-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}70%{-webkit-transform:scale(.9);-ms-transform:scale(.9);transform:scale(.9)}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}60%{opacity:1;-webkit-transform:translateY(30px);transform:translateY(30px)}80%{-webkit-transform:translateY(-10px);transform:translateY(-10px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes bounceInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}60%{opacity:1;-webkit-transform:translateY(30px);-ms-transform:translateY(30px);transform:translateY(30px)}80%{-webkit-transform:translateY(-10px);-ms-transform:translateY(-10px);transform:translateY(-10px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}60%{opacity:1;-webkit-transform:translateX(30px);transform:translateX(30px)}80%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes bounceInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}60%{opacity:1;-webkit-transform:translateX(30px);-ms-transform:translateX(30px);transform:translateX(30px)}80%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}60%{opacity:1;-webkit-transform:translateX(-30px);transform:translateX(-30px)}80%{-webkit-transform:translateX(10px);transform:translateX(10px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes bounceInRight{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}60%{opacity:1;-webkit-transform:translateX(-30px);-ms-transform:translateX(-30px);transform:translateX(-30px)}80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}60%{opacity:1;-webkit-transform:translateY(-30px);transform:translateY(-30px)}80%{-webkit-transform:translateY(10px);transform:translateY(10px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes bounceInUp{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}60%{opacity:1;-webkit-transform:translateY(-30px);-ms-transform:translateY(-30px);transform:translateY(-30px)}80%{-webkit-transform:translateY(10px);-ms-transform:translateY(10px);transform:translateY(10px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(.95);transform:scale(.95)}50%{opacity:1;-webkit-transform:scale(1.1);transform:scale(1.1)}100%{opacity:0;-webkit-transform:scale(.3);transform:scale(.3)}}@keyframes bounceOut{0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(.95);-ms-transform:scale(.95);transform:scale(.95)}50%{opacity:1;-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}100%{opacity:0;-webkit-transform:scale(.3);-ms-transform:scale(.3);transform:scale(.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes bounceOutDown{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(20px);transform:translateX(20px)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes bounceOutLeft{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes bounceOutRight{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}20%{opacity:1;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(20px);transform:translateY(20px)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes bounceOutUp{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}100%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}100%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(20px);-ms-transform:translateY(20px);transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes fadeOutDownBig{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}}@keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-20px);-ms-transform:translateX(-20px);transform:translateX(-20px)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes fadeOutLeftBig{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}}@keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(20px);-ms-transform:translateX(20px);transform:translateX(20px)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes fadeOutRightBig{0%{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes fadeOutUpBig{0%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px)translateZ(0)rotateY(0)scale(1);transform:perspective(400px)translateZ(0)rotateY(0)scale(1)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1)}50%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95)}80%,100%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1)}}@keyframes flip{0%{-webkit-transform:perspective(400px)translateZ(0)rotateY(0)scale(1);-ms-transform:perspective(400px)translateZ(0)rotateY(0)scale(1);transform:perspective(400px)translateZ(0)rotateY(0)scale(1)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1);-ms-transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(170deg)scale(1)}50%{-webkit-transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);-ms-transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);transform:perspective(400px)translateZ(150px)rotateY(190deg)scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95);-ms-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(.95)}80%,100%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1);-ms-transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1);transform:perspective(400px)translateZ(0)rotateY(360deg)scale(1)}}.animated.flip{-webkit-backface-visibility:visible;-ms-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateX(-10deg);transform:perspective(400px)rotateX(-10deg)}70%{-webkit-transform:perspective(400px)rotateX(10deg);transform:perspective(400px)rotateX(10deg)}100%{-webkit-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}}@keyframes flipInX{0%{-webkit-transform:perspective(400px)rotateX(90deg);-ms-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateX(-10deg);-ms-transform:perspective(400px)rotateX(-10deg);transform:perspective(400px)rotateX(-10deg)}70%{-webkit-transform:perspective(400px)rotateX(10deg);-ms-transform:perspective(400px)rotateX(10deg);transform:perspective(400px)rotateX(10deg)}100%{-webkit-transform:perspective(400px)rotateX(0);-ms-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}}.flipInX{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateY(-10deg);transform:perspective(400px)rotateY(-10deg)}70%{-webkit-transform:perspective(400px)rotateY(10deg);transform:perspective(400px)rotateY(10deg)}100%{-webkit-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}}@keyframes flipInY{0%{-webkit-transform:perspective(400px)rotateY(90deg);-ms-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}40%{-webkit-transform:perspective(400px)rotateY(-10deg);-ms-transform:perspective(400px)rotateY(-10deg);transform:perspective(400px)rotateY(-10deg)}70%{-webkit-transform:perspective(400px)rotateY(10deg);-ms-transform:perspective(400px)rotateY(10deg);transform:perspective(400px)rotateY(10deg)}100%{-webkit-transform:perspective(400px)rotateY(0);-ms-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}}.flipInY{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px)rotateX(0);-ms-transform:perspective(400px)rotateX(0);transform:perspective(400px)rotateX(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateX(90deg);-ms-transform:perspective(400px)rotateX(90deg);transform:perspective(400px)rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px)rotateY(0);-ms-transform:perspective(400px)rotateY(0);transform:perspective(400px)rotateY(0);opacity:1}100%{-webkit-transform:perspective(400px)rotateY(90deg);-ms-transform:perspective(400px)rotateY(90deg);transform:perspective(400px)rotateY(90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;-ms-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}60%{-webkit-transform:translateX(-20%)skewX(30deg);transform:translateX(-20%)skewX(30deg);opacity:1}80%{-webkit-transform:translateX(0%)skewX(-15deg);transform:translateX(0%)skewX(-15deg);opacity:1}100%{-webkit-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translateX(100%)skewX(-30deg);-ms-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}60%{-webkit-transform:translateX(-20%)skewX(30deg);-ms-transform:translateX(-20%)skewX(30deg);transform:translateX(-20%)skewX(30deg);opacity:1}80%{-webkit-transform:translateX(0%)skewX(-15deg);-ms-transform:translateX(0%)skewX(-15deg);transform:translateX(0%)skewX(-15deg);opacity:1}100%{-webkit-transform:translateX(0%)skewX(0);-ms-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{-webkit-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}100%{-webkit-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}}@keyframes lightSpeedOut{0%{-webkit-transform:translateX(0%)skewX(0);-ms-transform:translateX(0%)skewX(0);transform:translateX(0%)skewX(0);opacity:1}100%{-webkit-transform:translateX(100%)skewX(-30deg);-ms-transform:translateX(100%)skewX(-30deg);transform:translateX(100%)skewX(-30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,100%{-webkit-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);-ms-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,100%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:center center;-ms-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(200deg);-ms-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:left bottom;-ms-transform-origin:left bottom;transform-origin:left bottom}100%{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);opacity:1}0%,100%{-webkit-transform-origin:right bottom;-ms-transform-origin:right bottom;transform-origin:right bottom}100%{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}100%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(-2000px);-ms-transform:translateX(-2000px);transform:translateX(-2000px)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes slideOutRight{0%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}100%{opacity:0;-webkit-transform:translateX(2000px);-ms-transform:translateX(2000px);transform:translateX(2000px)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes slideOutUp{0%{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-2000px);-ms-transform:translateY(-2000px);transform:translateY(-2000px)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}@-webkit-keyframes hinge{0%{-webkit-transform:rotate(0);transform:rotate(0)}0%,20%,60%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg)}40%{-webkit-transform:rotate(60deg);transform:rotate(60deg)}40%,80%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}80%{-webkit-transform:rotate(60deg)translateY(0);transform:rotate(60deg)translateY(0);opacity:1}100%{-webkit-transform:translateY(700px);transform:translateY(700px);opacity:0}}@keyframes hinge{0%{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}0%,20%,60%{-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);-ms-transform:rotate(80deg);transform:rotate(80deg)}40%{-webkit-transform:rotate(60deg);-ms-transform:rotate(60deg);transform:rotate(60deg)}40%,80%{-webkit-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}80%{-webkit-transform:rotate(60deg)translateY(0);-ms-transform:rotate(60deg)translateY(0);transform:rotate(60deg)translateY(0);opacity:1}100%{-webkit-transform:translateY(700px);-ms-transform:translateY(700px);transform:translateY(700px);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%)rotate(-120deg);transform:translateX(-100%)rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%)rotate(-120deg);-ms-transform:translateX(-100%)rotate(-120deg);transform:translateX(-100%)rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0)rotate(0);-ms-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1;-webkit-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}100%{opacity:0;-webkit-transform:translateX(100%)rotate(120deg);transform:translateX(100%)rotate(120deg)}}@keyframes rollOut{0%{opacity:1;-webkit-transform:translateX(0)rotate(0);-ms-transform:translateX(0)rotate(0);transform:translateX(0)rotate(0)}100%{opacity:0;-webkit-transform:translateX(100%)rotate(120deg);-ms-transform:translateX(100%)rotate(120deg);transform:translateX(100%)rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut} --------------------------------------------------------------------------------