-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
229 lines (193 loc) · 7.68 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Pack C/C++ Struct</title>
<meta name="description" content="How to pack C/C++ struct to reduce memory footprint and gain performance">
<meta name="author" content="Clark">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/reveal.min.css">
<link rel="stylesheet" href="css/theme/night.css" id="theme">
<!-- For syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- If the query includes 'print-pdf', include the PDF print sheet -->
<script>
if( window.location.search.match( /print-pdf/gi ) ) {
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'css/print/pdf.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
}
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Pack C/C++ Struct</h1>
</section>
<section>
<h2>Why Struct Packing?</h2>
<ol>
<li>減少記憶體用量 (Esp. 開發嵌入式系統或大型程式)</li>
<li>提高程式運行效率
<ul>
<li>cache line</li>
</li>
</li>
</ol>
</section>
<section>
<h2>Careless Struct Packing</h2>
<pre><code data-trim contenteditable>
int main(int argc, char *argv[]){
struct {
char c; // 1 byte, followed by 7-byte padding
long long ell; // 8 bytes
short s; // 2 bytes, followed by 6-byte padding
} s;
printf("sizeof(s) is %lu\n", sizeof(s)); // sizeof(s) is 24
return 0;
}
</code></pre>
</section>
<section>
<h2>Alignment</h2>
<ul>
<li>1 byte data (char) 可以在任何address</li>
<li>2 byte data (short) 的address是2的倍數</li>
<li>4 byte data (int) 的address是4的倍數</li>
<li>pointer 的 address 是4的倍數(32-bit addressing)或8的倍數(64-bit addressing)</li>
</ul>
</section>
<section>
<h2>Compiler 會在struct中間塞進padding, 以符合alignment</h2>
</section>
<section>
<h2> 依據使用的記憶體大小, 把data member從大排到小 </h2>
</section>
<section>
<h2>rearrange</h2>
<pre><code data-trim contenteditable>
int main(int argc, char *argv[]){
struct {
long long ell; // 8 bytes
short s; // 2 bytes
char c; // 1 byte, followed by 5-byte padding
} s;
printf("sizeof(s) is %lu\n", sizeof(s)); // sizeof(s) is 16
return 0;
}
</code></pre>
<p>24 bytes 變成 16 bytes, 33% improvement!</p>
</section>
<section>
<h2> 檢查工具 </h2>
<ol>
<li>gcc -Wpadded</li>
<li>clang -Wpadded</li>
<li>pahole</li>
</ol>
</section>
<section>
<h2>gcc</h2>
<pre><code data-trim contenteditable>
int main(int argc, char *argv[]){
struct {
char c; // 1 byte, followed by 7-byte padding
long long ell; // 8 bytes
short s; // 2 bytes, followed by 6-byte padding
} s;
printf("sizeof(s) is %lu\n", sizeof(s)); // sizeof(s) is 24
return 0;
}
</code></pre>
<p align="left"> $ gcc -Wpadded bad_struct.c</p>
<p data-markdown>
<script type="text/template">
```
ad_struct.c: In function ‘main’:
bad_struct.c:6:19: warning: padding struct to align ‘ell’ [-Wpadded]
bad_struct.c:8:5: warning: padding struct size to alignment boundary [-Wpadded]
```
</script>
</p>
</section>
<section>
<h2>Clang</h2>
<p align="left"> $ clang -Wpadded bad_struct.c</p>
<p data-markdown>
<script type="text/template">
```
bad_struct.c:6:19: warning: padding struct 'struct <anonymous at
bad_struct.c:4:5>' with 7 bytes to align 'ell' [-Wpadded]
long long ell;
^
bad_struct.c:4:5: warning: padding size of 'struct <anonymous at
bad_struct.c:4:5>' with 6 bytes to alignment boundary [-Wpadded]
struct {
^
2 warnings generated.
```
</script>
</p>
<p align="left">clang has more detailed output than gcc</p>
</section>
<section>
<h2>pahole (poke-a-hole)</h2>
<ul>
<li>在 dwarves 套件中</li>
<li>pahole 在我的小範例裡沒有任何輸出 :)</li>
<li>請移駕至 <a href="http://ivoire.dinauz.org/blog/post/2010/07/14/Saving-memory-for-free" target="_blank">Saving memory for free</a></li>
</ul>
<p></p>
</section>
<section>
<h2>External Links</h2>
<ul>
<li><a href="http://www.catb.org/esr/structure-packing/#_structure_alignment_and_padding" target="_blank">The Lost Art of C Structure Packing (推薦)</a></li>
<li><a href="http://lwn.net/Articles/335942/" target="_blank">Poke-a-hole and friends</a></li>
<li><a href="http://ivoire.dinauz.org/blog/post/2010/07/14/Saving-memory-for-free" target="_blank">Saving memory for free</a></li>
</ul>
</section>
<section>
<h2>https://github.com/chihungtzeng/struct_pack.git</h2>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.min.js"></script>
<script>
// Full list of configuration options available here:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
slideNumber: true,
theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
// Parallax scrolling
// parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
// parallaxBackgroundSize: '2100px 900px',
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
]
});
</script>
</body>
</html>