optimization.txt 10.4 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

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

get_pixels / diff_pixels
86
    Used for encoding, easy.
87

Michael Niedermayer's avatar
Michael Niedermayer committed
88
clear_blocks
89
    easiest to optimize
90

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

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

Michael Niedermayer's avatar
Michael Niedermayer committed
104
pix_sum
105
    Used for encoding.
106

107
hadamard8_diff / sse / sad == pix_norm1 / dct_sad / quant_psnr / rd / bit
108 109 110 111
    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
112 113

put_pixels_clamped / add_pixels_clamped
114 115 116
    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
117 118

idct/fdct
119 120 121 122
    idct (encoding & decoding)
    fdct (encoding)
    difficult to optimize

Michael Niedermayer's avatar
Michael Niedermayer committed
123
dct_quantize_trellis
124
    Used for encoding with trellis quantization.
125
    difficult to optimize
Michael Niedermayer's avatar
Michael Niedermayer committed
126 127

dct_quantize
128
    Used for encoding.
129

Michael Niedermayer's avatar
Michael Niedermayer committed
130
dct_unquantize_mpeg1
131
    Used in MPEG-1 en/decoding.
Michael Niedermayer's avatar
Michael Niedermayer committed
132 133

dct_unquantize_mpeg2
134
    Used in MPEG-2 en/decoding.
Michael Niedermayer's avatar
Michael Niedermayer committed
135 136

dct_unquantize_h263
137
    Used in MPEG-4/H.263 en/decoding.
Michael Niedermayer's avatar
Michael Niedermayer committed
138 139


140

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


148 149 150
General Tips:
-------------
Use asm loops like:
151
__asm__(
152 153
    "1: ....
    ...
154
    "jump_instruction ....
Michael Niedermayer's avatar
Michael Niedermayer committed
155
Do not use C loops:
156
do{
157
    __asm__(
158 159 160
        ...
}while()

161 162 163 164 165 166 167 168
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").
169 170 171 172 173 174
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"));
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193

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.

194 195 196 197 198
When debugging a x86 external asm compilation issue, if lost in the macro
expansions, add DBG=1 to your make command-line: the input file will be
preprocessed, stripped of the debug/empty lines, then compiled, showing the
actual lines causing issues.

199 200 201 202
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)
203
are accepted in FFmpeg. Which one to use differs per specific case.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

- 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.
221

Michael Niedermayer's avatar
Michael Niedermayer committed
222 223

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

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

231
The IA-32 Intel Architecture Software Developer's Manual, Volume 2:
Michael Niedermayer's avatar
Michael Niedermayer committed
232 233 234 235 236 237 238 239
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

240 241

ARM-specific:
242
-------------
243 244 245 246 247 248 249 250 251 252 253 254
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
255
Intel Wireless MMX 2 Coprocessor: Programmers Reference Manual
256
http://download.intel.com/design/intelxscale/31451001.pdf
257

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

263
PowerPC32/AltiVec PEM:
264 265 266 267 268
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
269

Michael Niedermayer's avatar
Michael Niedermayer committed
270
GCC asm links:
271
--------------
Michael Niedermayer's avatar
Michael Niedermayer committed
272 273 274
official doc but quite ugly
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

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