85
Go Native Squeeze the juice out of your 64-bit processor using…

Go Native : Squeeze the juice out of your 64-bit processor using C++

Embed Size (px)

Citation preview

Page 1: Go Native : Squeeze the juice out of your 64-bit processor using C++

Go Native

Squeeze the juice out of your 64-bit processor

using…

Page 2: Go Native : Squeeze the juice out of your 64-bit processor using C++

Go Native

Squeeze the juice out of your 64-bit processor

using…

C/C++

Page 3: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who am I

Page 4: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who am I

-> Fernando Moreira ( @fpmore )

Page 5: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who am I

-> Fernando Moreira ( @fpmore )

-> MSc student @ FEUP

Page 6: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who am I

-> Fernando Moreira ( @fpmore )

-> MSc student @ FEUP

-> Undergraduate Researcher @ Porto Interactive Center

Page 7: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who am I

-> Fernando Moreira ( @fpmore )

-> MSc student @ FEUP

-> Undergraduate Researcher @ Porto Interactive Center

-> Microsoft Student Partner Lead @ M$ PT

Page 8: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who am I

-> Fernando Moreira ( @fpmore )

-> MSc student @ FEUP

-> Undergraduate Researcher @ Porto Interactive Center

-> Microsoft Student Partner Lead @ M$ PT

-> I’ve doing C++ for over… 5y

Page 9: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

Page 10: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte

Page 11: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro

Page 12: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul

Page 13: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul . Açores

Page 14: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul . Açores . Madeira

Page 15: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul . Açores . Madeira . FMI

Page 16: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul . Açores . Madeira . FMI

-> Who has experience with C?

Page 17: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul . Açores . Madeira . FMI

-> Who has experience with C? And with C++?

Page 18: Go Native : Squeeze the juice out of your 64-bit processor using C++

Who are you ?

-> Norte . Centro . Sul . Açores . Madeira . FMI

-> Who has experience with C? And with C++?

-> Who has experience with 64bit native dev?

Page 19: Go Native : Squeeze the juice out of your 64-bit processor using C++

Talk’s Schedule

int main( int argc, char **argv ) {

try {

} catch( Timeout &e ) { return -1; }

return 0;

}

Page 20: Go Native : Squeeze the juice out of your 64-bit processor using C++

Talk’s Schedule

int main( int argc, char **argv ) {

try {

introducing_x64();

} catch( Timeout &e ) { return -1; }

return 0;

}

Page 21: Go Native : Squeeze the juice out of your 64-bit processor using C++

Talk’s Schedule

int main( int argc, char **argv ) {

try {

introducing_x64();

advantagesOver_x86();

} catch( Timeout &e ) { return -1; }

return 0;

}

Page 22: Go Native : Squeeze the juice out of your 64-bit processor using C++

Talk’s Schedule

int main( int argc, char **argv ) {

try {

introducing_x64();

advantagesOver_x86();

nativeDev_x64( const Topic &t );

} catch( Timeout &e ) { return -1; }

return 0;

}

Promising not to change the topic.

Page 23: Go Native : Squeeze the juice out of your 64-bit processor using C++

Talk’s Schedule

int main( int argc, char **argv ) {

try {

introducing_x64();

advantagesOver_x86();

nativeDev_x64( const Topic &t );

codeAnalysis_and_DebugTools();

} catch( Timeout &e ) { return -1; }

return 0;

}

Page 24: Go Native : Squeeze the juice out of your 64-bit processor using C++

Talk’s Schedule

int main( int argc, char **argv ) {

try {

introducing_x64();

advantagesOver_x86();

nativeDev_x64( const Topic &t );

codeAnalysis_and_DebugTools();

costProspectionOn_x64Dev();

} catch( Timeout &e ) { return -1; }

return 0;

}

Page 25: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

Page 26: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

-> The names : x64, x86-64, AMD64, Intel 64, IA-64, etc…

Page 27: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

-> The names : x64, x86-64, AMD64, Intel 64, IA-64, etc…

-> Notice : IA-64 ≠ AMD64

Page 28: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

-> The names : x64, x86-64, AMD64, Intel 64, IA-64, etc…

-> Notice : IA-64 ≠ AMD64

-> AMD64 is backwards compatible with x86 (IA-64 isn’t)

Page 29: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

-> The names : x64, x86-64, AMD64, Intel 64, IA-64, etc…

-> Notice : IA-64 ≠ AMD64

-> AMD64 is backwards compatible with x86 (IA-64 isn’t)

-> Some Hardware: Phenom, Athlon 64, Core-iX, Core 2, …

Page 30: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

-> The names : x64, x86-64, AMD64, Intel 64, IA-64, etc…

-> Notice : IA-64 ≠ AMD64

-> AMD64 is backwards compatible with x86 (IA-64 isn’t)

-> Some Hardware: Phenom, Athlon 64, Core-iX, Core 2, …

-> Some OS’s : Win(XP.Vista.7), OSX, Several Linux distros.

Page 31: Go Native : Squeeze the juice out of your 64-bit processor using C++

introducing_x64()

This talk will be focused on the AMD64 architecture.

Page 32: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

Page 33: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

-> Address space : Theoretical limit of 16 ExaBytes (2^64)

Page 34: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

-> Address space : Theoretical limit of 16 ExaBytes (2^64)

-> More available registers. (there’s one called RIP)

Page 35: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

-> Address space : Theoretical limit of 16 ExaBytes (2^64)

-> More available registers. (there’s one called RIP)

-> Larger instruction set with emphasis on SIMD

Page 36: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

-> Address space : Theoretical limit of 16 ExaBytes (2^64)

-> More available registers. (there’s one called RIP)

-> Larger instruction set with emphasis on SIMD

-> SSE1, SSE2, and SSE3 are always there

Page 37: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

-> Address space : Theoretical limit of 16 ExaBytes (2^64)

-> More available registers. (there’s one called RIP)

-> Larger instruction set with emphasis on SIMD

-> SSE1, SSE2, and SSE3 are always there

-> Unified function calling convention

Page 38: Go Native : Squeeze the juice out of your 64-bit processor using C++

advantagesOver_x86()

Can run x86 environmentsCan run x86 binaries under x64

environments

On Windows: . 32bit processes can’t load 64bit DLLs for execution

. 64bit processes can’t load 32bit DLLs for execution

Page 39: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( how_it_looks_like )

Page 40: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( how_it_looks_like )

-> A valid, yet useless, 64bit application.

int main( int argc, char **argv } { return 0;}

Page 41: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( how_it_looks_like )

-> A valid, yet useless and dangerous, 64bit application.

int main( int argc, char **argv } {

size_t external_debt = SIZE_MAX; int *ptr = &external_debt; *ptr = 0;

return 0;}

Page 42: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( how_it_looks_like )

-> A valid, yet useless and dangerous, 64bit application.

int main( int argc, char **argv } {

size_t external_debt = SIZE_MAX; int *ptr = &external_debt; *ptr = 0;

return 0;}

Page 43: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

Page 44: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

Page 45: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

-> On Linux : LP64 model

Page 46: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

-> On Linux : LP64 model

-> LLP64: short( 2 ), int( 4 ), long( 4 ), ptr( 8 ), long long(8)

Page 47: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

-> On Linux : LP64 model

-> LLP64: short( 2 ), int( 4 ), long( 4 ), ptr( 8 ), long long(8)

-> LP64: short( 2 ), int( 4 ), long( 8 ), ptr( 8 ), long long( 8 )

Page 48: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

-> On Linux : LP64 model

-> LLP64: short( 2 ), int( 4 ), long( 4 ), ptr( 8 ), long long(8)

-> LP64: short( 2 ), int( 4 ), long( 8 ), ptr( 8 ), long long( 8 )

Can you see the data portability problem?

Page 49: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

-> On Linux : LP64 model

-> LLP64: short( 2 ), int( 4 ), long( 4 ), ptr( 8 ), long long(8)

-> LP64: short( 2 ), int( 4 ), long( 8 ), ptr( 8 ), long long( 8 )

Suggestions: Use conditional compilation and type aliasing.

Page 50: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On Microsoft Win64 : LLP64 model

-> On Linux : LP64 model

-> LLP64: short( 2 ), int( 4 ), long( 4 ), ptr( 8 ), long long(8)

-> LP64: short( 2 ), int( 4 ), long( 8 ), ptr( 8 ), long long( 8 )

Suggestions: Use conditional compilation and type aliasing. Make conscious usage of the sizeof operator.

Page 51: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On x86 : ptr( 4 ), size_t( 4 ), ptrdiff_t( 4 )

Page 52: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On x86 : ptr( 4 ), size_t( 4 ), ptrdiff_t( 4 )

-> On x64 : ptr( 8 ), size_t( 8 ), ptrdiff_t( 8 )

Page 53: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( data_model )

-> On x86 : ptr( 4 ), size_t( 4 ), ptrdiff_t( 4 )

-> On x64 : ptr( 8 ), size_t( 8 ), ptrdiff_t( 8 )

These ones will increase memory usage…

But will be performance-wise.

Page 54: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( common_pitfalls )

Page 55: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( common_pitfalls )

-> Usage of magic numbers & bit-wise ops: 0x7fffffff

Page 56: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( common_pitfalls )

-> Usage of magic numbers & bit-wise ops: 0x7fffffff

-> Functions with variable number of arguments : printf

Page 57: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( common_pitfalls )

-> Usage of magic numbers & bit-wise ops: 0x7fffffff

-> Functions with variable number of arguments : printf

-> Virtual functions

Page 58: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( common_pitfalls )

-> Usage of magic numbers & bit-wise ops: 0x7fffffff

-> Functions with variable number of arguments : printf

-> Virtual functions

-> Data exchange between x86 and x64 apps

Page 59: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( common_pitfalls )

-> Usage of magic numbers & bit-wise ops: 0x7fffffff

-> Functions with variable number of arguments : printf

-> Virtual functions

-> Data exchange between x86 and x64 apps

-> Data misalignment : SSE requires 16-byte alignment

Page 60: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( optimization_tips )

Page 61: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( optimization_tips )

-> Use native types for loops or tight data usage

Page 62: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( optimization_tips )

-> Use native types for loops or tight data usage

-> Use 16-byte alignment for SSE loads and stores

Page 63: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( optimization_tips )

-> Use native types for loops or tight data usage

-> Use 16-byte alignment for SSE loads and stores

-> Heap-allocs in Win64 and XBOX360 are 16-byte aligned

Page 64: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( optimization_tips )

-> Use native types for loops or tight data usage

-> Use 16-byte alignment for SSE loads and stores

-> Heap-allocs in Win64 and XBOX360 are 16-byte aligned

-> *Use* intrinsics : #include <immintrin.h>

Page 65: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( optimization_tips )

-> Use native types for loops or tight data usage

-> Use 16-byte alignment for SSE loads and stores

-> Heap-allocs in Win64 and XBOX360 are 16-byte aligned

-> *Use* intrinsics : #include <immintrin.h>

-> Unroll loops and sort object’s member data by their size

Page 66: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( real-world_tips )

Page 67: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( real-world_tips )

-> Don’t sacrifice your software architecture.

Page 68: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( real-world_tips )

-> Don’t sacrifice your software architecture.

-> Don’t use it if you don’t know how to.

Page 69: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( real-world_tips )

-> Don’t sacrifice your software architecture.

-> Don’t use it if you don’t know how to.

-> Don’t go into premature optimization.

Page 70: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( real-world_tips )

-> Don’t sacrifice your software architecture.

-> Don’t use it if you don’t know how to.

-> Don’t go into premature optimization.

-> Do it at lower levels and then hide it.

Page 71: Go Native : Squeeze the juice out of your 64-bit processor using C++

nativeDev_x64( real-world_tips )

-> Don’t sacrifice your software architecture.

-> Don’t use it if you don’t know how to.

-> Don’t go into premature optimization.

-> Do it at lower levels and then hide it.

-> Trust your compiler to help you do the job.

Page 72: Go Native : Squeeze the juice out of your 64-bit processor using C++

codeAnalysis_and_DebugTools()

Page 73: Go Native : Squeeze the juice out of your 64-bit processor using C++

codeAnalysis_and_DebugTools()

-> Your IDE : LEARN to fu**** use it!

Page 74: Go Native : Squeeze the juice out of your 64-bit processor using C++

codeAnalysis_and_DebugTools()

-> Your IDE : LEARN to fu**** use it!

-> Conditional break points, call-stack

Page 75: Go Native : Squeeze the juice out of your 64-bit processor using C++

codeAnalysis_and_DebugTools()

-> Your IDE : LEARN to fu**** use it!

-> Conditional break points, call-stack

-> Free tool : CppCheck (CmdLine, Eclipse, CodeBlocks, …)

Page 76: Go Native : Squeeze the juice out of your 64-bit processor using C++

codeAnalysis_and_DebugTools()

-> Your IDE : LEARN to fu**** use it!

-> Conditional break points, call-stack

-> Free tool : CppCheck (CmdLine, Eclipse, CodeBlocks, …)

-> State-of-the-art tool: PVS-Studio (VS 05,08,10)

Page 77: Go Native : Squeeze the juice out of your 64-bit processor using C++

codeAnalysis_and_DebugTools()

-> Your IDE : LEARN to fu**** use it!

-> Conditional break points, call-stack

-> Free tool : CppCheck (CmdLine, Eclipse, CodeBlocks, …)

-> State-of-the-art tool: PVS-Studio (VS 05,08,10)

-> Do pair programming and peer-review if possible

Page 78: Go Native : Squeeze the juice out of your 64-bit processor using C++

costProspectionOn_x64Dev()

Page 79: Go Native : Squeeze the juice out of your 64-bit processor using C++

costProspectionOn_x64Dev()

-> Hardware & Software (IDE + Plugins + Tools + Libs)

Page 80: Go Native : Squeeze the juice out of your 64-bit processor using C++

costProspectionOn_x64Dev()

-> Hardware & Software (IDE + Plugins + Tools + Libs)

-> You’ll need to teach the developers (theory & practice)

Page 81: Go Native : Squeeze the juice out of your 64-bit processor using C++

costProspectionOn_x64Dev()

-> Hardware & Software (IDE + Plugins + Tools + Libs)

-> You’ll need to teach the developers (theory & practice)

-> A port takes time, adds bugs, and it’s not creative

Page 82: Go Native : Squeeze the juice out of your 64-bit processor using C++

costProspectionOn_x64Dev()

-> Hardware & Software (IDE + Plugins + Tools + Libs)

-> You’ll need to teach the developers (theory & practice)

-> A port takes time, adds bugs, and it’s not creative

-> … plus you’ll probably have to maintain two code paths

Page 83: Go Native : Squeeze the juice out of your 64-bit processor using C++

costProspectionOn_x64Dev()

-> Hardware & Software (IDE + Plugins + Tools + Libs)

-> You’ll need to teach the developers (theory & practice)

-> A port takes time, adds bugs, and it’s not creative

-> … plus you’ll probably have to maintain two code paths

-> Full implementation adds creativity, but takes much more time and will add many more bugs.

Page 84: Go Native : Squeeze the juice out of your 64-bit processor using C++

Lets gostate-of-the-art!

Page 85: Go Native : Squeeze the juice out of your 64-bit processor using C++

Questions?