Daha çox

QGIS-dəki əsas funksiyalar çox yivli işdən istifadə edəcəkmi?


QGIS-də çox iş parçalı işləmə imkanını oxuduqdan sonra QGIS 2.6-ya müxtəlif proseslər daxil edərkən bunun daxil ediləcəyini düşündüm. Onlayn yoxladım və yalnız bunu tapa bildim çox yivli göstərmə QGIS 2.4 tətbiq olundu (2.6-da yenidən təqdim ediləcəyini düşünürəm). İndi xəritələr, xüsusilə böyük məlumat dəstləri ilə işləyərkən çox tez bir zamanda yenidən çəkilə bilər.

Çox iş parçacığını əsas funksionallığa daxil etməyin olduqca çətin olduğunu və istifadəçilərə buna nail olmaq üçün Python kodunu manipulyasiya etmələrini tövsiyə etdiyini, məsələn, PyQGIS-də GIS əməliyyatlarına paralel olaraq?

Xüsusiyyət tələbini də yoxladım, amma Tim Sutton tərəfindən 9 aydır bağlanır, son şərh isə belədir:

"Bunu bağlayıram - Martin Dobias QGIS 2.2-dən sonra birləşdiriləcək bir filialda bir tətbiqə sahibdir"

QGIS 2.6-dakı bəzi funksiyalar çox iş parçalamaqdan istifadə edəcəkmi (yoxsa yenidən göstərməyə yönəldiləcək) və olmasa, QGIS 3.0-da dəyişəcəkmi?


Düşünürəm ki, QGIS 3.0 cavabını Nabble-da yerləşdirilmiş bu son söhbətdə tapa bilərsiniz:

QGIS 3-də işləmə paralelləşməni dəstəkləyəcəkmi?

Nyall Dawson-a istinad:

Paralelləşmədən sonra daxilində tək bir alqoritm (Məsələn, birdən çox mövzu istifadə edərək tamponlama xüsusiyyətləri), onda bu işin həyata keçirilməsinə dair planlardan xəbərsizəm.


Yalnız indiki zamanda işləyir (QGIS 2.6).

Martin və mən bir növ ümumi yivli proses API haqqında danışdıq, ancaq bu anda yalnız danışıqlar.


S: Çox işləməli nə zaman istifadə etməlisiniz?

A: & quotSualınız çox genişdir. Fəaliyyətin yalnız bir iplə sadə, sürətli və etibarlı şəkildə qarşılana biləcəyi az sayda sistem var. Məsələn: [hədəf şirkətin satdığı tipik bir sistemi seçin və işinin daha yaxşı yivlənə biləcəyi bir neçə cəhətini seçin - ağır CPU, komb., Çox istifadəçi - ehtimal olunan bir şeyi seçin və izah edin].

S: Fərqli mövzuların qarşılıqlı müstəqil tapşırıqları yerinə yetirməsi halında çox işləmə faydalı olarmı?

A: & quot "Tapşırıqları icra etmək" dediklərinizdən asılıdır. Mövzular qarşılıqlı müstəqil məlumatları paralel şəkildə işləsə, çox işləmə mütləq faydalı olardı - qıfıllar üçün tələbləri azaldır və kilidlərin sayı ilə super xətti bir şəkildə çıxma ehtimalı artır. OTOH, eyni kodu icra edən mövzu ilə bağlı heç bir problem yoxdur, bu təhlükəsizdir və çox yaygındır. & Quot


3 Cavablar 3

Əməliyyat sistemi təklif edir vaxt dilimiİşləməyə uyğun olan mövzuya CPU s.

Yalnız bir nüvə varsa, əməliyyat sistemi bu nüvədə bir müddət dilimində işləməyə ən uyğun ipliyi planlaşdırır. Bir müddət dilim tamamlandıqdan sonra və ya IO-da işləyən iplik bloklandıqda və ya prosessor xarici hadisələrlə kəsildikdə, əməliyyat sistemi bundan sonra hansı mövzu işləyəcəyini yenidən qiymətləndirir (və eyni ipliyi yenidən və ya fərqli birisini seçə bilər).

Qaçış üçün uyğunluq, ədalət və prioritet və hazırlıq dəyişikliyindən ibarətdir və bu üsulla müxtəlif iplər vaxt dilimləri alır, bəziləri digərlərindən daha çoxdur.

Birdən çox nüvə varsa, N, əməliyyat sistemi nüvələr üzərində işləməyə ən uyğun N mövzularını planlaşdırır.

Prosessor yaxınlığı səmərəliliyi nəzərə alır. CPU hər dəfə əvvəlkindən fərqli bir iş parçası işlədərkən biraz yavaşlamağa meylli olur, çünki önbelleği əvvəlki iplik üçün isti, yenisinə isə soyuqdur. Beləliklə, eyni ipi eyni prosessorda çoxsaylı zaman dilimləri üzərində işləmək səmərəliliyin üstünlüyüdür.

Bununla birlikdə, əməliyyat sistemi fərqli CPU-larda bir mövzu vaxt dilimi təklif etməkdə sərbəstdir və fərqli zaman dilimlərindəki bütün CPU-larda fırlana bilər. Bununla birlikdə, @ gnasher729-un dediyi kimi, eyni vaxtda birdən çox CPU-da bir mövzu işlədə bilməz.

Hyperthreading, aparatda tək olan bir metoddur inkişaf etmiş CPU nüvəsi iki və ya daha çoxunun icrasını dəstəkləyə bilər fərqli eyni vaxtda iplər. (Belə bir CPU, silikon daşınmaz əmlakında əlavə tam nüvələrdən daha aşağı qiymətə əlavə mövzuları təklif edə bilər.) Bu inkişaf etmiş CPU nüvəsi, CPU qeyd dəyərləri kimi digər iş parçaları üçün əlavə vəziyyəti dəstəkləməlidir və koordinasiya vəziyyətinə və amp davranışına sahibdir. mövzuları qarışdırmadan həmin CPU daxilindəki funksional bölmələrin paylaşılmasına imkan verir.

Hiper işləmə, texniki baxımdan bir proqram baxımından, proqramçı baxımından çətin olsa da, icra modeli daha mürəkkəb bir şey deyil, sadəcə əlavə CPU nüvələridir. Beləliklə, əməliyyat sistemi əlavə CPU nüvələrini görür, baxmayaraq ki, bir neçə hipertişli mövzu bir CPU nüvəsinin önbellek arxitekturasını paylaşdığına görə bəzi yeni prosessor yaxınlıq problemləri var.

Biz sadəlövhlüklə düşünə bilərik ki, hiper dişli bir nüvədə işləyən iki iplik hər biri öz tam nüvəsi ilə yarı qədər sürətlə işləyir. Ancaq bu mütləq belə deyildir, çünki tək bir ipin icrası ləng döngülər ilə doludur və bunların bir hissəsi digər hipertişli ip tərəfindən istifadə edilə bilər. Bundan əlavə, zəif olmayan dövrlər zamanı belə, bir iplik digərindən fərqli funksional vahidlərdən istifadə edə bilər, buna görə eyni vaxtda icra oluna bilər. Hiper işləmə üçün inkişaf etmiş CPU, bunu dəstəkləmək üçün xüsusi olaraq bir neçə daha çox istifadə olunan funksional bölməyə sahib ola bilər.

Eyni anda birdən çox nüvədə işləyən tək bir iplik kimi bir şey yoxdur.

Ancaq bu o demək deyil ki, bir mövzudan gələn təlimat paralel olaraq icra edilə bilməz. Orada deyilən mexanizmlər var təlimat boru kəmərisifariş xaricində icra buna imkan verir. Hər bir nüvədə sadə təlimatlar tərəfindən istifadə olunmayan bir çox lazımsız qaynaq var, belə ki, bir çox bu cür təlimat birlikdə işləyə bilər (birincisi əvvəlki nəticədən asılı olmadıqca). Ancaq bu hələ də bir nüvənin içində olur.

Hyper-threading bu fikrin bir növ həddindən artıq variantıdır, burada bir nüvə yalnız bir ipdən təlimatı paralel olaraq yerinə yetirmir, həm də istifadəni daha da optimallaşdırmaq üçün iki fərqli iplikdən gələn təlimatları qarışdırır.

xülasə: Tək yivli bir proqramda (təlimat səviyyəsində) paralelliyi tapmaq və istismar etmək, işlədiyi CPU nüvəsi ilə tamamilə aparatda aparılır. Və yalnız bir neçə yüz təlimatın bir pəncərəsi üzərində, geniş miqyasda yenidən sifariş vermək deyil.

Tək yivli proqramlar, çox nüvəli CPU-lardan başqa heç bir fayda əldə edə bilməz digər şeylər tək yivli tapşırığa vaxt ayırmaq əvəzinə digər nüvələrdə işləyə bilər.

OS bütün mövzuların təlimatlarını bir-birlərini gözləməyəcək şəkildə təşkil edir.

Əməliyyat sistemi mövzuların təlimat axınlarına baxmır. Yalnız mövzuları nüvələrə planlaşdırır.

Əslində, hər bir nüvə nə edəcəyini başa düşməsi lazım olduqda OS-nin planlaşdırıcısı funksiyasını işə salır. Planlaşdırma paylanmış bir alqoritmdir. Çox nüvəli maşınları daha yaxşı başa düşmək üçün hər nüvəni kernelin ayrıca işləməsi kimi düşünün. Çox yivli bir proqram kimi, nüvə yazılır ki, bir nüvədəki kodu digər nüvələrdəki kodu ilə təhlükəsiz şəkildə qarşılıqlı əlaqə quraraq paylaşılan məlumat strukturlarını (işləməyə hazır olan mövzuların siyahısı kimi) yeniləsin.

Hər halda, OS çox yivli proseslərin istismarına kömək edir əllə çox yivli bir proqram yazaraq açıq şəkildə ifşa edilməli olan mövzu səviyyəsində paralellik. (Və ya OpenMP və ya başqa bir şeylə avtomatik paralelləşdirən bir tərtibçi tərəfindən).

Sonra CPU-nun ön tərəfi hər bir nüvəyə bir iplik paylayaraq bu təlimatları daha da təşkil edir və hər bir ipdən müstəqil təlimatları açıq dövrlər arasında paylayır.

Bir CPU nüvəsi dayandırılmadığı təqdirdə yalnız bir təlimat axını işləyir (növbəti fasiləyə qədər yuxuda, məsələn zamanlayıcı fasilə). Tez-tez bu bir iş parçacığıdır, ancaq çekirdək işləndikdən və kəsildikdən və ya sistem çağırışından sonra əvvəlki mövzuya qayıtmaqdan başqa bir şey etməyi qərara alsaydı, bir kernel interrupt işçisi və ya başqa bir kernel kodu da ola bilər.

HyperThreading və ya digər SMT dizaynları ilə fiziki bir CPU nüvəsi çoxsaylı "məntiqi" nüvələr kimi fəaliyyət göstərir. Dörd nüvəli hipertişli (4c8t) CPU və düz 8 nüvəli maşın (8c8t) arasındakı OS perspektivindən yeganə fərq HT-dən xəbərdar olan bir OS-nin fiziki nüvələri ayırmaq üçün mövzuları planlaşdırmağa çalışmasıdır. t bir-biri ilə rəqabət. Hiper işləmə barədə bilməyən bir əməliyyat sistemi yalnız 8 nüvəni görəcəkdir (BIOS-da HT-i söndürmədiyiniz təqdirdə, o, yalnız 4-ü aşkar edəcək).

"Terminiön uç "CPU nüvəsinin maşın kodunu götürən, təlimatları deşifr edən və nüvənin sıradan çıxmış hissəsinə buraxan hissəsinə aiddir.. Hər nüvənin öz ön tərəfi var və bütövlükdə nüvənin bir hissəsidir. Təlimat gətirir var CPU hazırda işləyir.

Nüvənin sıradan çıxmış hissəsinin içərisində təlimat (və ya uops) giriş operandları hazır olduqda və sərbəst icra portu olduqda icra limanlarına göndərilir. Bunun proqram qaydasında olması lazım deyil, buna görə bir OOO prosessorunun tək bir iş parçası içərisində təlimat səviyyəsindəki paralelliyindən necə istifadə edə biləcəyi.

Fikrinizdə "çekirdek" i "icra vahidi" ilə əvəz edirsinizsə, düzəltməyə yaxınsınız. Bəli, CPU paralel olaraq icra vahidlərinə müstəqil təlimat / uops paylayır. (Ancaq bir terminoloji qarışıqlıq var, çünki "ön tərəf" dediniz, çünki həqiqətən CPU-nun təlimat planlayıcısı aka Rezervasyon Stansiyası icra olunmağa hazır olanı seçir).

Sifarişdən kənar icra yalnız çox yerli səviyyədə ILP tapa bilər, yalnız bir neçə yüz təlimat, iki müstəqil döngə arasında deyil (qısa olmadıqları təqdirdə).

Məsələn, bunun asm ekvivalenti

yalnız Intel Haswell-də bir sayğac artıran eyni döngə qədər sürətlə işləyəcəkdir. i ++ yalnız i-nin əvvəlki dəyərindən, j ++ yalnız j-nin əvvəlki dəyərindən asılıdır, buna görə də ikisi asılılıq zəncirləri proqram qaydasında icra olunan hər şeyin illüziyasını pozmadan paralel olaraq işləyə bilər.

X86-da, loop belə bir şeyə bənzəyir:

Haswell'in 4 tam ədədi yerinə yetirmə limanı var və hamısının toplayıcı vahidləri var, belə ki, hamısı müstəqil olduqları təqdirdə saatda 4 inc təlimata qədər iş qabiliyyətini təmin edə bilər. (Gecikmə = 1 olduqda, uçuşda 4 inc təlimatı tutaraq məhsuldarlığı artırmaq üçün yalnız 4 qeydiyyata ehtiyacınız var. Bunu vektor-FP MUL və ya FMA ilə zidd edin: gecikmə = 5 işləmə = 0,5 10 FMA-nı saxlamaq üçün 10 vektor akkumulyatora ehtiyac var. iş qabiliyyətini maksimuma çatdırmaq üçün uçuş. Və hər bir vektor 256b ola bilər, 8 ədəd bir dəqiqlikli süzgəc tutur).

Alınan budaq da bir darboğazdır: bir döngü hər təkrarlanma üçün hər zaman ən azı bir tam saat alır, çünki götürülmüş budaq ötürücülüyü saatda 1 ilə məhdudlaşır. Eax və ya edx oxumadığı / yazmadığı halda, bu asılılıq zəncirini uzadacağı təqdirdə, performansı azaltmadan loopun içinə daha bir təlimat qoya bilərdim. Döngüyə daha 2 təlimat qoymaq (və ya bir kompleks çoxlu təlimat) ön tərəfdə bir darlıq yaratmış olardı, çünki sıradan çıxmış nüvəyə hər saatda 4 uops verə bilər. (4 çoxdan çox olmayan döngələrdə baş verənlər barədə bəzi məlumatlar üçün bu SO Q & ampA-ya baxın: loop-buffer və uop cache işləri maraqlı edir.)

Daha mürəkkəb hallarda paralelliyi tapmaq daha böyük bir təlimat pəncərəsinə baxmağı tələb edir. (məsələn, bəlkə hamısı bir-birinə, sonra bəzi müstəqil olanlara bağlı olan 10 təlimat sırası var).

Yenidən Sifariş Tamponu tutumu sifarişdən kənar pəncərə ölçüsünü məhdudlaşdıran amillərdən biridir. Intel Haswell-də 192 qəpik var. (Və hətta qeydiyyatdan ad dəyişdirmə qabiliyyəti ilə birlikdə (qeyd sənədinin ölçüsü) eksperimental olaraq da ölçə bilərsiniz.) ARM kimi aşağı güclü CPU nüvələri, ümumiyyətlə sifariş xaricində icra edərlərsə, daha kiçik ROB ölçülərinə sahibdirlər.

CPU-ların sıradan çıxması ilə yanaşı boru xəttinə də ehtiyac duyulduğuna diqqət yetirin. Beləliklə, təlimatlar yerinə yetirilənlərdən xeyli qabaq alınmalı və tercihen gətirmə dövrlərini itirdikdən sonra buferləri doldurmaq üçün kifayət qədər iş qabiliyyəti olmalıdır. Filiallar hiyləgərdir, çünki filialın hansı yolla getdiyini bilmiriksə haradan gətirəcəyimizi bilmirik. Bu səbəbdən budaq proqnozu çox vacibdir. (Və nə üçün müasir CPU-lar spekulyativ icraatdan istifadə edirlər: bir filialın hansı tərəfə gedəcəyini və bu təlimat axınının alınmasına / dekodlanmasına / icrasına başlayacağını təxmin edirlər. Yanlış proqnoz aşkar edildikdə, son bilinən yaxşı vəziyyətə qayıdır və oradan icra edirlər.)

CPU daxili məlumatları haqqında daha çox məlumat oxumaq istəyirsinizsə, Stackoverflow x86 etiketi vikisində, o cümlədən Agner Fog-un mikroarx rəhbərinə və David Kanter-in Intel və AMD CPU-lərinin diaqramları ilə ətraflı yazılarına bəzi keçidlər var. Intel Haswell mikroarxitektura yazısından bu bir Haswell nüvəsinin (bütün çipin deyil) bütün boru kəmərinin son diaqramıdır.

Bu a-nın blok diaqramıdır subay CPU nüvəsi. Dörd nüvəli prosessorda bunların 4-ü çipdə, hər biri öz L1 / L2 önbelleklərinə malikdir (L3 önbellek, yaddaş nəzarətçiləri və sistem cihazlarına PCIe əlaqələrini bölüşmək).

Bunun çox çətin olduğunu bilirəm. Kanter-in məqaləsində ayrıca, cəbhə hissəsini icra vahidlərindən və ya önbelleklərdən ayrı danışmaq üçün bunların hissələri göstərilir.


GO - Goroutine və paralellik

pthreads əvvəlcədən planlaşdırma aparın, halbuki C ++ lifləri kooperativ planlaşdırma edin.

Pthreads ilə: cari icra yolu istənilən vaxt kəsilə bilər və ya əvvəlcədən seçilə bilər. Bu o deməkdir ki, mövzu üçün məlumat bütövlüyü böyük bir problemdir, çünki bir mövzu məlumatın bir hissəsini yeniləmək ortasında dayandırıla bilər və məlumatın bütövlüyünü pis vəziyyətdə saxlaya bilər. və ya natamam vəziyyət. Bu həm də o deməkdir ki, əməliyyat sistemi eyni vaxtda birdən çox iş parçasını işə salmaqla və məlumat əldə etməsini qorumaq üçün geliştiriciyə tapşıraraq çoxsaylı CPU və CPU nüvələrindən faydalana bilər.

C istifadə edərək,

Mövzular istifadə olunur, ərizə eyniadlı ola bilər,

Paralelliyin xüsusiyyətləri:

1) Birdən çox aktyor

2) Paylaşılan mənbə

3) Giriş qaydaları (Atom / Şərti sinxronizasiya)

C ++ lifləri ilə: cari icra yolu yalnız lif icrası verdikdə kəsilir Bu, o deməkdir ki, liflər həmişə yaxşı müəyyən edilmiş yerlərdə başlayır və dayanır, buna görə də məlumatların bütövlüyü məsələdən daha azdır. Həm də liflər istifadəçi məkanında tez-tez idarə olunduğu üçün bahalı kontekst açarları və prosessor vəziyyəti dəyişikliyi edilməsi lazım deyildir, bu da bir lifdən digərinə dəyişməyi son dərəcə təsirli edir. Digər tərəfdən, eyni vaxtda heç iki lif işləyə bilmədiyi üçün, yalnız liflərdən istifadə etmək çoxsaylı CPU və ya birdən çox CPU nüvəsindən istifadə etməyəcəkdir.

Win32-də, a lif bir növ istifadəçi tərəfindən idarə olunan bir mövzu. Bir lifin öz yığını və öz təlimat göstəricisi vs. var, lakin liflər OS tərəfindən planlaşdırılmır: SwitchToFiber-i açıq şəkildə çağırmalısınız. İplər, əksinə, əməliyyat sistemi tərəfindən əvvəlcədən planlaşdırılır.

Yəni təxminən bir liflə danışmaq, gerçək bir OS ipi olmaqdan daha çox tətbiqetmə / runti me səviyyəsində idarə olunan bir mövzu.

C istifadə edərək,

Niyə C ++ lifləri?

Əməliyyat sistemi iplər istədiyimiz hər şeyi verin, ancaq ağır bir performans cəzası üçün: iplər arasında keçid istifadəçidən kernel rejiminə, bəlkə də ünvan sahəsi hüdudlarında irəliləməyi əhatə edir. Bunlar qismən səbəb olduqları üçün bahalı əməliyyatlardır TLB yuyulur, önbellek qaçırırCPU boru kəməri zərər: bu səbəbdən də tələlərin və syscallların nizamlı prosedur çağırışlarından daha böyük bir əmr ola biləcəyi.

Bundan əlavə, kernel, tək bir əməliyyata xidmət edənlərdən tutmuş bütün bir video oynayanlara qədər hər cür mövzuları nəzərə ala biləcək ümumi təyinatlı bir planlaşdırma alqoritmindən istifadə edərək mövzuları planlaşdırır (yəni davamını bir CPU nüvəsinə təyin edir).

Liflər, tətbiq qatında planlaşdırıldıqları üçün istifadə halları üçün daha uyğun bir planlaşdırıcı istifadə edə bilərlər. Əksər liflər vərdiş etdiyi kimi əməliyyatlara xidmət etmək, ümumiyyətlə çox qısa müddət ərzində aktiv olurlar və çox vaxt bloklanırlar. Onların davranışları tez-tez IO və ya başqa bir lif tərəfindən oyanmalı, qısa bir işləmə dövrü keçirilməli və sonra idarəetməni başqa bir lifə köçürməlidir (növbə və ya başqa bir sinxronizasiya mexanizmi istifadə edərək) .Bu cür davranış ən yaxşı bir alqoritm istifadə edən bir zamanlayıcı tərəfindən xidmət olunur. “İş oğurlamaq”Liflər bu şəkildə davranarkən, iş oğurlamaq təmin edir minimal önbellek qaçırır nə vaxt liflər arasında keçid.

Fiber çox nüvənin gücündən istifadə etmir, çünki OS-nin bildiyi tək dişli prosesdir.

GO-da go açar sözündən istifadə edərək goroutine müraciət edirik

1) GO gündəlikdir (f) a lif istifadəçi məkanında, GO işləmə vaxtı tərəfindən əvvəlcədən planlaşdırılmayan?


10 cavab

Mövzunun hamısı interleave əməliyyatlardır ki, prosesin hissələri vaxtında üst-üstə düşsün. Birdən çox sapı olan tək nüvəli maşın yalnız ətrafa tullanır: bir ipdən kiçik kodları yerinə yetirir, sonra başqa bir yivə keçir. Sadə bir planlaşdırıcı hansının ən yüksək prioritet olduğuna qərar verir və əslində nüvədə icra olunur.

Bir nüvəli kompüterdə, heç nə əslində "eyni zamanda" olur. Bütün bunlar sadəcə interleaved icrasıdır.

Arxa qalmağın bir çox yolu var. Çox.

Tutaq ki, hər iki mövzu da ümumi dəyişənə yaza bilməsi üçün sadə bir kiliddən istifadə edən sadə iki yivli bir prosesiniz var. Altı kod kodunuz var.

  • T1 əvvəl kilid
  • T1-kilidli
  • T1 sonra kilid
  • T2 əvvəl kilid
  • T2-kilidli
  • T2-dən sonra kilid

[Bu bir döngədə ola bilər və ya daha çox kilid və ya başqa bir şey ola bilər. Bütün bunlar uzanmaqdır, daha mürəkkəb deyil.]

T1-nin addımları qaydada işləməlidir (T1-əvvəl, T1-ilə, T1-sonra) və T2-nin addımları ardıcıllıqla (T2-əvvəl, T2-ilə, T2-sonra) işləməlidir.

"Sıralı" məhdudlaşdırma xaricində bunlar hər hansı bir şəkildə interleaved edilə bilər. Hər hansı bir şəkildə. Yuxarıda göstərildiyi kimi işlədilə bilər. Digər etibarlı bir sifariş (T1-əvvəl, T2-əvvəl, T2-kilid, T1-kilid, T2-sonra, T1-sonra). Bir çox etibarlı sifariş var.

Bu, yalnız altı dövləti olan bir dövlət maşınıdır.

Deterministik olmayan sonlu bir dövlət avtomatıdır. T1-xxx vəziyyətlərinin T2-xxx vəziyyətləri ilə sıralanması qeyri-müəyyəndir və heç bir əhəmiyyəti yoxdur. Beləliklə, "növbəti vəziyyət" in sikkə atdığı yerlər var.

Məsələn, FSM başladıqda T1 əvvəl və ya T2 əvvəl hər ikisi qanuni ilk vəziyyətdir. Bir sikkə atın.

Deyək ki, T1 əvvəl ortaya çıxdı. Bunu et. Tamamlandıqdan sonra T1-ilə və T2-əvvəl arasında seçim var. Bir sikkə atın.

FSM-nin hər addımında iki seçim olacaq (iki mövzu - iki seçim) və bir sikkə atmaq hansının konkret vəziyyətinin izləndiyini müəyyən edə bilər.

Bloklama funksiyalarının yazılması dövlət maşınları yarada bilməyən insanlar üçündür)

Mövzular bloklamadan keçə bilmirsinizsə faydalıdır. Heç bir təməl kompüter fəaliyyəti həqiqətən maneə törətmir, sadəcə çoxu istifadə rahatlığı üçün bu şəkildə həyata keçirilir. Bir xarakter qaytarmaq və ya "oxunmadı" əvəzinə bir oxuma funksiyası bütün bufer oxunana qədər bloklanır. Bir növbədə qayıt mesajını yoxlamaq və tapılmadıqda geri qayıtmaq əvəzinə bir əlaqə funksiyası cavab gözləyir.

Bir dövlət maşınında bloklama funksiyalarından istifadə edə bilməzsiniz (ən azı "dondurulmasına" icazə verilməyən).

Bəli, dövlət maşınından istifadə etmək alternativdir. Real Time sistemlərində bu, maşın üçün bir çərçivə təmin edən sistemdir. Mövzulardan istifadə etmək və bloklama funksiyaları sadəcə "asan çıxış yolu" dır, çünki adətən bir bloklama funksiyasına bir çağırış dövlət maşınındakı təxminən 3-4 vəziyyəti əvəz edir.

Yalnız bir iş parçası və dövlət maşını istifadə edərək, Java kimi yüksək səviyyəli dildə çoxsaylı işləmə funksiyasına necə nail olmaq olar? Məsələn, görüləcək 2 fəaliyyət varsa (hesablama aparmaq və G / Ç aparmaq) və bir fəaliyyət blok edə bilərsə?

Təsvir etdiyiniz adlanır kooperativ çox tapşırıqtapşırıqların CPU-ya verildiyi və müəyyən bir müddət və ya fəaliyyətdən sonra könüllü olaraq imtina etməsi gözlənilən. CPU istifadə etməyə davam etməklə və ya saqqızları bütün işləri bloklamaqla və bir donanım nəzarətçi taymerinə sahib olmaqla iş birliyi etməyən bir tapşırıq, vəzifələri idarə edən bir kod yoxdur.

Müasir sistemlərdə gördüklərinizə deyilir qabaqcıl çox tapşırıq, burada tapşırıqların CPU-dan imtina etməsi lazım deyil, çünki nəzarətçi bir hardware tərəfindən yaradılan fasilə gəldikdə bunu edir. Nəzarətçidəki fasilə xidməti rutini CPU-nun vəziyyətini saxlayır və növbəti dəfə tapşırıq vaxt diliminə layiq görüldüyü zaman bərpa edir, sonra vəziyyəti növbəti vəzifədə yerinə yetiriləcək olan vəziyyətdən bərpa edir və heç bir şey olmamış kimi içəriyə qayıdır. . Bu hərəkətə a deyilir kontekst açarı və bahalı ola bilər.

Yüksək səviyyəli dillərdə çoxlu işləmə əvəzinə "yalnız dövlət maşını" yolundan istifadə etmək üçün alternativdir?

Canlı? Əlbəttə. Ağlı başında? Bəzən. Mövzulardan və ya bir növ ev şəraitində hazırlanan kooperativ çox tapşırıqdan (məsələn, dövlət maşınlarından) istifadə etməyiniz, etmək istədiyiniz alış-verişdən asılıdır.

Mövzular tapşırıq dizaynını sadələşdirir ki, hər birini öz məlumat sahəsi ilə başqaları ilə bölüşən bir proqram kimi qəbul edə bilərsiniz. Bu, əlinizdəki işə diqqət yetirmə azadlığı verir və eyni zamanda təkrarlamaq üçün tələb olunan bütün rəhbərlik və ev işləri deyil. Ancaq heç bir yaxşı iş cəzasız qalmadığından, bu rahatlığın hamısını kontekst açarları ilə ödəyəcəksiniz. Minimum iş gördükdən sonra (könüllü olaraq və ya G / Ç kimi bloklayacaq bir şey etməklə) CPU qazanan bir çox mövzuya sahib olmaq, kontekst keçidini həyata keçirərkən çox sayda prosessor vaxtını yeyə bilər. Xüsusilə, bloklama əməliyyatlarınız nadir hallarda çox uzun müddət bloklanırsa doğrudur.

Kooperativ yolunun daha mənalı olduğu bəzi vəziyyətlər var. Bir dəfə səsvermə tələb edən yaddaşla eşlenen interfeys vasitəsilə bir çox məlumat kanalını ötürən bir aparat üçün bəzi istifadəçi proqramı yazmalı oldum. Hər kanal elə qurulmuş bir obyekt idi ki, ya mövzu kimi işləməsinə icazə verə bilərəm, ya da təkrar bir anket dövrü icra edə bilərəm.

Yuxarıda göstərdiyim səbəbdən çox işlənmiş versiyanın performansı heç də yaxşı deyildi: hər bir mövzu minimal iş gördü və sonra digər kanalların bir müddət qalması üçün çox kontekst açarına səbəb ola bilməsi üçün CPU verirdi. Əvvəlcədən işləmə qabiliyyətinə kömək edənə qədər mövzuların sərbəst buraxılmasına icazə verilməsi, lakin bir müddət əvvəl dilim ala bilmədikləri üçün aparat bufer yüklənmədən əvvəl bəzi kanalların xidmətə alınmaması ilə nəticələndi.

Hər kanalda təkrarlanan tək yivli versiya, yanmış meymun kimi qaçdı və sistemdəki yük qaya kimi düşdü. Əlavə performans üçün ödədiyim cərimə tapşırıqları özümlə ələ keçirmək məcburiyyətində qaldı. Bu vəziyyətdə bunu etmək üçün kod kifayət qədər sadə idi ki, onu inkişaf etdirmək və saxlamaq üçün xərclər performansın yaxşılaşdırılmasına dəyər idi. Düşünürəm ki, bu, həqiqətən, alt xəttdir. Mənim iplərim bir sistem zənginin qayıtmasını gözləyən oturanlar olsaydı, məşq yəqin ki, buna dəyməzdi.


[Udemy 100% Endirim] -Qgis 101

100% Pulsuz Udemy Endirimli Kupon Kodunu (UDEMY Pulsuz Promo Kodu) əldə edin, bu Kursu qeydiyyatdan keçirə biləcəksiniz və # 8220Qgis 101& # 8221 Ömür boyu giriş üçün tamamilə PULSUZ. Tələsin, yoxsa $ $ ödəməlisiniz

Tələblər

Kurs müddəti: 2 saat

TəlimatçıMədənçı Geoloq

İngilis Reytinqi: 4.3

Təsvir

Kursun məqsədi tələbəni başlamaqdır QGIS, pulsuz və açıq mənbə istifadəçilərin məkan məlumatlarını təhlil etmələrini və redaktə etmələrini təmin edən kompleks bir iş mühiti olan masa üstü coğrafi məlumat sistemi proqramı. QGIS ilə inteqrasiya olunduğu üçün coğrafi emal üçün müxtəlif faydalı əmrlər və yardımçı proqramları təqdim edən çoxsaylı məlumat növlərini (vektor və raster formatları), veb xidmətləri dəstəkləyir. GDALOGR kitabxanalar.

Kurs, coğrafi məlumat sisteminin ümumi konsepsiyalarını öyrənən, vektor, alfasayısal və raster məlumatlarla işləyən, coğrafi işləmə alətləri ilə işləyən və xəritə yaratmağı bacaran tələbənin köməyi ilə fərqli çətinlik səviyyəsinə malik vahidlər şəklində qurulmuşdur.

Bu onlayn kursda qeydiyyatdan keçən tələbələr bu kursun sonunda Qgis-dən necə səmərəli istifadə edəcəyini öyrənəcəklər, yalnız başlanğıcdakı əsasları və orta səviyyəli hissəni əhatə edəcək və daha sonra inkişaf etmiş bir bölmə əlavə ediləcəkdir.


2 Cavablar 2

(Bu tam cavab deyil, ancaq bir şərhə sığmaq çox uzun görünür.)

Proqram sənayesində "Paralellik üçün dizayn" ın qəbul olunma dərəcəsini təsir edən bir çox amil var. Bəzilərinin faydalarla heç bir əlaqəsi yox idi. Məsələn, inkişaf etdiricilərin bacarıq dəstləri və bilik səviyyələri və s.

Müşahidələrimdən biri də tətbiqetmə növünün paralel paradiqmanın qəbul dərəcəsini təyin etməsidir. Hər bir proqram məhsulu xətti (səviyyə) və ya komponentdə bir və ya daha çox "təbii domen / paradiqma" var, yəni müəyyən bir paradiqmada tətbiq olunduğu təqdirdə proqramın inkişafı və qorunması çox daha asan olardı.

Müəyyən bir tətbiqi paralelləşdirmək üçün bir paradiqma açarı lazımdırsa, ehtimal ki, proqram şirkətləri əsaslandırmaq üçün bu qədər səmərəli tapa bilməzlər. Xüsusi paradiqma asanlıqla paralelləşə bilərsə, gördüyünüz budur ki, bu proqram paralel proqramlaşdırma üçün daha yüksək qəbul etmə dərəcəsinə sahib olacaqdır.

Paradiqmalar siyahısı ilə əlaqədar olaraq Dataflow əlavə etmək istərdim. Bütün tapşırıqlar əvvəlcədən elan edilir. Hər bir tapşırıq icraya başlamazdan əvvəl giriş və çıxışlarını elan edir. Bir tapşırıq bütün daxilolma məlumatları əldə edilən anda başlayır.

Dataflow paradiqmasının nümunələri:

Çox uğurlu bir paradiqmaya sahib olmaq kifayət deyil. Paralel proqramlaşdırmanın qəbul dərəcəsini gündəmə gətirmək üçün paralelliyin digər paradiqmalara da ("köhnəlmiş" olanlar daxil olmaqla) tətbiq edilməsi lazımdır.

Hesablama tapşırığı üçün bir Windows dialoqunu (hər bir Windows dialoqu bir mövzuda yerləşdirilir) kürü ataraq Windows GUI proqramında paralelliyi uğurla həyata keçirən və Windows mesajlarından istifadə edərək məlumat mübadiləsi həyata keçirən başqalarını gördüm.

Bu, yuxarıdakı müşahidəmi təkrarlayır: bir tətbiqə paralelliyin tətbiqi tətbiqetmənin qeyri-təbii bir paradiqmada yenidən yazılmasını tələb edərsə, inkişaf və istismarın mürəkkəbliyi artacaqdır.

Tamamilə hesablama baxımından intensiv olan tapşırıqlar üçün performans qazancı ümumiyyətlə Amdahl Qanununun proqnozu ilə çox yaxından uyğun gəlir, bir şərtlə ki, bütün hesablamalar yerli olaraq bir kompüterdə aparılsın (yəni daha yavaş şəbəkə I / O trafikinə tabe deyil).

Yəni tətbiqlərinizdə paralelləşməyən darlıqların olduğunu tez bir zamanda öyrənəcəksiniz. Bəzən bu darlıqlar nəzəri cəhətdən paralelləşdirilmir, yəni daha yaxşı bir alqoritm tapmaq ümidi yoxdur.

Şəxsi hekayə. Bir JPEG sənədini deşifrə edən, ölçüsünü dəyişən və sonra xüsusi bir şəkil faylı formatında saxlayan sadə bir paralelləşdirilmiş proqram yazdım. Sınaqdan sonra, proqramın 3 mövzu və ya 4 mövzu ilə sınaqdan keçirildiyi zaman 1,6 saniyə çəkdiyini gördüm. JPEG kod çözmə addımının zamanın 25% -dən çoxunu aldığı və ən yavaş paralel olmayan addım halına gəldiyi ortaya çıxdı.

Başqa sözlə, Amdahl qanunu kiçik proqramım üçün yalnız 3-4 CPU nüvəsi ilə qüvvəyə minir.

Bəzən proqram tələblərini dəyişdirməyə icazə verildiyi təqdirdə bu darlıqlar aradan qaldırıla bilər (məsələn, müştərilərinizdən tələb etməyiniz yox müəyyən bir şəkil formatından istifadə edin), lakin əksər hallarda tələblər daş şəklində qoyulur.

Paralellik işi üçün yazılmamış kodu eyni vaxtda sehrli bir şəkildə edə bilməzsiniz (və sehrli şəkildə kompilyatorlardan istifadə də daxil edilir).

Dəfələrlə şərtlər dəyişdi və kodun başqa cür edilməsi lazım idi. Çox köhnə günlərdə yaddaş bir mükafat idi, buna görə özünü dəyişdirmə kodu yaygındır. Bu günlərdə yaddaşdakı kodun yalnız oxunaqlı olmasının faydaları o qədər böyükdür ki, bütün müasir əməliyyat sistemləri onu tətbiq etmək istəyir.

Həm də Windows populyarlaşdıqda nə olduğunu düşünün. Bütün DOS proqramçıları proqramlaşdırma yollarını yenidən nəzərdən keçirməli idilər. Tək bir yivli proqramda tam tətbiqetmə funksiyasını çağıran bir klaviatura səsvermə döngəsinə sahib ola bilmədiniz - hadisə işləyiciləriniz olmalı idi - bu da tətbiq kodunun tərtibatını dəyişdirdi.

Mantralar "dəyişməz obyektlərdən istifadə edin!" çətin bir şəkildə öyrənilən təcrübələrdir. Yolda tez-tez itirilməsinin, lakin yenidən qurulmasının səbəbləri. "Dəyişməz obyektlərdən istifadə etmək", proqramın bu yerlərdən birinin yenilənmədən birdən çox yerdəki məlumatların önbelleğe alınmasına imkan verməyin sadə bir yoludur.

Paralel olması lazım olan dəyişikliyin funksional bir dildə tam yenidən yazılmasına ehtiyac yoxdur, lakin kitabxana ilə həll edilə bilər - bu mövcud kod kitabxanalarını saxlamağa imkan verir - ancaq yenə də istifadə etmək üçün proqramınızı yazmalısınız. OpenCL (OS X-də Grand Central) yanaşması həm CPU, həm də GPU-lardan istifadə etmək üçün çox maraqlı bir yoldur, lakin yenə də proqramınızı buna uyğun etməlisiniz.

Java-da kiçik kod parçalarının icrasını şəffaf şəkildə genişləndirmək üçün yaxşı bina blokları təmin etmək üçün çox səy sərf edildi, ancaq bunun üçün yazmırsınızsa istifadə edə bilməzsiniz.


4 Cavablar 4

Ctime və asctime funksiyalarının spesifikasiyası C89-a qayıdır və işlər o vaxtlarda bir qədər fərqli şəkildə aparılırdı, əsasən çox prosessorlu sistemlər çox yayılmırdı və beləliklə statik bir tampon istifadə etmək böyük bir problem yaratmazdı.

Çox güman ki, əlavə olaraq ayrılmış yaddaşa qayıtmadılar, çünki əlavə vaxt tələb olundu və o günlərdə CPU dövrlərinin gəlməsi daha çətindi.

Linux kimi bir POSIX sistemindəsinizsə, alternativ olaraq təsvir etdiyiniz digər iki funksiya mövcuddur:

Bu funksiya çıxışı ala bilən bir tampona bir göstərici gətirir (və eyni göstərici buferə qayıdır). _R şəkilçisi "yenidən müraciət edən" deməkdir, yəni çox işlənmiş bir proqramda və ya arada bir sıra nöqtəsi olmadan bir dəfədən çox etibarlı bir şəkildə adlandırıla bilər.


Bəzi çap x və çap (x) zəngləri üçün fərqli formatlaşdırma ilə bir az təmkinli olduqda (sonuncusu həqiqətən üstünlük verilir) yaxşı görünür, ehtimal ki, yeni stil siniflərindən də istifadə etməlisiniz, yəni sinif Loader (object):.

Bundan başqa məni narahat edən əsas məsələ semaforun istisnalardan qorunmasıdır. Bu, daha çox böyük ssenarilər üçün narahatlıq yaradır, lakin asılı olmayaraq yaxşı bir vərdişdir. Beləliklə, sərbəst buraxılma üsulu çağırılmalıdır asılı olmayaraq bir istisnanın mövzuda başqa bir şey tərəfindən qaldırılıb qaldırılmadığına dair - əks halda proqram yalnız orada qala bilər və bu, ehtimal ki, birdəfəlik skript üçün yaxşıdır.

Pythons qlobal tərcüməçi kilidini nəzərə alaraq, iş parçalamanın həqiqətən iş qabiliyyətini yaxşılaşdırdığını yoxlamaq lazımdır.


Yaddaşın korlanması

Əvvəla, bunun mütləq bir cavabı olan mükəmməl bir Q & ampA tərzi sualı olmadığını başa düşürəm, amma daha yaxşı işləməsi üçün heç bir söz deyə bilmərəm. Bunun mütləq bir həll yolu olmadığını düşünürəm və bu, Stack Overflow yerinə buraya göndərməyimin səbəblərindən biridir.

Son bir ayda kifayət qədər köhnə bir server kodunu (mmorpg) daha müasir və genişləndirmək / modlaşdırmaq üçün yenidən yazdım. Şəbəkə hissəsi ilə başladım və mənim üçün şeyləri idarə etmək üçün 3-cü tərəf kitabxanasını tətbiq etdim. Bütün yenidən faktorinq və kod dəyişiklikləri ilə bir yerdə yaddaş korrupsiyasını tətbiq etdim və bunun harada baş verdiyini öyrənməkdə çətinlik çəkirdim.

Bəzi yükləri simulyasiya etmək üçün ibtidai botları tətbiq edərkən belə, daha çox qəza etmirəm (bəzi şeylərə səbəb olan bir yaşama problemini düzəltdim), onu dev / test mühitimdə etibarlı şəkildə çoxaldıra bilmirəm.

Valgrinding the hell out of it - No invalid writes until the thing crashes (which may take 1+ day in production.. or just an hour) which is really baffling me, surely at some point it would access invalid memory and not overwrite stuff by chance? (Is there a way to "spread out" the address range?)

Code-Analysis tools, namely coverity and cppcheck. While they did point out some.. nastiness and edge cases in the code there was nothing serious.

Recording the process until it crashes with gdb (via undodb) and then working my way backwards. This /sounds/ like it should be doable, but I either end up crashing gdb by using the auto-complete feature or I end up in some internal libevent structure where I get lost since there's too many possible branches (one corruption causing another and so on). I guess it would be nice if I could see what a pointer originally belongs to/where it was allocated, that would eliminate most of the branching-issues. I cant run valgrind with undodb though, and I the normal gdb record is unusably slow (if that even works in combination with valgrind).

Code review! By myself (thoroughly) and having some friends look over my code, though I doubt it was thorough enough. I was thinking about maybe hiring a dev to do some code review/debugging with me, but I cant afford to put too much money in it and I wouldn't know where to look for someone who'd be willing to work for little-to-no money if he doesn't find the issue or anyone qualified at all.

I should also note: I usually get consistent backtraces. There are a few places where the crash happens, mostly related to the socket class becoming corrupted somehow. Be it an invalid pointer pointing to something which isn't a socket or the socket class itself becoming overwritten (partially?) with gibberish. Although I suspect it's crashing there the most since that's one of the mostly used parts, so it's the first corrupted memory which gets used.

All in all this issue has had me busy for nearly 2 month (on and off, more of a hobby project) and is really frustrating me to the point where I become grumpy IRL and think about just giving up. I just can't think about what else I am supposed to do to find the issue.

Are there any useful techniques I missed? How do you deal with that? (It can't be that common since there isn't much information about this.. or I'm just really blind?)

Some specs in case it matters:

Using c++(11) via gcc 4.7 (version supplied by debian wheezy)

The codebase is around 150k lines

Edit in response to david.pfx post: (sorry for the slow response)

Are you keeping careful records of crashes, to look for patterns?

Yes, I still have dumps of the recent crashes lying around

Are the few places really similar? In what way?

Well, in the most recent version (they seem to change whenever I add/remove code or change related structures) it would always get caught in an item timer method. Basically an item has a specific time after which it expires and it sends updated info to the client. The invalid socket pointer would be in the (still valid as far as I can tell) Player class, mostly related to that. I am also experiencing loads of crashes in the cleanup phase, after the normal shutdown where it's destroying all the static classes that haven't been explicitly destroyed ( __run_exit_handlers in the backtrace). Mostly involving std::map of one class, guessing that's just the first thing that comes up though.

What does the corrupt data look like? Zeros? Ascii? Patterns?

I haven't found any patterns yet, seems somewhat random to me. It's hard to tell since I don't know where the corruption started.

It's entirely heap-related (I enabled gcc's stack guard and that didn't catch anything).

Does the corruption happen after a free() ?

You're going to have to elaborate a bit on that one. Do you mean having pointers of already free'd objects lying around? I'm setting every reference to null once the object gets destroyed, so unless I missed something somewhere, no. That should show up in valgrind though which it didn't.

Is there something distinctive about the network traffic (buffer size, recovery cycle)?

The network traffic consists of raw data. So char arrays, (u)intX_t or packed (to remove padding) structs for more complex things, each packet has a header consisting of an id and the packet size itself which is validated against the expected size. They are around 10-60bytes with the biggest (internal 'bootup' packet, fired once at startup) having a size of a few Mb.

Lots and lots of production asserts. Crash early and predictably before the damage propagates.

I once had a crash related to std::map corruption, each entity has a map of it's "view", each entity that can see it and vice versa is in that. I added a 200byte buffer in front and after, filled it with 0x33 and checked it before each access. The corruption just magically vanished, I must've moved something around which made it corrupt something else.

Strategic logging, so you know accurately what was happening just before. Add to the logging as you get closer to an answer.

In desperation, can you save state and auto-restart? I can think of a few pieces of production software that do that.

I somewhat do that. The software consists of a main "cache" process and some other worker ones which all access the cache to get and save stuff. So per crash I don't lose much progress, it still disconnects all the users and so on, it's definitely not a solution.

Concurrency: threading, race conditions, etc

There's a mysql thread to do "async" queries, that's all untouched though and only shares information to the database class via functions with all lock.

There's an interrupt timer to prevent it from locking up that just aborts if it didn't complete a cycle for 30 seconds, that code should be safe though:

tics is volatile int tics = 0 which is increased each time a cycle is completed. Old code too.

events/callbacks/exceptions: corrupting state or the stack unpredictably

Lots of callbacks are being used (async network I/O, timers), but they shouldn't do anything bad.

Unusual data: unusual input data/timing/state

I've had a few edge cases related to that. Disconnecting a socket while packets are still being processed resulted in accessing a nullptr and such, but those have been easy to spot so far since every reference gets cleaned up right after telling the class itself it's done. (Destruction itself is handled by a loop deleting all the destroyed objects each cycle)

Dependency on an asynchronous external process.

Care to elaborate? This is somewhat the case, the cache process mentioned above. Only thing I could imagine off the top of my head would be it not finishing quick enough and using garbage data, but that's not the case since that's using network too. Same packet model.


Videoya baxın: Usare PostGIS con QGis: connessione e import shapefile OSGEO (Oktyabr 2021).