Neden elementwise eklemeler ayr─▒ d├Âng├╝lerde birle┼čik d├Âng├╝de oldu─čundan ├žok daha h─▒zl─▒?


Al─▒nan cevaba git


Varsayal─▒m a1 , b1 , c1 ve d1 y─▒─č─▒n bellek ve benim say─▒sal koda noktas─▒ a┼ča─č─▒daki temel halka vard─▒r.

 const int n = 100000;

for (int j = 0; j < n; j++) {
    a1[j] += b1[j];
    c1[j] += d1[j];
}
 

Bu d├Âng├╝ ba┼čka bir d─▒┼č for d├Âng├╝ ├╝zerinden 10.000 kez y├╝r├╝t├╝l├╝r . H─▒zland─▒rmak i├žin kodu de─či┼čtirdim:

 for (int j = 0; j < n; j++) {
    a1[j] += b1[j];
}

for (int j = 0; j < n; j++) {
    c1[j] += d1[j];
}
 

Intel Core 2 Duo'da (x64) 32 bit i├žin tam optimizasyon ve SSE2 ├Âzellikli MS Visual C ++ 10.0'da derlenen ilk ├Ârnek 5.5 saniye, ├žift d├Âng├╝ ├Ârne─či ise sadece 1.9 saniye s├╝r├╝yor. Sorum ┼ču: (L├╝tfen alttaki cevapland─▒r─▒lm─▒┼č soruma bak─▒n)http://en.wikipedia.org/wiki/SSE2http://en.wikipedia.org/wiki/Intel_Core_2

Not: Bu yard─▒mc─▒ olur e─čer emin de─čilim:

─░lk d├Âng├╝ i├žin demontaj temelde ┼čuna benzer (bu blok tam programda yakla┼č─▒k be┼č kez tekrarlan─▒r):

 movsd       xmm0,mmword ptr [edx+18h]
addsd       xmm0,mmword ptr [ecx+20h]
movsd       mmword ptr [ecx+20h],xmm0
movsd       xmm0,mmword ptr [esi+10h]
addsd       xmm0,mmword ptr [eax+30h]
movsd       mmword ptr [eax+30h],xmm0
movsd       xmm0,mmword ptr [edx+20h]
addsd       xmm0,mmword ptr [ecx+28h]
movsd       mmword ptr [ecx+28h],xmm0
movsd       xmm0,mmword ptr [esi+18h]
addsd       xmm0,mmword ptr [eax+38h]
 

├çift d├Âng├╝ ├Ârne─činin her d├Âng├╝s├╝ bu kodu ├╝retir (a┼ča─č─▒daki blok yakla┼č─▒k ├╝├ž kez tekrarlan─▒r):

 addsd       xmm0,mmword ptr [eax+28h]
movsd       mmword ptr [eax+28h],xmm0
movsd       xmm0,mmword ptr [ecx+20h]
addsd       xmm0,mmword ptr [eax+30h]
movsd       mmword ptr [eax+30h],xmm0
movsd       xmm0,mmword ptr [ecx+28h]
addsd       xmm0,mmword ptr [eax+38h]
movsd       mmword ptr [eax+38h],xmm0
movsd       xmm0,mmword ptr [ecx+30h]
addsd       xmm0,mmword ptr [eax+40h]
movsd       mmword ptr [eax+40h],xmm0
 

Davran─▒┼člar─▒n b├╝y├╝k ├Âl├ž├╝de dizilerin (n) ve CPU ├Ânbelleklerinin b├╝y├╝kl├╝─č├╝ne ba─čl─▒ olmas─▒ nedeniyle, sorunun alakas─▒z oldu─ču ortaya ├ž─▒kt─▒. E─čer daha fazla ilgi varsa, soruyu yeniden ifade ediyorum:

A┼ča─č─▒daki grafikteki be┼č b├Âlge taraf─▒ndan g├Âsterildi─či gibi farkl─▒ ├Ânbellek davran─▒┼člar─▒na yol a├žan detaylar hakk─▒nda sa─člam bir i├žg├Âr├╝ sa─člayabilir misiniz?

Bu CPU'lar i├žin benzer bir grafik sunarak CPU / ├Ânbellek mimarileri aras─▒ndaki farklar─▒ ortaya koymak ilgin├ž olabilir.

PPS: ─░┼čte tam kod. Makroyu tan─▒mlayarak devre d─▒┼č─▒ b─▒rak─▒labilen daha y├╝ksek ├ž├Âz├╝n├╝rl├╝k zamanlamas─▒ i├žin TBB kullan─▒r : Tick_Count TBB_TIMING

 #include <iostream>
#include <iomanip>
#include <cmath>
#include <string>

//#define TBB_TIMING

#ifdef TBB_TIMING   
#include <tbb/tick_count.h>
using tbb::tick_count;
#else
#include <time.h>
#endif

using namespace std;

//#define preallocate_memory new_cont

enum { new_cont, new_sep };

double *a1, *b1, *c1, *d1;


void allo(int cont, int n)
{
    switch(cont) {
      case new_cont:
        a1 = new double[n*4];
        b1 = a1 + n;
        c1 = b1 + n;
        d1 = c1 + n;
        break;
      case new_sep:
        a1 = new double[n];
        b1 = new double[n];
        c1 = new double[n];
        d1 = new double[n];
        break;
    }

    for (int i = 0; i < n; i++) {
        a1[i] = 1.0;
        d1[i] = 1.0;
        c1[i] = 1.0;
        b1[i] = 1.0;
    }
}

void ff(int cont)
{
    switch(cont){
      case new_sep:
        delete[] b1;
        delete[] c1;
        delete[] d1;
      case new_cont:
        delete[] a1;
    }
}

double plain(int n, int m, int cont, int loops)
{
#ifndef preallocate_memory
    allo(cont,n);
#endif

#ifdef TBB_TIMING   
    tick_count t0 = tick_count::now();
#else
    clock_t start = clock();
#endif

    if (loops == 1) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++){
                a1[j] += b1[j];
                c1[j] += d1[j];
            }
        }
    } else {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                a1[j] += b1[j];
            }
            for (int j = 0; j < n; j++) {
                c1[j] += d1[j];
            }
        }
    }
    double ret;

#ifdef TBB_TIMING   
    tick_count t1 = tick_count::now();
    ret = 2.0*double(n)*double(m)/(t1-t0).seconds();
#else
    clock_t end = clock();
    ret = 2.0*double(n)*double(m)/(double)(end - start) *double(CLOCKS_PER_SEC);
#endif

#ifndef preallocate_memory
    ff(cont);
#endif

    return ret;
}


void main()
{   
    freopen("C:\\test.csv", "w", stdout);

    char *s = " ";

    string na[2] ={"new_cont", "new_sep"};

    cout << "n";

    for (int j = 0; j < 2; j++)
        for (int i = 1; i <= 2; i++)
#ifdef preallocate_memory
            cout << s << i << "_loops_" << na[preallocate_memory];
#else
            cout << s << i << "_loops_" << na[j];
#endif

    cout << endl;

    long long nmax = 1000000;

#ifdef preallocate_memory
    allo(preallocate_memory, nmax);
#endif

    for (long long n = 1L; n < nmax; n = max(n+1, long long(n*1.2)))
    {
        const long long m = 10000000/n;
        cout << n;

        for (int j = 0; j < 2; j++)
            for (int i = 1; i <= 2; i++)
                cout << s << plain(n, m, j, i);
        cout << endl;
    }
}
 

(Farkl─▒ de─čerler i├žin FLOP / sn g├Âsterir n .)


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin


2165









Cevap say─▒s─▒n─▒ say: 10






Bunun daha da analiz edilmesi ├╝zerine, bunun (en az─▒ndan k─▒smen) d├Ârt g├Âstericinin veri uyumundan kaynakland─▒─č─▒na inan─▒yorum. Bu, baz─▒ ├Ânbellek bankas─▒ / yol ├žak─▒┼čmalar─▒na neden olur.

Dizilerinizi nas─▒l tahsis etti─činizi do─čru bir ┼čekilde tahmin ettiyseniz , b├╝y├╝k olas─▒l─▒kla sayfa sat─▒r─▒na hizalan─▒r .

Bu, her d├Âng├╝deki t├╝m eri┼čiminizin ayn─▒ ├Ânbellek yoluna d├╝┼čece─či anlam─▒na gelir. Ancak, Intel i┼člemcileri bir s├╝redir 8 y├Ânl├╝ L1 ├Ânbellek ili┼čkilendirmesine sahipti. Ancak ger├žekte, performans tamamen tekd├╝ze de─čildir. 4 yoldan eri┼čmek 2 yoldan daha yava┼č.

EDIT: Asl─▒nda, t├╝m dizileri ayr─▒ ayr─▒ tahsis ediyormu┼čsunuz gibi g├Âr├╝n├╝yor. Genellikle bu t├╝r b├╝y├╝k tahsisatlar talep edildi─činde, tahsisat├ž─▒ i┼čletim sisteminden yeni sayfalar talep edecektir. Bu nedenle, b├╝y├╝k tahsislerin ayn─▒ s─▒n─▒rdan sayfa s─▒n─▒r─▒ndan ├ž─▒kmas─▒ ihtimali y├╝ksek.

─░┼čte test kodu:

 int main(){
    const int n = 100000;

#ifdef ALLOCATE_SEPERATE
    double *a1 = (double*)malloc(n * sizeof(double));
    double *b1 = (double*)malloc(n * sizeof(double));
    double *c1 = (double*)malloc(n * sizeof(double));
    double *d1 = (double*)malloc(n * sizeof(double));
#else
    double *a1 = (double*)malloc(n * sizeof(double) * 4);
    double *b1 = a1 + n;
    double *c1 = b1 + n;
    double *d1 = c1 + n;
#endif

    //  Zero the data to prevent any chance of denormals.
    memset(a1,0,n * sizeof(double));
    memset(b1,0,n * sizeof(double));
    memset(c1,0,n * sizeof(double));
    memset(d1,0,n * sizeof(double));

    //  Print the addresses
    cout << a1 << endl;
    cout << b1 << endl;
    cout << c1 << endl;
    cout << d1 << endl;

    clock_t start = clock();

    int c = 0;
    while (c++ < 10000){

#if ONE_LOOP
        for(int j=0;j<n;j++){
            a1[j] += b1[j];
            c1[j] += d1[j];
        }
#else
        for(int j=0;j<n;j++){
            a1[j] += b1[j];
        }
        for(int j=0;j<n;j++){
            c1[j] += d1[j];
        }
#endif

    }

    clock_t end = clock();
    cout << "seconds = " << (double)(end - start) / CLOCKS_PER_SEC << endl;

    system("pause");
    return 0;
}
 

K─▒yaslama Sonu├žlar─▒:

EDIT: Ger├žek Core 2 mimarisi makinesindeki sonu├žlar:

2 x Intel Xeon X5482 Harpertown 3.2 GHz'te:

 #define ALLOCATE_SEPERATE
#define ONE_LOOP
00600020
006D0020
007A0020
00870020
seconds = 6.206

#define ALLOCATE_SEPERATE
//#define ONE_LOOP
005E0020
006B0020
00780020
00850020
seconds = 2.116

//#define ALLOCATE_SEPERATE
#define ONE_LOOP
00570020
00633520
006F6A20
007B9F20
seconds = 1.894

//#define ALLOCATE_SEPERATE
//#define ONE_LOOP
008C0020
00983520
00A46A20
00B09F20
seconds = 1.993
 

G├Âzlemler:

  • Bir d├Âng├╝ ile 6.206 saniye ve iki d├Âng├╝ ile 2.116 saniye . Bu OP'nin sonu├žlar─▒n─▒ tam olarak tekrarlar.

  • ─░lk iki testte diziler ayr─▒ ayr─▒ tahsis edilmi┼čtir. Hepsinin sayfaya g├Âre ayn─▒ hizada oldu─čunu fark edeceksiniz.

  • ─░kinci iki testte, diziler bu hizalamay─▒ bozmak i├žin bir araya getirilir. Burada iki devrenin daha h─▒zl─▒ oldu─čunu fark edeceksiniz. Ayr─▒ca, ikinci (├žift) d├Âng├╝ ┼čimdi normalde bekledi─činiz gibi yava┼čt─▒r.

@Stephen Cannon yorumlarda da belirtildi─či gibi, bu hizalaman─▒n y├╝kleme / saklama ├╝nitelerinde veya ├Ânbellekte yanl─▒┼č takma olmas─▒na neden olma olas─▒l─▒─č─▒ ├žok y├╝ksektir . Bunun i├žin Googled ve Intel asl─▒nda k─▒smi adres takma tezgahlar─▒ i├žin bir donan─▒m sayac─▒ oldu─čunu bulundu :

http://software.intel.com/sites/products/documentation/doclib/stdxe/2013/~amplifierxe/pmw_dp/events/partial_address_alias.html


5 B├Âlgeler - A├ž─▒klamalar

B├Âlge 1:

Bu kolay. Veri k├╝mesi o kadar k├╝├ž├╝k ki performans, genel d├Âng├╝ ve dallanma gibi tepeg├Âz taraf─▒ndan y├Ânetiliyor.

B├Âlge 2:

Burada, veri boyutlar─▒ artt─▒k├ža, nispi ek y├╝k miktar─▒ d├╝┼čer ve performans ÔÇťdoyurulurÔÇŁ. Burada iki d├Âng├╝ daha yava┼čt─▒r ├ž├╝nk├╝ iki kat daha fazla halka ve tepeye dallanma sa─člar.

Burada tam olarak ne oldu─čundan emin de─čilim ... Agner Fog, ├Ânbellek bankas─▒ ├žat─▒┼čmalar─▒ndan bahsetti─činden, uyum hala etkili olabilir . (Bu ba─člant─▒ Sandy K├Âpr├╝s├╝ ile ilgilidir, ancak fikir hala ├çekirdek 2'ye uygulanabilir olmal─▒d─▒r.)

B├Âlge 3:

Bu noktada, veriler art─▒k L1 ├Ânbelle─čine s─▒─čm─▒yor. B├Âylece performans L1 <-> L2 ├Ânbellek bant geni┼čli─či ile s─▒n─▒rland─▒r─▒lm─▒┼čt─▒r.

B├Âlge 4:

Tek d├Âng├╝deki performans d├╝┼č├╝┼č├╝ g├Âzlemledi─čimiz ┼čeydir. Ve belirtildi─či gibi, bu (b├╝y├╝k olas─▒l─▒kla) i┼člemci y├╝kleme / depolama ├╝nitelerinde yanl─▒┼č takma tezgahlar─▒na neden olan uyumdan kaynaklanmaktad─▒r.

Ancak, yanl─▒┼č takma i┼člemlerin ger├žekle┼čmesi i├žin, veri k├╝meleri aras─▒nda yeterince b├╝y├╝k bir ad─▒m olmas─▒ gerekir. Bu y├╝zden bunu 3. b├Âlgede g├Ârm├╝yorsunuz.

B├Âlge 5:

Bu noktada, hi├žbir ┼čey ├Ânbelle─če s─▒─čmaz. Yani haf─▒za bant geni┼čli─čine ba─čl─▒s─▒n─▒z.



2 x Intel X5482 Harpertown @ 3.2 GHz


Intel Core i7 870 @ 2.8 GHz


Intel Core i7 2600K @ 4.4 GHz


1649







Tamam, do─čru cevap kesinlikle CPU ├Ânbelle─čiyle bir ┼čeyler yapmak zorunda. Ancak ├Ânbellek arg├╝man─▒n─▒ kullanmak ├Âzellikle veri olmadan olduk├ža zor olabilir.

├çok fazla tart─▒┼čmaya yol a├žan bir├žok cevap var, ancak ┼čunu kabul edelim: ├ľnbellek sorunlar─▒ ├žok karma┼č─▒k olabilir ve tek boyutlu olmayabilir. Verilerin boyutuna b├╝y├╝k ├Âl├ž├╝de ba─čl─▒lar, bu y├╝zden sorum haks─▒zl─▒kt─▒: ├ľnbellek grafi─činde ├žok ilgin├ž bir noktada oldu─ču ortaya ├ž─▒kt─▒.

@ Mysticial'─▒n cevab─▒, b├╝y├╝k olas─▒l─▒kla ger├žeklere dayanan tek ki┼či oldu─ču i├žin (ben dahil) bir ├žok insan─▒ ikna etti, ancak ger├že─čin yaln─▒zca bir "veri noktas─▒" idi.

Bu y├╝zden testini (s├╝rekli vs. ayr─▒ bir tahsisat kullanarak) ve @James'in Cevaplar─▒n─▒ bir araya getirdim.

A┼ča─č─▒daki grafikler, cevaplar─▒n ├žo─čunun ve ├Âzellikle soru ve cevaplara verilen yorumlar─▒n ├žo─čunun, kullan─▒lan senaryo ve parametrelere ba─čl─▒ olarak tamamen yanl─▒┼č veya do─čru olarak de─čerlendirilebilece─čini g├Âstermektedir.

─░lk sorumun n = 100.000 oldu─čunu unutmay─▒n . Bu nokta (kazayla) ├Âzel davran─▒┼č sergilemektedir:

  1. Bir ve iki loop'lu versiyon aras─▒ndaki en b├╝y├╝k farkl─▒l─▒─ča sahiptir (neredeyse ├╝├ž fakt├Âr)

  2. Tek d├Âng├╝n├╝n (yani s├╝rekli tahsisi olan) iki d├Âng├╝ s├╝r├╝m├╝n├╝ d├Âvd├╝─č├╝ tek nokta budur. (Bu, Mysticial'in cevab─▒n─▒ kesinlikle m├╝mk├╝n k─▒ld─▒.)

─░lklendirilen verileri kullanan sonu├ž:


Resim tan─▒m─▒n─▒ buraya girin

Ba┼člat─▒lmam─▒┼č verileri kullanan sonu├ž (bu, Mysticial'in test etti─či ┼čeydir):


Resim tan─▒m─▒n─▒ buraya girin

Bu da a├ž─▒klamas─▒ zor olan─▒: Ba┼člat─▒lm─▒┼č veriler, bir kez tahsis edilmi┼č ve farkl─▒ vekt├Âr boyutundaki her bir sonraki test durumu i├žin yeniden kullan─▒lm─▒┼č:


Resim tan─▒m─▒n─▒ buraya girin

├Âneri

Y─▒─č─▒n Ta┼čmas─▒ ile ilgili her d├╝┼č├╝k seviye performansla ilgili soru, t├╝m ├Ânbellekle ilgili veri boyutlar─▒ i├žin MFLOPS bilgisi sa─člamak i├žin gerekli olmal─▒d─▒r! Cevaplar─▒ d├╝┼č├╝nmek ve ├Âzellikle de bu bilgiler olmadan ba┼čkalar─▒yla tart─▒┼čmak herkesin zaman─▒n─▒ bo┼ča harcar.


215







─░kinci d├Âng├╝ ├žok daha az ├Ânbellek etkinli─či i├žerir, bu nedenle i┼člemcinin bellek taleplerini yerine getirmesi daha kolayd─▒r.


76







n Dizilerinizi yaln─▒zca bir seferde bellekte tutman─▒z─▒n m├╝mk├╝n olabilece─či bir makine ├╝zerinde ├žal─▒┼čt─▒─č─▒n─▒z─▒ , ancak disk ├Ânbellekleme yoluyla kullan─▒labilir toplam belle─čin hala d├Ârd├╝ tutmak i├žin yeterli oldu─čunu hayal edin.

Basit bir LIFO ├Ânbelle─če alma politikas─▒ varsayarak, bu kod:

 for(int j=0;j<n;j++){
    a[j] += b[j];
}
for(int j=0;j<n;j++){
    c[j] += d[j];
}
 

├Ânce RAM'e y├╝klenecek a ve b y├╝klenecek ve daha sonra tamamen RAM'de ├žal─▒┼čacakt─▒ . ─░kinci d├Âng├╝ ba┼člad─▒─č─▒nda c ve d daha sonra diskten RAM'e y├╝klenir ve ├žal─▒┼čt─▒r─▒l─▒r.

di─čer d├Âng├╝

 for(int j=0;j<n;j++){
    a[j] += b[j];
    c[j] += d[j];
}
 

iki dizi ve her iki d├Âng├╝ etraf─▒nda sayfa di─čer iki sayfa ├ž─▒karacak . Bu a├ž─▒k├ža daha yava┼č olacakt─▒r.

Muhtemelen testlerinizde disk ├Ânbelle─čini g├Ârm├╝yorsunuz, ancak muhtemelen ba┼čka bir ├Ânbelle─če alma bi├žiminin yan etkilerini g├Âr├╝yorsunuz.


Burada biraz kar─▒┼č─▒kl─▒k / yanl─▒┼č anla┼č─▒lma var gibi g├Âr├╝n├╝yor, bu y├╝zden bir ├Ârnek kullanarak biraz daha fazla ├žal─▒┼čaca─č─▒m.

S├Âyleyin n = 2 ve baytlarla ├žal─▒┼č─▒yoruz. Benim senaryomda bu nedenle sadece 4 byte RAM var ve haf─▒zam─▒z─▒n geri kalan─▒ ├Ânemli ├Âl├ž├╝de yava┼člar (100 kat daha uzun eri┼čim).

Bayt ├Ânbellekte de─čilse, olduk├ža aptal bir ├Ânbellek politikas─▒ varsayarsak , oraya koyun ve biz de bu s─▒rada a┼ča─č─▒daki gibi bir senaryo alacaks─▒n─▒z:

  • ─░le

     for(int j=0;j<n;j++){
     a[j] += b[j];
    }
    for(int j=0;j<n;j++){
     c[j] += d[j];
    }
     
  • ├Ânbellek a[0] ve a[1] ard─▒ndan b[0] ve b[1] ve a[0] = a[0] + b[0] ├Ânbelle─če ayarla - ├Ânbellekte art─▒k d├Ârt bayt var a[0], a[1] ve b[0], b[1] . Maliyet = 100 + 100.

  • a[1] = a[1] + b[1] ├Ânbellekte ayarlay─▒n . Maliyet = 1 + 1.
  • ─░├žin tekrarlay─▒n c ve d .
  • Toplam maliyet = (100 + 100 + 1 + 1) * 2 = 404

  • ─░le

     for(int j=0;j<n;j++){
     a[j] += b[j];
     c[j] += d[j];
    }
     
  • ├Ânbellek a[0] ve a[1] ard─▒ndan b[0] ve b[1] ve a[0] = a[0] + b[0] ├Ânbelle─če ayarla - ├Ânbellekte art─▒k d├Ârt bayt var a[0], a[1] ve b[0], b[1] . Maliyet = 100 + 100.

  • a[0], a[1], b[0], b[1] ├Ânbellekten ve ├Ânbellekten ├ž─▒kar─▒n c[0] ve c[1] ard─▒ndan d[0] ve ├Ânbellekte d[1] ayarlay─▒n c[0] = c[0] + d[0] . Maliyet = 100 + 100.
  • Nereye gitti─čimi g├Ârmeye ba┼člad─▒─č─▒ndan ┼č├╝pheleniyorum.
  • Toplam maliyet = (100 + 100 + 100 + 100) * 2 = 800

Bu klasik bir ├Ânbellek thrash senaryosu.


46







Farkl─▒ bir koddan de─čil, ├Ânbelle─če almaktan dolay─▒ de─čil: RAM, CPU kay─▒tlar─▒ndan daha yava┼čt─▒r ve RAM bir de─či┼čken her de─či┼čti─činde yazmaktan ka├ž─▒nmak i├žin CPU i├žinde bir ├Ânbellek haf─▒zas─▒d─▒r. Ancak ├Ânbellek RAM oldu─ču kadar b├╝y├╝k de─čildir, dolay─▒s─▒yla sadece bunun bir k─▒sm─▒n─▒ e┼čler.

─░lk kod uzaktaki bellek adreslerini her d├Âng├╝de de─či┼čtirerek de─či┼čtirir, bu nedenle s├╝rekli olarak ├Ânbelle─či ge├žersiz k─▒lmak gerekir.

─░kinci kod de─či┼čmez: sadece biti┼čik adreslere iki kez akar. Bu, t├╝m i┼čin ├Ânbellekte tamamlanmas─▒n─▒ sa─člar, ancak ikinci d├Âng├╝ ba┼člad─▒ktan sonra ge├žersiz k─▒lar.


31







Burada tart─▒┼č─▒lan sonu├žlar─▒ ├žo─čaltam─▒yorum.

Test kodunun zay─▒f olup olmad─▒─č─▒n─▒ veya ne oldu─čunu bilmiyorum, ancak iki y├Ântem a┼ča─č─▒daki kodu kullanarak makinemde birbirlerinin% 10'unda ve bir d├Âng├╝ genellikle ikiden biraz daha h─▒zl─▒. bekliyoruz.

Dizi boyutlar─▒, sekiz d├Âng├╝ kullanarak 2 ^ 16 ile 2 ^ 24 aras─▒nda de─či┼čmi┼čtir. Kaynak dizileri ba┼člat─▒rken dikkatli olmu┼čtum, bu y├╝zden += atama FPUÔÇÖya iki kat─▒ olarak yorumlanan bellek ├ž├Âp├╝n├╝ eklemesini istemiyordu .

B├Âyle atama koyarak gibi ├že┼čitli d├╝zenleri, etraf─▒nda oynanan b[j] , d[j] i├žin InitToZero[j] d├Âng├╝ler i├žine ve ayr─▒ca kullanarak += b[j] = 1 ve += d[j] = 1 , ve ben olduk├ža tutarl─▒ sonu├žlar ald─▒k.

E─čer ba┼člat─▒l─▒yor, Tahmin edebilece─činiz gibi b ve d kullanma d├Âng├╝ i├žinde InitToZero[j] olduklar─▒ atamalar─▒ ├Ânce arka arkaya yapm─▒┼č gibi, kombine yakla┼č─▒m, bir avantaj sa─člad─▒ a ve c , ama yine de i├žinde% 10. Git fig├╝r├╝.

Donan─▒m, 3. nesil Core i7 @ 3.4 GHz ve 8 GB belle─če sahip Dell XPS 8500 . 2 ^ 16 ila 2 ^ 24 i├žin sekiz d├Âng├╝ kullanarak, toplam s├╝re s─▒ras─▒yla 44.987 ve 40.965 idi. Visual C ++ 2010, tamamen optimize edilmi┼č.http://en.wikipedia.org/wiki/Intel_Core%23Core_i7#Core_i7

Not: D├Âng├╝leri s─▒f─▒ra geri saymaya de─či┼čtirdim ve birle┼čik y├Ântem marjinal olarak daha h─▒zl─▒yd─▒. Ba┼č─▒m─▒ t─▒rmalamak. Yeni dizi boyutland─▒rmas─▒na ve d├Âng├╝ say─▒mlar─▒na dikkat edin.

 // MemBufferMystery.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <cmath>
#include <string>
#include <time.h>

#define  dbl    double
#define  MAX_ARRAY_SZ    262145    //16777216    // AKA (2^24)
#define  STEP_SZ           1024    //   65536    // AKA (2^16)

int _tmain(int argc, _TCHAR* argv[]) {
    long i, j, ArraySz = 0,  LoopKnt = 1024;
    time_t start, Cumulative_Combined = 0, Cumulative_Separate = 0;
    dbl *a = NULL, *b = NULL, *c = NULL, *d = NULL, *InitToOnes = NULL;

    a = (dbl *)calloc( MAX_ARRAY_SZ, sizeof(dbl));
    b = (dbl *)calloc( MAX_ARRAY_SZ, sizeof(dbl));
    c = (dbl *)calloc( MAX_ARRAY_SZ, sizeof(dbl));
    d = (dbl *)calloc( MAX_ARRAY_SZ, sizeof(dbl));
    InitToOnes = (dbl *)calloc( MAX_ARRAY_SZ, sizeof(dbl));
    // Initialize array to 1.0 second.
    for(j = 0; j< MAX_ARRAY_SZ; j++) {
        InitToOnes[j] = 1.0;
    }

    // Increase size of arrays and time
    for(ArraySz = STEP_SZ; ArraySz<MAX_ARRAY_SZ; ArraySz += STEP_SZ) {
        a = (dbl *)realloc(a, ArraySz * sizeof(dbl));
        b = (dbl *)realloc(b, ArraySz * sizeof(dbl));
        c = (dbl *)realloc(c, ArraySz * sizeof(dbl));
        d = (dbl *)realloc(d, ArraySz * sizeof(dbl));
        // Outside the timing loop, initialize
        // b and d arrays to 1.0 sec for consistent += performance.
        memcpy((void *)b, (void *)InitToOnes, ArraySz * sizeof(dbl));
        memcpy((void *)d, (void *)InitToOnes, ArraySz * sizeof(dbl));

        start = clock();
        for(i = LoopKnt; i; i--) {
            for(j = ArraySz; j; j--) {
                a[j] += b[j];
                c[j] += d[j];
            }
        }
        Cumulative_Combined += (clock()-start);
        printf("\n %6i miliseconds for combined array sizes %i and %i loops",
                (int)(clock()-start), ArraySz, LoopKnt);
        start = clock();
        for(i = LoopKnt; i; i--) {
            for(j = ArraySz; j; j--) {
                a[j] += b[j];
            }
            for(j = ArraySz; j; j--) {
                c[j] += d[j];
            }
        }
        Cumulative_Separate += (clock()-start);
        printf("\n %6i miliseconds for separate array sizes %i and %i loops \n",
                (int)(clock()-start), ArraySz, LoopKnt);
    }
    printf("\n Cumulative combined array processing took %10.3f seconds",
            (dbl)(Cumulative_Combined/(dbl)CLOCKS_PER_SEC));
    printf("\n Cumulative seperate array processing took %10.3f seconds",
        (dbl)(Cumulative_Separate/(dbl)CLOCKS_PER_SEC));
    getchar();

    free(a); free(b); free(c); free(d); free(InitToOnes);
    return 0;
}
 

MFLOPS'un neden ilgili bir ├Âl├ž├╝m oldu─čuna karar verildi─činden emin de─čilim. Bence fikir haf─▒za eri┼čimine odaklanmakt─▒, ben de kayan nokta hesaplama zaman─▒n─▒ en aza indirmeye ├žal─▒┼čt─▒m. Ben b─▒rakt─▒m += ama neden oldu─čundan emin de─čilim.

Hesaplamas─▒ olmayan bir d├╝z atama, haf─▒za eri┼čim s├╝resinin daha temiz bir testi olur ve d├Âng├╝ say─▒s─▒ndan ba─č─▒ms─▒z olarak tek tip bir test olu┼čturur. Belki de sohbette bir ┼čeyleri ├Âzledim ama iki kez d├╝┼č├╝nmeye de─čer. Art─▒ ├Âdev d─▒┼č─▒nda kal─▒rsa, k├╝m├╝latif s├╝re her biri 31 saniyede neredeyse ayn─▒d─▒r.


19


2012-12-30





Bunun nedeni, CPU'nun ├žok fazla ├Ânbellek ├Âzeti i├žermemesidir (dizi verilerinin RAM yongalar─▒ndan gelmesini beklemek zorundad─▒r). Dizilerin boyutunu s├╝rekli olarak ayarlaman─▒z, i┼člemcinizin seviye 1 ├Ânbelle─či (L1) ve ard─▒ndan seviye 2 ├Ânbelle─či (L2) boyutlar─▒n─▒ a┼čman─▒z ve kodunuz i├žin harcanan zaman─▒ planlaman─▒z i├žin ilgin├ž olurdu . Dizilerin boyutlar─▒na kar┼č─▒ ├žal─▒┼čt─▒rmak i├žin. Grafik, bekledi─činiz gibi d├╝z bir ├žizgi olmamal─▒d─▒r.


16







─░lk d├Âng├╝, her de─či┼čkende yaz─▒ yazar. ─░kinci ve ├╝├ž├╝nc├╝ olanlar sadece k├╝├ž├╝k element b├╝y├╝kl├╝─č├╝ s─▒├žramalar─▒ yapar.

20 ha├ž iki paralel ├žizgi bir kalem ve 20 cm ayr─▒lm─▒┼č bir ka─č─▒tla yazmay─▒ deneyin. Birini bitirdikten sonra di─čerini bitirmeyi deneyin ve s─▒rayla her ├žizgiye bir ├žarp─▒ i┼čareti yazarak ba┼čka bir zaman deneyin.


13







Orijinal soru

Bir d├Âng├╝ neden iki d├Âng├╝den daha yava┼č?


Sonu├ž:

Durum 1 , verimsiz olan bir klasik enterpolasyon problemidir. Bunun, bir├žok makine mimarisinin ve geli┼čtiricisinin, paralel programlama yan─▒ s─▒ra ├žoklu i┼č par├žac─▒kl─▒ uygulamalar yapma kabiliyetine sahip ├žok ├žekirdekli sistemler kurup tasarlama nedeninin ├Ânde gelen nedenlerinden biri oldu─čunu d├╝┼č├╝n├╝yorum.

Donan─▒m, ─░┼čletim Sistemi ve Derleyici (ler) in RAM, ├ľnbellek, Sayfa Dosyalar─▒ vb. ─░le ├žal─▒┼čmay─▒ i├žeren y─▒─č─▒n tahsisleri yapmak i├žin nas─▒l birlikte ├žal─▒┼čt─▒klar─▒n─▒ i├žermeden bu t├╝r bir yakla┼č─▒ma bakmak; Bu algoritmalar─▒n temelini olu┼čturan matematik bize bu ikisinden hangisinin daha iyi bir ├ž├Âz├╝m oldu─čunu g├Âstermektedir. Bir yerde Biz bir benzetme kullanabilirsiniz Boss veya Summation bir temsil edecek For Loop i┼č├žiler aras─▒nda seyahat gerekti─čini A & B kolayca g├Ârebiliriz Durum 2 en az oldu─ču 1 / 2 h─▒zl─▒ sanki birden de─čil biraz K─▒l─▒f 1 mesafe nedeniyle bu fark─▒ seyahat etmek ve i┼č├žiler aras─▒nda ge├žen zamana ihtiya├ž vard─▒r. Bu matematik hem Bench Mark Times hem de Montaj Talimatlar─▒ndaki farklar─▒n miktar─▒ ile neredeyse hemen hemen ve m├╝kemmel bir ┼čekilde s─▒ralan─▒r.

┼×imdi t├╝m bunlar─▒n a┼ča─č─▒da nas─▒l ├žal─▒┼čt─▒─č─▒n─▒ a├ž─▒klamaya ba┼člayaca─č─▒m.


Sorunun De─čerlendirilmesi

OP'nin kodu:

 const int n=100000;

for(int j=0;j<n;j++){
    a1[j] += b1[j];
    c1[j] += d1[j];
}
 

Ve

 for(int j=0;j<n;j++){
    a1[j] += b1[j];
}
for(int j=0;j<n;j++){
    c1[j] += d1[j];
}
 

D├╝┼č├╝nme

OP'nin for d├Âng├╝lerinin 2 ├že┼čidi hakk─▒ndaki orijinal sorusunu ve ├Ânbelleklerin davran─▒┼č─▒na y├Ânelik de─či┼čtirilen sorusunu ve di─čer m├╝kemmel cevaplar─▒n ve faydal─▒ yorumlar─▒n bir├žo─čunu dikkate alarak; Bu durum ve sorun hakk─▒nda farkl─▒ bir yakla┼č─▒m benimseyerek burada farkl─▒ bir ┼čeyler denemek isterim.


Yakla┼č─▒m

─░ki d├Âng├╝y├╝ ve ├Ânbellek ve sayfa dosyalama hakk─▒ndaki t├╝m tart─▒┼čmalar─▒ g├Âz ├Ân├╝nde bulundurarak, buna farkl─▒ bir bak─▒┼č a├ž─▒s─▒yla bakmak i├žin ba┼čka bir yakla┼č─▒m almak istiyorum. ├ľnbellek ve sayfa dosyalar─▒n─▒ ve bellek ay─▒rma uygulamalar─▒n─▒ i├žermeyen, asl─▒nda bu yakla┼č─▒m as─▒l donan─▒m veya yaz─▒l─▒m─▒ bile ilgilendirmiyor.


Bak─▒┼č a├ž─▒s─▒

Bir s├╝re koda bakt─▒ktan sonra, sorunun ne oldu─ču ve ne ├╝retti─či olduk├ža belirgin hale geldi. Bunu algoritmik bir soruna ay─▒ral─▒m ve matematiksel notasyonlar─▒ kullanma perspektifinden bakal─▒m, sonra matematik problemlerine ve algoritmalara bir benzetme uygulayal─▒m.


Ne Biliyoruz?

Onun d├Âng├╝s├╝n├╝n 100.000 kez ├žal─▒┼čaca─č─▒n─▒ biliyoruz. Biz de biliyoruz a1 , b1 , c1 & d1 64-bit mimarisine g├Âstericisidir. 32 bitlik bir makinede C ++ 'da t├╝m i┼čaret├žiler 4 bayt, 64 bitlik bir makinede i┼čaret├žiler sabit uzunlukta oldu─čundan 8 bayt boyutundad─▒r. Her iki durumda da ayr─▒lacak 32 bayt─▒m─▒z oldu─čunu biliyoruz. Tek fark, her yinelemede 32 bayt veya 2 set 2-8 bayt tahsis etmemizdir; ikinci durumda ise her yinelemeye ba─č─▒ms─▒z d├Âng├╝ler i├žin 16 bayt ay─▒r─▒yoruz. Bu y├╝zden her iki d├Âng├╝ hala toplam tahsisattaki 32 bayta e┼čittir. Bu bilgilerle devam edelim ve genel matematik, algoritma ve analojisini g├Âsterelim. Her iki durumda da ayn─▒ i┼člem grubunun veya i┼člem grubunun ne kadar s├╝reyle ger├žekle┼čtirilece─čini biliyoruz. Her iki durumda da ayr─▒lmas─▒ gereken bellek miktar─▒n─▒ biliyoruz. Her iki durumda da tahsisatlar─▒n toplam i┼č y├╝k├╝n├╝n yakla┼č─▒k olarak ayn─▒ olaca─č─▒n─▒ s├Âyleyebiliriz.


Ne Bilmiyoruz?

Bir saya├ž koyup k─▒yaslama testi yapmazsak, her durum i├žin ne kadar s├╝rece─čini bilmiyoruz. Bununla birlikte, referans noktalar─▒ zaten as─▒l sorudan ve baz─▒ cevaplardan ve yorumlardan dahil edildi ve ikisi aras─▒nda anlaml─▒ bir fark g├Ârebiliyoruz. ile ba┼člar.


Ara┼čt─▒ral─▒m

Bunu zaten bir├žo─čunun zaten ├Âbek tahsisatlar─▒na, k─▒yaslama testleri, RAM, ├ľnbellek ve Sayfa Dosyalar─▒na bakarak yapm─▒┼č oldu─ču a├ž─▒k├ža g├Âr├╝l├╝yor. Belirli veri noktalar─▒na ve belirli yineleme indekslerine bakmak da dahil edildi ve bu belirli sorunla ilgili ├že┼čitli konu┼čmalar, bununla ilgili di─čer sorular─▒ sorgulamaya ba┼člayan bir├žok insan─▒ i├žeriyor. Peki, bu soruna matematiksel algoritmalar kullanarak ve buna benzetme yaparak nas─▒l bakmaya ba┼člar─▒z? Birka├ž iddiada bulunmaya ba┼čl─▒yoruz! Sonra algoritmam─▒z─▒ oradan in┼ča ediyoruz.


Bizim iddialar─▒m─▒z:

  • D├Âng├╝n├╝m├╝z├╝n ve yinelemelerinin, 1 ile ba┼člayan ve 100000'de biten ve 0 ile ba┼člamak yerine 100 ile biten bir ├ľzet olmas─▒na izin verece─čiz, ├ž├╝nk├╝ sadece ilgilendi─čimiz i├žin bellek adreslemenin 0 indeksleme ┼čemas─▒ i├žin endi┼čelenmenize gerek yok algoritman─▒n kendisi.
  • Her iki durumda da ├žal─▒┼čacak 4 fonksiyonumuz ve her bir fonksiyon ├ža─čr─▒s─▒nda 2 i┼člem yap─▒larak 2 fonksiyon ├ža─čr─▒m─▒z var. Biz fonksiyonlar─▒ ve i┼člev ├ža─čr─▒lar─▒ olmas─▒ i├žin bu kuracak Yani F1() , F2() , f(a) , f(b) , f(c) ve f(d) .

Algoritmalar:

1. Durum: - Sadece bir toplam ama iki ba─č─▒ms─▒z fonksiyon ├ža─čr─▒s─▒.

 Sum n=1 : [1,100000] = F1(), F2();
                       F1() = { f(a) = f(a) + f(b); }
                       F2() = { f(c) = f(c) + f(d);  }
 

2. Durum: - ─░ki toplam ama her birinin kendine ait fonksiyon ├ža─čr─▒s─▒ var.

 Sum1 n=1 : [1,100000] = F1();
                        F1() = { f(a) = f(a) + f(b); }

Sum2 n=1 : [1,100000] = F1();
                        F1() = { f(c) = f(c) + f(d); }
 

Fark ise F2() sadece var Sum burada hem Sum1 ve Sum2 yaln─▒zca i├žerir F1() . Bu, ayn─▒ zamanda, ikinci algoritmadan kaynaklanan bir optimizasyon oldu─čuna karar verdi─čimizde de ortaya ├ž─▒kacakt─▒r.

─░lk vaka yoluyla yineleme Sum aramalar─▒ f(a) onun kendine katacak f(b) o zaman ├ža─č─▒r─▒r f(c) o ayn─▒ ┼čeyi ancak katacak f(d) her biri i├žin kendisine 100000 iterations . ─░kinci durumda biz Sum1 ve Sum2 Ve her ikisi de ├╝st ├╝ste iki kez ├ža─čr─▒lanla ayn─▒ i┼čleve sahiplermi┼č gibi davran─▒rlar. Bu durumda biz tedavi edebilir Sum1 ve Sum2 sadece d├╝z eski olarak Sum nerede Sum bu durumda b├Âyle g├Âr├╝n├╝yor: Sum n=1 : [1,100000] { f(a) = f(a) + f(b); } ┼čimdi ve biz sadece ayn─▒ i┼člevi olarak d├╝┼č├╝nebilirsiniz bir optimizasyon gibi bu g├Âr├╝n├╝yor.


Analojiyle ├ľzet

─░kinci durumda g├Ârd├╝klerimizle neredeyse her ikisi de d├Âng├╝ i├žin ayn─▒ imzay─▒ ta┼č─▒d─▒─č─▒ i├žin optimizasyon varm─▒┼č gibi g├Âr├╝n├╝yor, ancak as─▒l mesele bu de─čil. Sorun taraf─▒ndan yap─▒l─▒yor i┼či de─čil f(a) , f(b) , f(c) ve f(d) her iki durumda ve bu ikisi aras─▒ndaki kar┼č─▒la┼čt─▒r─▒ld─▒─č─▒nda o Toplama size zaman y├╝r├╝tme fark─▒n─▒ verir her iki durumda da seyahat zorunda oldu─ču mesafeye fark─▒d─▒r.

D├╝┼č├╝n├╝n For Loops olarak Summations bir varl─▒k olarak yinelemeleri yapt─▒─č─▒ Boss iki ki┼čiye emir verdi─čini A & B ve i┼člerini ete oldu─čunu C ve D s─▒ras─▒yla ve onlardan baz─▒ paket almak ve bunu iade etmek. Buradaki analojide, for d├Âng├╝s├╝ veya toplam─▒ yinelemeleri ve ko┼čul kontrolleri kendilerini asl─▒nda temsil etmemektedir Boss . Ne asl─▒nda temsil Boss burada do─črudan ger├žek matematiksel algoritmalar dan de─čil, ger├žek kavram─▒ndan Scope ve Code Block rutin veya alt rutin, y├Ântem, fonksiyon, ├ževiri birimi vs. i├žinde 2 algoritma 2 sahip oldu─ču ilk algoritma 1 kapsam─▒ vard─▒r ard─▒┼č─▒k kapsamlar.

Her ├ža─čr─▒daki ilk davada fi┼če Boss gidip A sipari┼č verir ve paketi A almaya gider, B's sonra da Boss gidip C ayn─▒ i┼člemi yapmak ve sipari┼čleri D her iterasyondan al─▒r.

─░kinci durumda, t├╝m paketler al─▒nana kadar Boss do─črudan A gidip B's paketi almaya ├žal─▒┼č─▒r . Sonra t├╝m paketleri almak i├žin ayn─▒ ┼čeyi yapmak i├žin Boss ├žal─▒┼č─▒r . C D's

8 baytl─▒k bir i┼čaret├ži ile ├žal─▒┼čt─▒─č─▒m─▒z ve Heap tahsisi ile ilgilendi─čimiz i├žin bu problemi burada d├╝┼č├╝nelim. Bize diyelim Boss 100 fit aras─▒ndad─▒r A ve bu A 500 feet C . ─░cra emri nedeniyle Boss ba┼člang─▒├žta ne kadar uzakta oldu─ču konusunda endi┼čelenmemize gerek yok C . Her iki durumda da Boss ba┼člang─▒├žta A ilk ├Ânce o zamana kadar seyahat eder B . Bu benzetme, bu mesafenin kesin oldu─čunu s├Âylemek de─čildir; algoritmalar─▒n ├žal─▒┼čmas─▒n─▒ g├Âstermek i├žin sadece bir kullan─▒m testi senaryosudur. ├ľbek tahsisleri yaparken ve ├Ânbellek ve sayfa dosyalar─▒yla ├žal─▒┼č─▒rken, ├žo─ču zaman adres konumlar─▒ aras─▒ndaki bu farklar farkl─▒l─▒k g├Âstermeyebilir veya veri t├╝rlerinin niteli─čine ve dizi boyutlar─▒na ba─čl─▒ olarak ├žok b├╝y├╝k farkl─▒l─▒klar g├Âsterebilir.


Test Durumlar─▒:

─░lk Durum: ─░lk tekrarlamada, Boss sipari┼č fi┼čini vermek i├žin ilk ├Ânce 100 feet gitmek zorunda kal─▒r A ve A gider ve i┼čini yapar, ancak daha sonrasipari┼č fi┼čini vermek Boss i├žin 500 feet seyahat etmek C zorunda kal─▒r. Sonra bir sonraki yineleme ve di─čer t├╝m yinelemelerden sonra Boss ikisi aras─▒nda 500 metre ileri geri gitmek zorunda kal─▒r.

─░kinci Durum: The Boss ─░lk tekrarlamada 100 feet seyahat etmek zorundad─▒r A , ancak ondan sonra zaten oradad─▒r ve sadece A t├╝m fi┼čler dolana kadar geri d├Ânmeki├žin bekler. Sonra Boss ilk tekrar─▒nda 500 ad─▒m seyahat etmek zorunda C ├ž├╝nk├╝ C 500 feet A bu yana Boss( Summation, For Loop ) do─čru ├žal─▒┼čt─▒ktan sonra ├ža─čr─▒lan A ve o yapt─▒─č─▒ gibi o zaman sadece bekler A t├╝m kadar C's sipari┼č fi┼čleri yap─▒l─▒r.


Gidilen Mesafelerdeki Fark

 const n = 100000
distTraveledOfFirst = (100 + 500) + ((n-1)*(500 + 500); 
// Simplify
distTraveledOfFirst = 600 + (99999*100);
distTraveledOfFirst = 600 + 9999900;
distTraveledOfFirst =  10000500;
// Distance Traveled On First Algorithm = 10,000,500ft

distTraveledOfSecond = 100 + 500 = 600;
// Distance Traveled On Second Algorithm = 600ft;    
 

Keyfi De─čerlerin Kar┼č─▒la┼čt─▒r─▒lmas─▒

600'├╝n 10 milyondan ├žok daha az oldu─čunu kolayca g├Ârebiliriz. ┼×imdi bu kesin de─čil, ├ž├╝nk├╝ her yinelemedeki her ├ža─čr─▒n─▒n hangi RAM adresi veya hangi ├ľnbellek veya Sayfa Dosyas─▒ndan aralar─▒ndaki mesafe aras─▒ndaki ger├žek fark─▒ bilmiyoruz, fakat bu sadece di─čer bir├žok de─či┼čkenden kaynaklan─▒yor. Durumun de─čerlendirilmesi ve en k├Ât├╝ durum senaryosundan buna bakmaya ├žal─▒┼č─▒lmas─▒ durumu.

Dolay─▒s─▒yla, bu say─▒larla Algoritma Bir'in Algoritma ─░ki'den% 99 daha yava┼č olmas─▒ gerekti─či gibi g├Âr├╝n├╝yordu; Ancak bu sadece The Boss's bir par├ža veya algoritmalar─▒n sorumluluk ve ger├žek i┼č├žiler dikkate almaz A , B , C , ve D ve ne her ve Loop her tekrar─▒nda yapmak zorunday─▒z. Dolay─▒s─▒yla patronlar─▒n i┼či, yap─▒lan toplam i┼čin sadece% 15 - 40'─▒n─▒ olu┼čturuyor. Bu nedenle, i┼č├žiler arac─▒l─▒─č─▒yla yap─▒lan i┼čin b├╝y├╝k k─▒sm─▒, h─▒z fark─▒ farkl─▒l─▒klar─▒n─▒n% 50-70'e kadar tutulmas─▒ y├Ân├╝nde daha b├╝y├╝k bir etkiye sahiptir.


G├Âzlem: - ─░ki algoritma aras─▒ndaki farklar

Bu durumda, yap─▒lan i┼č s├╝recinin yap─▒s─▒d─▒r ve Dava 2'nin , benzer bir i┼člev bildirgesine sahip olan k─▒smi optimizasyondan ve sadece isimle farkl─▒ olan de─či┼čkenlerin oldu─ču tan─▒mdan daha verimli oldu─čunu g├Âstermeye devam etmektedir. . Ayr─▒ca, Durum 1'de katedilen toplam mesafenin Durum 2'de oldu─čundan ├žok daha uzakta oldu─čunu g├Âr├╝yoruz ve bu mesafenin iki algoritma aras─▒nda Zaman Fakt├Âr├╝ olarak gitti─čini d├╝┼č├╝nebiliriz . Durum 1'de Durum 2'den daha ├Ânemli i┼čler vard─▒r . Bu ayn─▒ zamanda ASM her iki vaka aras─▒nda g├Âsterilen kan─▒tlarda da g├Âr├╝lm├╝┼čt├╝r . Ne zaten bu gibi durumlarda ilgili ad─▒ ge├žen olsa bile, o da o ger├že─či dikkate almaz Durumunda 1 patron hem beklemek zorunda kalacak A ve C o d├Ânebilirsiniz ├Ânce geri almak i├žin A doesn da bunu bir sonraki denemede tekrar ├çok uzun zaman al─▒yorsa A veya B ├žok uzun s├╝r├╝yorsa, hem Boss di─čer i┼č├žilerin hem de bo┼čta beklediklerini hesaba katmay─▒n. In Durumunda 2 tek varl─▒k bo┼čta Boss i┼č├ži d├Ânene kadar. Yani bunun bile algoritma ├╝zerinde etkisi var.



OPs De─či┼čtirilmi┼č Soru (lar)

D├ťZENLEME: Davran─▒┼č ciddi ├Âl├ž├╝de dizilerin (n) ve CPU ├Ânbelle─činin boyutuna ba─čl─▒ oldu─čundan, sorunun alakas─▒z oldu─ču ortaya ├ž─▒kt─▒. E─čer daha fazla ilgi varsa, soruyu yeniden ifade ediyorum:

A┼ča─č─▒daki grafikteki be┼č b├Âlge taraf─▒ndan g├Âsterildi─či gibi farkl─▒ ├Ânbellek davran─▒┼člar─▒na yol a├žan detaylar hakk─▒nda sa─člam bir i├žg├Âr├╝ sa─člayabilir misiniz?

Bu CPU'lar i├žin benzer bir grafik sunarak CPU / ├Ânbellek mimarileri aras─▒ndaki farklar─▒ ortaya koymak ilgin├ž olabilir.


Bu Sorularla ─░lgili

┼×├╝phesiz g├Âsterdi─čim gibi, Donan─▒m ve Yaz─▒l─▒m devreye girmeden ├Ânce altta yatan bir sorun var. ┼×imdi bellek y├Ânetimi ve ├Ânbellekleme ile ilgili olarak hepsi bir arada bir sistemde birlikte ├žal─▒┼čan sayfa dosyalar─▒ vb. ─░le birlikte: The Architecture {Donan─▒m, Firmware, baz─▒ G├Âm├╝l├╝ S├╝r├╝c├╝ler, ├çekirdekler ve ASM Komut Setleri}, The OS {Dosya ve Bellek Y├Ânetimi sistemleri , S├╝r├╝c├╝ler ve Kay─▒t Defteri}, The Compiler {Kaynak Kodun ├çeviri Birimleri ve Optimizasyonlar─▒} ve hatta Source Code kendine ├Âzg├╝ algoritma (lar) lar─▒ ile; biz zaten biz bile herhangi ─░ste─če ba─čl─▒ olmak ile herhangi bir makineye uygulamadan ├Ânce ilk algoritma dahilinde oluyor bir darbo─čaz oldu─čunu g├Ârebilirsiniz Architecture , OS ve Programmable Language ikinci algoritmaya g├Âre. Dolay─▒s─▒yla, modern bir bilgisayar─▒n i├ž yap─▒s─▒n─▒ dahil etmeden ├Ânce zaten bir sorun vard─▒.


Biti┼č Sonu├žlar─▒

Ancak; Bu yeni sorular─▒n ├Ânemsiz olmad─▒─č─▒n─▒ s├Âylemek de─čil, ├ž├╝nk├╝ onlar kendileri ve her ┼čeyden ├Ânce bir rol oynuyorlar. Prosed├╝rleri ve genel performans─▒ etkilerler ve bu, cevaplar─▒n─▒ ve yorumlar─▒n─▒ veren bir├žok ki┼činin ├že┼čitli grafik ve de─čerlendirmeleri ile a├ž─▒kt─▒r. E─čer benzetmesi dikkat ├Âderseniz Boss ve iki i┼č├ži A & B vard─▒ gidip gelen paketleri almak i├žin C & D S├Âz konusu iki algoritmalar─▒n matematiksel g├Âsterimler dikkate s─▒ras─▒yla ve bilgisayar─▒n bile kat─▒l─▒m─▒ olmadan g├Ârebilirsiniz Case 2 % 60 yakla┼č─▒k Case 1 Bu algoritmalar kaynak koduna uyguland─▒ktan sonra grafiklere ve ├žizelgelere bakt─▒─č─▒n─▒zdan daha h─▒zl─▒ ve daha sonra, belirli bir donan─▒m ├╝zerinde i┼člem yapmak i├žin i┼čletim sistemi arac─▒l─▒─č─▒yla derlenmi┼č ve optimize edilmi┼č ve y├╝r├╝t├╝lm├╝┼čt├╝r. Bu algoritmalardaki farkl─▒l─▒klar aras─▒nda biraz daha fazla bozulma oldu─čunu bile g├Ârebilirsiniz.

┼×imdi "Veri" seti olduk├ža k├╝├ž├╝kse o ilk ba┼čta fark o kadar feci g├Âr├╝nmeyebilir ancak o zamandan beri Case 1 hakk─▒ndad─▒r 60 - 70% daha yava┼č Case 2 biz zaman infaz farkl─▒l─▒klar a├ž─▒s─▒ndan varl─▒k olarak bu i┼člevin b├╝y├╝me bakabilirsiniz:

 DeltaTimeDifference approximately = Loop1(time) - Loop2(time)
//where 
Loop1(time) = Loop2(time) + (Loop2(time)*[0.6,0.7]) // approximately
// So when we substitute this back into the difference equation we end up with 
DeltaTimeDifference approximately = (Loop2(time) + (Loop2(time)*[0.6,0.7])) - Loop2(time)
// And finally we can simplify this to
DeltaTimeDifference approximately = [0.6,0.7]*(Loop2(time)
 

Ve bu yakla┼č─▒m, bu iki d├Âng├╝ aras─▒ndaki hem algoritmik olarak hem de yaz─▒l─▒m optimizasyonlar─▒n─▒ ve makine talimatlar─▒n─▒ i├žeren makine operasyonlar─▒ aras─▒ndaki ortalama farkt─▒r. B├Âylece veri k├╝mesi do─črusal olarak b├╝y├╝d├╝─č├╝nde, ikisi aras─▒ndaki zaman fark─▒ da artar. Algoritma 1 zaman belirgin olan algoritma 2 daha getirmeler sahip Boss aras─▒ndaki yol ileri ve geri maksimum mesafeye sahip A ve C Algoritma 2 ise birinci tekrarlanmas─▒ndan sonra, her bir durum i├žin Boss seyahat etmek zorunda A ile bir kez ve daha sonra daha sonra yap─▒lan A o seyahat etmek zorunda sadece bir kez maksimum mesafe ge├žerken A i├žin C .

Dolay─▒s─▒yla, Boss ayn─▒ anda iki benzer ┼čey yapmaya odaklanmaya ├žal─▒┼čmak ve benzer ard─▒┼č─▒k g├Ârevlere odaklanmak yerine, ileri geri hokkabazl─▒k yapmak, onu iki kez daha fazla seyahat etmek ve ├žal─▒┼čmak zorunda oldu─ču i├žin onu g├╝n├╝n sonuna kadar olduk├ža k─▒zd─▒racak. Bu nedenle, patronunuzun enterpolasyonlu bir darbo─čaza girmesine izin vererek durumun kapsam─▒n─▒ kaybetmeyin, ├ž├╝nk├╝ patronun e┼či ve ├žocuklar─▒ bunu takdir etmez.


5







Eski C ++ ve optimizasyonlar olabilir. Bilgisayar─▒mda neredeyse ayn─▒ h─▒zda elde ettim:

Bir d├Âng├╝: 1.577 ms

─░ki d├Âng├╝: 1.507 ms

Visual Studio 2015'i 16 GB RAM'e sahip bir E5-1620 3.5 GHz i┼člemcide ├žal─▒┼čt─▒r─▒yorum.


1



─░lgili yay─▒nlar


Neden Java'da 2 * (i * i) 2 * i * i'den daha h─▒zl─▒?

Toplam neden enjeksiyondan (: +) daha h─▒zl─▒?

Neden Python 3.5'te Python 3.4'e g├Âre daha h─▒zl─▒ ├ževiri yap─▒yor?

Operat├Ârler neden y├Ântem ├ža─čr─▒lar─▒ndan ├žok daha yava┼č? (yap─▒lar yaln─▒zca eski JITÔÇÖlerde daha yava┼čt─▒r)

StringBuilder # append (int) neden Java 7'de Java 8'den daha h─▒zl─▒?

perl'de foreach d├Âng├╝s├╝nde otomatik olarak indeksini al

Neden numpy's einsum, numpy'nin yerle┼čik fonksiyonlar─▒ndan daha h─▒zl─▒d─▒r?

Solr neden Postgres'ten ├žok daha h─▒zl─▒?

S├Âzl├╝k neden listeden ├žok daha h─▒zl─▒?

Neden d├Âng├╝ler i├žinde keyfi hedef ifadelere izin verilir?

Etiketle ilgili di─čer sorular [c++]


JSON'u bir kabuk beti─činde nas─▒l g├╝zel basabilirim?

Birden ├žok sat─▒rdan metni SQL sunucusunda tek bir metin dizesine birle┼čtirmek nas─▒l?

Grep'i Linux'ta sadece dosya adlar─▒n─▒ g├Âstermek i├žin nas─▒l kullanabilirim?

Not Defteri ++ 'da JSON nas─▒l yeniden bi├žimlendirilir?

Yerel bir ┼čubenin hangi uzak ┼čubeyi takip etti─čini ├Â─črenin

git t├╝m kaydedilmemi┼č veya kaydedilmemi┼č de─či┼čiklikleri geri al

Arr .__ len __ () Python'da bir dizinin uzunlu─čunu almak i├žin tercih edilen y├Ântem midir?

Bir fonksiyonun i├žinde de─či┼čtirdikten sonra de─či┼čkenim neden de─či┼čmiyor? - Asenkron kod referans─▒

Olu┼čturucu ┼×ablonunu ne zaman kullan─▒rs─▒n─▒z? [kapal─▒]

MySQL2 y├╝klenirken hata olu┼čtu: gem yerel uzant─▒s─▒ olu┼čturulamad─▒