AMcoder - javascript, python, java, html, php, sql

OpenMP-ը կտրուկ դանդաղեցնում է հանգույցի արագությունը

Ես փորձում եմ արագացնել այս հանգույցը OpenMP-ի զուգահեռացման միջոցով: Ինձ մոտ այնպիսի տպավորություն էր, որ սա պետք է աշխատանքը բաժանի մի շարք թեմաների: Այնուամենայնիվ, երևի գերավճարը չափազանց մեծ է, որպեսզի դա ինձ արագացնի:

Պետք է նշեմ, որ այս օղակը շատ ու շատ անգամներ է լինում, և հանգույցի յուրաքանչյուր օրինակ պետք է զուգահեռացնել: Հանգույցի կրկնությունների թիվը՝ newNx, կարող է լինել 3-ից փոքր կամ 256-ի չափով: Այնուամենայնիվ, եթե պայմանականորեն այն զուգահեռացնեմ միայն newNx > 100-ի դեպքում (միայն ամենամեծ օղակները), այն դեռ զգալիորեն դանդաղում է:

Այստեղ կա՞ որևէ բան, որը կհանգեցնի նրան, որ դա ավելի դանդաղ կլինի, քան նախատեսված էր: Նշեմ նաև, որ A,v,b վեկտորները ՇԱՏ մեծ են, բայց հասանելիությունը O(1) է, կարծում եմ։

    #pragma omp parallel for private(j,k),shared(A,v,b)
    for(i=1;i<=newNx;i+=2) {
      for(j=1;j<=newNy;j++) { 
        for(k=1;k<=newNz;k+=1) {

          nynz=newNy*newNz; 

          v[(i-1)*nynz+(j-1)*newNz+k] = 
          -(v[(i-1)*nynz+(j-1)*newNz+k+1 - 2*(k/newNz)]*A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + kup+offA] + 
          v[(i-1)*nynz+(j-1)*newNz+ k-1+2*(1/k)]*A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + kdo+offA] + 
          v[(i-1)*nynz+(j - 2*(j/newNy))*newNz+k]*A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + jup+offA] + 
          v[(i-1)*nynz+(j-2 + 2*(1/j))*newNz+k]*A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + jdo+offA] + 
          v[(i - 2*(i/newNx))*nynz+(j-1)*newNz+k]*A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + iup+offA] + 
          v[(i-2 + 2*(1/i))*nynz+(j-1)*newNz+k]*A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + ido+offA] - 
          b[(i-1)*nynz + (j-1)*newNz + k])
          /A[((i-1)*nynz + (j-1)*newNz + (k-1))*spN + ifi+offA];}}}

  • Ես նույնպես պետք է կտրուկ դանդաղեցնեմ այս ամենից որևէ մեկը կարդալու համար... Ես չէի մեղադրի OpenMP-ին... 11.09.2013
  • Ընդամենը հինգ տառ՝ IOCCC (Լուրջ, եթե ջանք գործադրեք այս կոդը ավելի ընթեռնելի դարձնելու համար, գուցե ինչ-որ մեկը անի: մի քանի հուշում եմ տալիս) 11.09.2013
  • OpenMP-ը բավականին լավ է բեռնում Բարձր զուգահեռ-ը, ինչը նշանակում է, որ օղակի յուրաքանչյուր կրկնություն ՊԵՏՔ Է անկախ լինի մյուս բոլոր կրկնություններից: Երկրորդը, դուք պետք է ունենաք բավականաչափ կրկնություններ և բավականաչափ մեծ ծանրաբեռնվածություն, որպեսզի այն արժանի լինի, փոքր օղակ ունենալը, որտեղ յուրաքանչյուր կրկնություն արագ է կատարվում, սովորաբար չարժե, նույնիսկ եթե կան բազմաթիվ կրկնություններ: 12.09.2013
  • Շնորհակալություն... Դա հիմնականում զանգվածային զանգեր է 3 մեծ զանգվածների վրա, եթե չեք ցանկանում կարդալ այն 12.09.2013
  • Նայելով ձեր կրկնությունների քանակին... OpenMP-ը չի օգնի դրան, որպեսզի OpenMP-ն օգնի ձեզ, պետք է շատ ավելի բարձր կրկնությունների քանակ, և օղակի յուրաքանչյուր կրկնություն պետք է շատ ավելի նշանակալի լինի: Դուք, հավանաբար, բախվում եք այլ խնդիրների, ինչպիսիք են հղման վայրը: Ես շատ կառաջարկեի գործարկել պրոֆիլավորող՝ պարզելու, թե ինչն է պետք օպտիմալացնել՝ պարզապես դրա մեջ ցատկելու փոխարեն: 12.09.2013
  • Լավ, շնորհակալություն արագ և տեղեկատվական պատասխանի համար: Ես կքննեմ այն ​​հնարավորինս շուտ: 12.09.2013
  • Օգտագործեք ֆունկցիոնալ մակրոներ, իսկապես 12.09.2013

Պատասխանները:


1

Ենթադրելով, որ դուք մրցավազքի վիճակ չունեք, կարող եք փորձել միաձուլել օղակները: Միաձուլումը թույլ կտա ավելի մեծ կտորներ զուգահեռացնել, ինչը կօգնի նվազեցնել կեղծ համօգտագործման ազդեցությունը և, հավանաբար, ավելի լավ բաշխել բեռը:

Նման եռակի օղակի համար

for(int i2=0; i2<x; i2++) {
    for(int j2=0; j2<y; j2++) {
        for(int k2=0; k2<z; k2++) {
            //
        }
    }
}

դուք կարող եք միաձուլել այն այսպես

#pragma omp parallel for
for(int n=0; n<(x*y*z); n++) {
    int i2 = n/(y*z);
    int j2 = (n%(y*z))/z;
    int k2 = (n%(y*z))%z;
    //
}

Ձեր դեպքում դուք կարող եք դա անել այսպես

int i, j, k, n;
int x = newNx%2 ? newNx/2+1 : newNx/2;
int y = newNy;
int z = newNz;

#pragma omp parallel for private(i, j, k)
for(n=0; n<(x*y*z); n++) {
    i = 2*(n/(y*z)) + 1;
    j = (n%(y*z))/z + 1;
    k = (n%(y*z))%z + 1;
    // rest of code
}

Եթե ​​սա հաջողությամբ արագացնի ձեր կոդը, ապա դուք կարող եք լավ զգալ, որ ձեր կոդը ավելի արագ եք դարձրել և միևնույն ժամանակ այն էլ ավելի խճճել:

12.09.2013
  • +1 միայն այն պատճառով, որ դուք նույնիսկ փորձել եք կարդալ այդ կոդը: Միաձուլումը չի՞ իրականացվի նաև collapse հրահանգներով: 24.10.2013
  • Այո, բայց դա պահանջում է OpenMP-ի տարբերակ, որը չի աջակցվում MSVC-ի կողմից, և ես սիրում եմ ունենալ կոդ, որն աշխատում է բազմաթիվ կոմպիլյատորների հետ, այնպես որ ես ինքս եմ միաձուլումը կատարում: 24.10.2013
  • Առաջարկ (պահանջում է math.h): int x = ceil(newNx/2); 12.04.2017
  • Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..