Low-hanging fruit - Universidad Nacional de Córdoba · contíguos de 64 bytes . 8 doubles, 16 oats...

Post on 28-Sep-2020

0 views 0 download

Transcript of Low-hanging fruit - Universidad Nacional de Córdoba · contíguos de 64 bytes . 8 doubles, 16 oats...

Low-hangingfruitCarlosBederián,carlos.bederian@unc.edu.ar

NicolásWolovick,nicolasw@famaf.unc.edu.ar

1/45

MotivaciónEnHPCsepuedellegarrelativamentelejosconpocotrabajo

BuenusodelasherramientasdisponiblesParalelizacióncondirectivasBibliotecas

¡Ysepuedellegaraningunapartedespuésdemuchotrabajo!

"Optimizar"todoamano

2/45

AgendaHoy:Mejorarperformancefácilmenteconelcompilador

Ytodoslosrabbitholesdondenometerse

Mañana:Herramientasparaverpordóndeseguir

3/45

Unsegundo...¿EstonoeradeHPC?

4/45

EncuestaausuariosCCAD¿Cuántosrecursospodríaaprovecharsicontaraconusoexclusivopor1mes?

5/45

CompiladoresUncompiladormodernoes:

Unfrontendqueconvierteelcódigoenunlenguajeparticularaunarepresentaciónintermedia(IR)

PreprocesadorAnálisisléxicoAnálisissintácticoAnálisissemántico

UnmiddleendquetransformalarepresentaciónintermediaAnálisisyoptimización

Unbackendquetransformalarepresentaciónintermediaalaarquitecturaencuestión

OptimizaciónparalaarquitecturaGeneracióndecódigo

6/45

GCCClásicasuitedecompiladoresdeGNU

Iniciadoen1987porRichardStallmanLicenciaGPL(copyleft)Ada,C,C++,D,Fortran,Go,Objective-CSoportaprácticamentecualquierarquitecturaÚltimaversión:GCC9.1.0(abril2019)

7/45

LLVMColecciónmodulardetecnologíaparacompiladores

Iniciadoen2003porChrisLattnerLicenciaUIUC/NCSAAltamentemodular

ReemplazodebackenddeGCCClang(Apple),compiladorcompletoparaC,C++,Objective-CCUDA,ISPC,Julia,OpenCL,Rust,Swift...Flang/f18(NVIDIA),compiladorFortran2018

SoportedearquitecturasgeneralmenteprovistoporlosfabricantesmismosAunquenosiempreencódigoabierto

GeneralmentecompatibleconGCCenparámetrosyextensionesÚltimaversión:LLVM8.0(marzo2019)

8/45

IntelSuitepropietariadecompiladoresparaHPC

PropietarioCaro(paranosotros)

Licenciasespecialesparaestudiantes,proyectosopensource,educadoresC,C++,FortranOptimizadoparaarquitecturasIntel

...yavecesofuscadoparaAMDÚltimaversión:ParallelStudioXE2019Update4(junio2019)

9/45

ConsiguiendocompiladoresCadaversiónnuevadeuncompiladortiene:

Bug�xesSoportedeversionesnuevasdelenguajesenelfrontendMásomejoresoptimizaciones

Formasdeobtenerlaúltimaversión:

EsperarunanuevaversióndeladistribucióndelinuxUsarrepositoriosthird-partyBajarloycompilarlo

Spack,Easybuild

10/45

OptimizacionesdelcompiladorProblemaNP-completooindecidible

Transformacionesdecódigoporotroequivalenteadistintasescalas

PeepholeLocal(bloquebásico)LoopGlobal(función)Interprocedural

11/45

Strengthreduction,instructioncombiningReemplazodeexpresionesporotrasequivalentesconmenorcostocomputacional

4*a a<<2n%2==0 n&1==0i++;i++ i+=2x=0 x=x^xfor(i=0;i<N;++i)a[i]=0; memset(a,0,N*sizeof(a[0]))

12/45

Punto�otanteElcompiladorgeneralmentenointentahacernadaconoperacionesdepunto�otante.

D.Goldberg,WhatEveryComputerScientistShouldKnowAboutFloating-PointArithmetic

-ffast-mathal...rescate?

ReordenamientoyreemplazodeinstruccionesPermiteaproximacionesconinversosActualizacióndeerrnoenfuncionesdepunto�otanteAsumequenohaycerosconsignoApagachecksdeNaNoceroenalgunoslugaresIgnoraexcepcionesdelhardwareDenormalstruncadosacero(enalgunoscompiladores)

EnloscompiladoresIntel,fp-modelfastvieneprendidopordefecto.

13/45

Adivinaadivinador¿Cuántodemoraenejecutarestecódigo?

#defineN1073741824ull

intmain(){double*a=malloc(N*sizeof(double));doublesum=0.0;for(size_ti=0;i<N;++i){sum+=a[i];}return0;}

14/45

DeadcodeeliminationElcompiladoreliminacódigoquenoseejecutaoquenoafectaelresultado

AnálisisagresivoActivadoen-O1

Pesadillaparalagentequepiensaenseguridad¡Noavisacuandolohace!

15/45

ConstantfoldingElcompiladorcalculaentiempodecompilaciónlosresultadosquepuede.

ConstantpropagationElcompiladorllevarastrodelosvaloresdelasvariables.

Lacombinaciónconotrasoptimizacionesespoderosa:Deadcodeelimination:SalteaguardasinnecesariasStrengthreduction:Convierteoperacionescarascomo%Constantfolding:Pre-calculaexpresionesmáscomplejas

Fijacotasdeloops

16/45

Constantfolding(...)intconstant_sum(void){intsum=0;for(inti=1;i<=5;++i){sum+=i;}returnsum;}

17/45

LiverangeanalysisConstantpropagationrecargado.Elcompiladorllevarastroderangosdevaloresdelasvariables.

intsquare(intx){inty=x*x;if(y<0){printf("Acánoselleganunca");}returny;}

18/45

CommonsubexpressioneliminationElcompiladorahorratrabajosacandofactorcomún.

Aplicaalcálculodeposicionesenmatricesysusvecinos

floatcse(floata,floatb,floatc){floatx=(a*b)-c;floaty=(a*b)+c;returnx/y;}

19/45

VariablerenamingElcompiladorgeneracopiasdevariablesquesereutilizanconpropósitosindependientes.

Permiteparalelismoenlaejecución

OptimizaciónquevienegratisconlaconversiónaformaSSA

20/45

InvarianthoistingElcompiladordetectacódigoinvariantedentrodeunloopylomueveafuera.

InductionvariableanalysisElcompiladoranalizacómoseutilizalavariabledeinduccióndentrodelloopytransformalasexpresiones

voidzero_odd(floata[]){for(inti=0;i<N;++i){a[2*i+1]=0.0f;}}

21/45

LoopunrollingElcompiladordespliegaunloopdemaneraquecadaiteraciónoperesobremúltipleselementos.

MuchoparalelismodisponibleAltísimocostoencachedeinstrucciones

voidarray_sum(floata[],floatb[],floatc[]){for(inti=0;i<N;++i){c[i]=a[i]+b[i];}}

voidarray_sum_unrolled(floata[],floatb[],floatc[]){inti;for(i=0;i<N-i%4;i+=4){c[i+0]=a[i+0]+b[i+0];c[i+1]=a[i+1]+b[i+1];c[i+2]=a[i+2]+b[i+2];c[i+3]=a[i+3]+b[i+3];}for(;i<N;++i){c[i]=a[i]+b[i];}}

22/45

LoopunswitchingDehaberunacondicióninvariantedentrodeunloop,elcompiladorlaextraeygenerardosversionesdelloop.

voidarray_divide(floata[],floatd){for(inti=0;i<N;++i){if(d==0.0f){a[i]=0.0f;}else{a[i]=a[i]/d;}}}

23/45

LooppeelingSeparariteracionesconcomportamientodistinto(generalmentelaprimera)

Enestemomento,gcc,clangeiccnosabensepararlasiteracionesdelbordedelresto.

voidstencil(floata[],floatb[],intN){for(unsignedinti=0;i<N;++i){if(i==0){b[i]=a[i+1]/2;}elseif(i==N-1){b[i]=a[i-1]/2;}else{//0<i<N-1b[i]=(a[i-1]+a[i+1])/2;}}}

24/45

Loop�ssion,loopfusionSepararounirloopsindependientesquecorrensobreelmismorango.

voidinit(floata[],floatb[],floatc[]){for(inti=0;i<N;++i){a[i]=f();b[i]=g();c[i]=h();}}

25/45

MatricesenmemoriaLasmatricessetienenqueguardarenmemoria,queesunidimensional.

ParaunamatrizA :

Fortran:A(y,x) x*N+y("column-major")C:A[y][x] y*N+x("row-major")

Estoesimportanteporquelamemoriayelprocesadoroperansobresegmentoscontíguosde64bytes .

8doubles,16�oats¡Loquenoseutilizaesanchodebandadememoriamalgastado!

���

[� ∗ 64, (� + 1) ∗ 64)

26/45

LoopinterchangeIntercambiodeloopsanidadosparamejorlocalidad.

Ojoacá:SaberlasrazonesyescribirlobiendesdeunprincipionoafectalalegibilidadNosiempreleaciertaelcompilador(GCCenparticular)

floata[N][N],b[N][N],c[N][N];

voidmatmul(){for(inty=0;y<N;++y)for(intx=0;x<N;++x)for(intk=0;k<N;++k)c[y][x]+=a[y][k]*b[k][x];}

27/45

Loopblocking/tilingParticionarlasiteracionesparaobtenermejorlocalidaddememoria.

Ejemplopatológico:Transponerunamatriz

¡11%decachemisses!

floatA[N][N],At[N][N];

voidtranspose(){for(inty=0;y<N;++y)for(intx=0;x<N;++x)At[x][y]=A[y][x];}

28/45

ConloopblockingfloatA[N][N],At[N][N];

voidtranspose(){for(by=0;by<N;by+=BY){for(bx=0;bx<N;bx+=BX){for(y=by;y<by+BY;++y){for(x=bx;x<bx+BX;++x){At[x][y]=A[y][x];}}}}}

29/45

InliningReemplazarunllamadoafunciónpordirectamentecopiarelcuerpodelafuncióndentrodelcódigodelllamador

SeahorratodoelprocesodellamadoafunciónPasajedeparámetros,prólogo,epílogo

SepagaconduplicacióndecódigoPresiónsobreelcachedeinstrucciones

ElcompiladorestimaconheurísticassiconvieneNota:Silafunciónesvisiblefueradelmódulo,tambiénsegeneralaversiónestándarNotienesentidousarmacrosparaesto

30/45

Link-timeoptimizationLasoptimizacionesgeneralmenteselimitanaunaunidaddecompilaciónporcómosellamaalcompilador.

ConLTO(GCC:-flto,Intel:-ipo)sólosecorreelfrontendsobrecadaunidaddecompilación,yelrestodelasfasessedejanparaelmomentodelinkdetodoelprograma.

Nota:Requieretoolchainmoderna

31/45

AutovectorizaciónLosprocesadorestieneninstruccionesvectorialesqueoperansobreconjuntosdeelementosdelongitud�ja.

EnunprocesadorconAVX-512,noutilizarinstruccionesvectorialesparadoublesestirar~80%delaperformanceLoselementosgeneralmentetienenqueestarcontíguosenmemoriaLoselementostienenqueserindependientes

32/45

Códigoautovectorizado1.(Aveces)Loopinicialescalarhastallegaradirecciónalineada2.Loopvectorizado,procesamúltipleselementosporciclo3.Loopescalarparaelrestodeloselementos

Nota:Silacantidaddeelementosespequeña,estoesmáslento

33/45

¿Ysinoautovectoriza?Elautovectorizadornofuncionaparacódigorelativamentecomplejo:acáesdondehayqueoptimizar

1.Revisarmensajesdediagnósticodelcompiladorporlosquenovectorizóunloopyarreglarlos

Motivo#1:lascosasestánmaldispuestasenmemoria2.IndicarlealcompiladorcondirectivasOpenMPSIMD3.Usarotrolenguajemásamigableparavectorizar(e.g.SYCL,ISPC)4.Vectorizaramanoconintrinsics

34/45

AutoparalelizaciónElcompiladoranalizasilasiteracionesdeunloopsonindependientes,ylasreparteentrehilossiconviene.

Engeneralnofunciona,peronuncaestádemásprobar...

35/45

SeleccióndearquitecturaElcompiladortieneunmodelodelasunidadesdeejecucióndelprocesador:

CostoylatenciadecadainstrucciónPuertosdeejecuciónSetsdeinstruccionessoportados

Siunonoledicenada,elcompiladorgeneracódigoparacualquierprocesador

EnX86-64,estoesunprocesadorconSSEySSE2...de2003.

36/45

Feedback-drivenoptimizationMuchasdelasoptimizacionessedecidensegúnheurísticas.FDOsetratadeobservarelprogramaenfuncionamientoparacompilarloconmásconocimiento.

1.Primerapasada:Compilarelprogramaconinstrumentacióndelcompiladorparaobtenermétricas

AlternativanuevaparaGCC/Clang:AutoFDO,obtienemétricasdeunacompilaciónnormaldelprogramautilizandoperf.

2.Correrelprogramatratandodeejercitartodoelcódigo3.Segundapasada:Compilarnuevamenteelprogramapasándolealcompiladorlas

métricasobtenidas

37/45

JuntandotodoQueremosaplicartodaslasoptimizacionesposibles(-O3)Lasdepunto�otantetambién(GCC:-ffast-math,Intel:-fp-modelfast=2-no-prec-div)Optimizarentredistintasfuncionesymódulos(GCC:-flto,Intel:-ipo)Paraelprocesadorquetenemos(GCC:-march=native,Intel:-xHost)Obteniendométricasparaoptimizarmejor(GCC:-fprofile-generate,Intel:-prof-gen)

...ousandolainformaciónqueobtuvimos(GCC:-fprofile-use,Intel:-prof-use)

Incluirinformacióndedebuggingparaelpro�ler(-g)Versiloopblockingayuda(GCC:-floop-block)Avisamedóndenopudistevectorizar(GCC:-fopt-info-vec-missed,Intel:-qopt-report-qopt-report-phase=vec)

38/45

PythonCPythonesunintérpretelento

SellamanfuncionesybibliotecasimplementadasenFortran,CoC++paracualquiercosapesada

NumPyparatodo¿AquéBLASyLAPACKllama?¿ConquécompiladorsecompilóelcódigoFortran?

Sinoalcanza,probarconNumba

39/45

DistribucionesdePythonLaquevinoconladistrodeLinux

UsaelBLASinstalado(ATLASuOpenBLAS)Compiladocongfortrandeladistribución

AnacondaMantenidaporContinuumMezcladepackagemanagerconvirtualenvOpcióndeMKLuOpenBLASEngeneralelPythonmásrápido

Amano

40/45

NumbaPermitemarcarcódigoPython+NumpycondecoradoresparaqueseacompiladoconLLVM.

AplicablesóloparaunsubconjuntodellenguajeSoportacorrerenGPUsyparalelizar

importnumbaimportnumpy

@numba.jitdefsum(x):total=0foriinrange(x.shape[0]):total+=x[i]returntotal

x=numpy.arange(10_000_000);%timesum(x)%timesum(x)

41/45

JuliaLenguajeinterpretadoespecí�camentecreadoparaaplicacionescientí�cas.

SintaxisfamiliarparausuariosdeFortran1-basedarrays

HerramientasmodernasJupyternotebooks

EcosistemacrecienteDiseñadoparaperformance

ElcódigoenrealidadsecompilaconLLVM

42/45

AplicacionesHPC1.Bajarbinariosoptimizadosporlosdesarrolladores

Siesnecesariorecompilar(e.g.porusarotroMPI),versitienenopcionesdecompiladorsugeridas

2.BuscarotragentedelrubroquelohayahechoXCONFIGURE(deIntel,paraIntel)HPCAdvisoryCouncilBestPracticesSpackEasybuild

3.Soborneasusysadminfavorito

43/45

Elelefanteenlahabitación¿YTensorFlow?

44/45

Q&A

45/45