View
1
Download
0
Category
Preview:
Citation preview
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
Recommended