optimization.txt 10.8 KB
Newer Older
Michael Niedermayer's avatar
Michael Niedermayer committed
1
optimization Tips (for libavcodec):
2
===================================
Michael Niedermayer's avatar
Michael Niedermayer committed
3 4

What to optimize:
5
-----------------
6
If you plan to do non-x86 architecture specific optimizations (SIMD normally),
7
then take a look in the x86/ directory, as most important functions are
8
already optimized for MMX.
Michael Niedermayer's avatar
Michael Niedermayer committed
9

10
If you want to do x86 optimizations then you can either try to finetune the
11
stuff in the x86 directory or find some other functions in the C source to
12
optimize, but there aren't many left.
Michael Niedermayer's avatar
Michael Niedermayer committed
13

14

Michael Niedermayer's avatar
Michael Niedermayer committed
15
Understanding these overoptimized functions:
16
--------------------------------------------
17 18
As many functions tend to be a bit difficult to understand because
of optimizations, it can be hard to optimize them further, or write
19
architecture-specific versions. It is recommended to look at older
20 21
revisions of the interesting files (web frontends for the various FFmpeg
branches are listed at http://ffmpeg.org/download.html).
22
Alternatively, look into the other architecture-specific versions in
23
the x86/, ppc/, alpha/ subdirectories. Even if you don't exactly
24 25
comprehend the instructions, it could help understanding the functions
and how they can be optimized.
26 27

NOTE: If you still don't understand some function, ask at our mailing list!!!
28
(http://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel)
Michael Niedermayer's avatar
Michael Niedermayer committed
29

30

31 32
When is an optimization justified?
----------------------------------
33 34 35 36 37 38 39 40 41
Normally, clean and simple optimizations for widely used codecs are
justified even if they only achieve an overall speedup of 0.1%. These
speedups accumulate and can make a big difference after awhile. Also, if
none of the following factors get worse due to an optimization -- speed,
binary code size, source size, source readability -- and at least one
factor improves, then an optimization is always a good idea even if the
overall gain is less than 0.1%. For obscure codecs that are not often
used, the goal is more toward keeping the code clean, small, and
readable instead of making it 1% faster.
Michael Niedermayer's avatar
Michael Niedermayer committed
42 43


44
WTF is that function good for ....:
45
-----------------------------------
46 47
The primary purpose of this list is to avoid wasting time optimizing functions
which are rarely used.
Michael Niedermayer's avatar
Michael Niedermayer committed
48 49

put(_no_rnd)_pixels{,_x2,_y2,_xy2}
50
    Used in motion compensation (en/decoding).
Michael Niedermayer's avatar
Michael Niedermayer committed
51 52

avg_pixels{,_x2,_y2,_xy2}
53
    Used in motion compensation of B-frames.
54
    These are less important than the put*pixels functions.
Michael Niedermayer's avatar
Michael Niedermayer committed
55 56

avg_no_rnd_pixels*
57
    unused
Michael Niedermayer's avatar
Michael Niedermayer committed
58 59

pix_abs16x16{,_x2,_y2,_xy2}
60
    Used in motion estimation (encoding) with SAD.
Michael Niedermayer's avatar
Michael Niedermayer committed
61 62

pix_abs8x8{,_x2,_y2,_xy2}
63
    Used in motion estimation (encoding) with SAD of MPEG-4 4MV only.
64
    These are less important than the pix_abs16x16* functions.
Michael Niedermayer's avatar
Michael Niedermayer committed
65 66

put_mspel8_mc* / wmv2_mspel8*
67 68 69
    Used only in WMV2.
    it is not recommended that you waste your time with these, as WMV2
    is an ugly and relatively useless codec.
Michael Niedermayer's avatar
Michael Niedermayer committed
70 71

mpeg4_qpel* / *qpel_mc*
72 73 74 75 76
    Used in MPEG-4 qpel motion compensation (encoding & decoding).
    The qpel8 functions are used only for 4mv,
    the avg_* functions are used only for B-frames.
    Optimizing them should have a significant impact on qpel
    encoding & decoding.
77

Michael Niedermayer's avatar
Michael Niedermayer committed
78
qpel{8,16}_mc??_old_c / *pixels{8,16}_l4
79 80
    Just used to work around a bug in an old libavcodec encoder version.
    Don't optimize them.
Michael Niedermayer's avatar
Michael Niedermayer committed
81

82
tpel_mc_func {put,avg}_tpel_pixels_tab
83
    Used only for SVQ3, so only optimize them if you need fast SVQ3 decoding.
84

Michael Niedermayer's avatar
Michael Niedermayer committed
85
add_bytes/diff_bytes
86
    For huffyuv only, optimize if you want a faster ffhuffyuv codec.
Michael Niedermayer's avatar
Michael Niedermayer committed
87 88

get_pixels / diff_pixels
89
    Used for encoding, easy.
90

Michael Niedermayer's avatar
Michael Niedermayer committed
91
clear_blocks
92
    easiest to optimize
93

Michael Niedermayer's avatar
Michael Niedermayer committed
94
gmc
95 96
    Used for MPEG-4 gmc.
    Optimizing this should have a significant effect on the gmc decoding
97
    speed.
Michael Niedermayer's avatar
Michael Niedermayer committed
98

Michael Niedermayer's avatar
Michael Niedermayer committed
99
gmc1
100 101
    Used for chroma blocks in MPEG-4 gmc with 1 warp point
    (there are 4 luma & 2 chroma blocks per macroblock, so
102 103
    only 1/3 of the gmc blocks use this, the other 2/3
    use the normal put_pixel* code, but only if there is
104 105
    just 1 warp point).
    Note: DivX5 gmc always uses just 1 warp point.
Michael Niedermayer's avatar
Michael Niedermayer committed
106

Michael Niedermayer's avatar
Michael Niedermayer committed
107
pix_sum
108
    Used for encoding.
109

110
hadamard8_diff / sse / sad == pix_norm1 / dct_sad / quant_psnr / rd / bit
111 112 113 114
    Specific compare functions used in encoding, it depends upon the
    command line switches which of these are used.
    Don't waste your time with dct_sad & quant_psnr, they aren't
    really useful.
Michael Niedermayer's avatar
Michael Niedermayer committed
115 116

put_pixels_clamped / add_pixels_clamped
117 118 119
    Used for en/decoding in the IDCT, easy.
    Note, some optimized IDCTs have the add/put clamped code included and
    then put_pixels_clamped / add_pixels_clamped will be unused.
Michael Niedermayer's avatar
Michael Niedermayer committed
120 121

idct/fdct
122 123 124 125
    idct (encoding & decoding)
    fdct (encoding)
    difficult to optimize

Michael Niedermayer's avatar
Michael Niedermayer committed
126
dct_quantize_trellis
127
    Used for encoding with trellis quantization.
128
    difficult to optimize
Michael Niedermayer's avatar
Michael Niedermayer committed
129 130

dct_quantize
131
    Used for encoding.
132

Michael Niedermayer's avatar
Michael Niedermayer committed
133
dct_unquantize_mpeg1
134
    Used in MPEG-1 en/decoding.
Michael Niedermayer's avatar
Michael Niedermayer committed
135 136

dct_unquantize_mpeg2
137
    Used in MPEG-2 en/decoding.
Michael Niedermayer's avatar
Michael Niedermayer committed
138 139

dct_unquantize_h263
140
    Used in MPEG-4/H.263 en/decoding.
Michael Niedermayer's avatar
Michael Niedermayer committed
141 142

FIXME remaining functions?
143
BTW, most of these functions are in dsputil.c/.h, some are in mpegvideo.c/.h.
Michael Niedermayer's avatar
Michael Niedermayer committed
144 145


146

Michael Niedermayer's avatar
Michael Niedermayer committed
147
Alignment:
148
Some instructions on some architectures have strict alignment restrictions,
149
for example most SSE/SSE2 instructions on x86.
150
The minimum guaranteed alignment is written in the .h files, for example:
Diego Biurrun's avatar
Diego Biurrun committed
151
    void (*put_pixels_clamped)(const int16_t *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
Michael Niedermayer's avatar
Michael Niedermayer committed
152 153


154 155 156
General Tips:
-------------
Use asm loops like:
157
__asm__(
158 159
    "1: ....
    ...
160
    "jump_instruction ....
Michael Niedermayer's avatar
Michael Niedermayer committed
161
Do not use C loops:
162
do{
163
    __asm__(
164 165 166
        ...
}while()

167 168 169 170 171 172 173 174
For x86, mark registers that are clobbered in your asm. This means both
general x86 registers (e.g. eax) as well as XMM registers. This last one is
particularly important on Win64, where xmm6-15 are callee-save, and not
restoring their contents leads to undefined results. In external asm (e.g.
yasm), you do this by using:
cglobal functon_name, num_args, num_regs, num_xmm_regs
In inline asm, you specify clobbered registers at the end of your asm:
__asm__(".." ::: "%eax").
175 176 177 178 179 180
If gcc is not set to support sse (-msse) it will not accept xmm registers
in the clobber list. For that we use two macros to declare the clobbers.
XMM_CLOBBERS should be used when there are other clobbers, for example:
__asm__(".." ::: XMM_CLOBBERS("xmm0",) "eax");
and XMM_CLOBBERS_ONLY should be used when the only clobbers are xmm registers:
__asm__(".." :: XMM_CLOBBERS_ONLY("xmm0"));
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203

Do not expect a compiler to maintain values in your registers between separate
(inline) asm code blocks. It is not required to. For example, this is bad:
__asm__("movdqa %0, %%xmm7" : src);
/* do something */
__asm__("movdqa %%xmm7, %1" : dst);
- first of all, you're assuming that the compiler will not use xmm7 in
   between the two asm blocks.  It probably won't when you test it, but it's
   a poor assumption that will break at some point for some --cpu compiler flag
- secondly, you didn't mark xmm7 as clobbered. If you did, the compiler would
   have restored the original value of xmm7 after the first asm block, thus
   rendering the combination of the two blocks of code invalid
Code that depends on data in registries being untouched, should be written as
a single __asm__() statement. Ideally, a single function contains only one
__asm__() block.

Use external asm (nasm/yasm) or inline asm (__asm__()), do not use intrinsics.
The latter requires a good optimizing compiler which gcc is not.

Inline asm vs. external asm
---------------------------
Both inline asm (__asm__("..") in a .c file, handled by a compiler such as gcc)
and external asm (.s or .asm files, handled by an assembler such as yasm/nasm)
204
are accepted in FFmpeg. Which one to use differs per specific case.
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221

- if your code is intended to be inlined in a C function, inline asm is always
   better, because external asm cannot be inlined
- if your code calls external functions, yasm is always better
- if your code takes huge and complex structs as function arguments (e.g.
   MpegEncContext; note that this is not ideal and is discouraged if there
   are alternatives), then inline asm is always better, because predicting
   member offsets in complex structs is almost impossible. It's safest to let
   the compiler take care of that
- in many cases, both can be used and it just depends on the preference of the
   person writing the asm. For new asm, the choice is up to you. For existing
   asm, you'll likely want to maintain whatever form it is currently in unless
   there is a good reason to change it.
- if, for some reason, you believe that a particular chunk of existing external
   asm could be improved upon further if written in inline asm (or the other
   way around), then please make the move from external asm <-> inline asm a
   separate patch before your patches that actually improve the asm.
222

Michael Niedermayer's avatar
Michael Niedermayer committed
223 224

Links:
225
======
Michael Niedermayer's avatar
Michael Niedermayer committed
226 227
http://www.aggregate.org/MAGIC/

228
x86-specific:
229
-------------
Michael Niedermayer's avatar
Michael Niedermayer committed
230 231
http://developer.intel.com/design/pentium4/manuals/248966.htm

232
The IA-32 Intel Architecture Software Developer's Manual, Volume 2:
Michael Niedermayer's avatar
Michael Niedermayer committed
233 234 235 236 237 238 239 240
Instruction Set Reference
http://developer.intel.com/design/pentium4/manuals/245471.htm

http://www.agner.org/assem/

AMD Athlon Processor x86 Code Optimization Guide:
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22007.pdf

241 242

ARM-specific:
243
-------------
244 245 246 247 248 249 250 251 252 253 254 255
ARM Architecture Reference Manual (up to ARMv5TE):
http://www.arm.com/community/university/eulaarmarm.html

Procedure Call Standard for the ARM Architecture:
http://www.arm.com/pdfs/aapcs.pdf

Optimization guide for ARM9E (used in Nokia 770 Internet Tablet):
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0240b/DDI0240A.pdf
Optimization guide for ARM11 (used in Nokia N800 Internet Tablet):
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0211j/DDI0211J_arm1136_r1p5_trm.pdf
Optimization guide for Intel XScale (used in Sharp Zaurus PDA):
http://download.intel.com/design/intelxscale/27347302.pdf
256
Intel Wireless MMX 2 Coprocessor: Programmers Reference Manual
257
http://download.intel.com/design/intelxscale/31451001.pdf
258

259
PowerPC-specific:
260
-----------------
261
PowerPC32/AltiVec PIM:
262 263
www.freescale.com/files/32bit/doc/ref_manual/ALTIVECPEM.pdf

264
PowerPC32/AltiVec PEM:
265 266 267 268 269
www.freescale.com/files/32bit/doc/ref_manual/ALTIVECPIM.pdf

CELL/SPU:
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/30B3520C93F437AB87257060006FFE5E/$file/Language_Extensions_for_CBEA_2.4.pdf
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/9F820A5FFA3ECE8C8725716A0062585F/$file/CBE_Handbook_v1.1_24APR2007_pub.pdf
270

Michael Niedermayer's avatar
Michael Niedermayer committed
271
SPARC-specific:
272
---------------
Michael Niedermayer's avatar
Michael Niedermayer committed
273 274 275
SPARC Joint Programming Specification (JPS1): Commonality
http://www.fujitsu.com/downloads/PRMPWR/JPS1-R1.0.4-Common-pub.pdf

276 277 278
UltraSPARC III Processor User's Manual (contains instruction timings)
http://www.sun.com/processors/manuals/USIIIv2.pdf

279 280
VIS Whitepaper (contains optimization guidelines)
http://www.sun.com/processors/vis/download/vis/vis_whitepaper.pdf
Michael Niedermayer's avatar
Michael Niedermayer committed
281

Michael Niedermayer's avatar
Michael Niedermayer committed
282
GCC asm links:
283
--------------
Michael Niedermayer's avatar
Michael Niedermayer committed
284 285 286
official doc but quite ugly
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

287
a bit old (note "+" is valid for input-output, even though the next disagrees)
288
http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf