Downtime.. & some interesting videos
Sveiki,
Gal kas pastebejo – kelias dienas blog’as buvo down ir bandymai ji pasiekti dziugindavo visokiais idomiais error’ais
To priezastis – persikraustymas i kita serva. Dabar viskas turetu gryzt i savas vezes (na ir tikiuosi jog bus laiko mestelti kokio naujo content’o.. visgi arteja naujo Visual Studio beta release, tad manau tikrai bus apie ka parasyt
)
Kad post’as nebutu toks bevertis – siulau pasiziureti kelias mano manymu idomiausias presentacijas is nesenai vykusios GoingNative 2012 konferencijos (kas tikrai turetu but aktualu C++ dev’ams, ir bent jau man tai tikrai ji paliko gera ispudi):
Bjarne Stroustrup: C++11 Style
Threads and Shared Variables in C++11
STL11: Magic && Secrets
Herb Sutter: C++11, VC++11 and Beyond
Tai tiek ziniu.
Smagios darbo savaites visiems.
C++ lambda funkciju ir funkciju pointeriu vykdymo greitis keliose scenarijose
Sveiki,
Jau senokai kanors rasiau tai va pagalvojau kad jau pats laikas butu kuom nors pasidalinti
Programuodamas jau ne karta pagavau save darant funkcijas funkcijose su auto fnSomeFunction = /* some lambda expression */ kad sumazint kodo duplikavima jose. Zinoma, tokius cases galima drasiai iskelt i atskira funkcija toje pacioje klaseje.. bet kazkaip kartais atrodo tvarkingiau jas ikist toje vietoje pries panaudojima (ypac jei ji bus naudojama tik toje funkcijoje).. tada skaitant koda (bent jau man) aiskiau viskas atrodo negu kai ten ta funkcija kazkur po klase kaba. Aisq viskam turi but savo ribos.. tikrai neuzsiimu tokiu dalyku abuse’inimu
Bet.. gryztam prie sio atvejo. Man visad buvo idomu kiek tai ‘kainoja’ nasumo prasme.. nes nu mes kaip ir on-the-fly pasikuriam kazkoki daikta, kuris pagal viska tikrai neturetu gautis for free
Bent jau ant C# kiek zinau tokie bairiai tikrai neblogai kerta.
Taigi pagaliau priejau prie to kad nutariau pasirasyt small test atveji kuris tiesiog paskaiciotu ivairiu panasiu funkciju panaudojimo atveju nasuma C++’se. Apsiribojau ties keliais atvejais (kuriuos tikrai tingiu aprasinet, bet jie labai aiskus is kodo, kuri pateikiu zemiau. Jei jie nlb aiskus tai matyt ne ten uzklydote
). Taigi.. source yra toks:
LambdaFunctionPerformanceTest.h :
#pragma once #include "stdafx.h" class CLambdaFunctionPerformanceTest { private: void RegularFunction(int& p_rSomeData); std::function<void(int&)> m_fnMemberLambdaFunction; std::function<void(int&)> m_fnMemberBoundFunction; public: CLambdaFunctionPerformanceTest(); void PerformRegularFunctionCall(int& p_rSomeData); void PerformLambdaFunctionCall(int& p_rSomeData); void PerformBoundFunctionCall(int& p_rSomeData); void PerformOnTheFlyLambdaFunctionCall(int& p_rSomeData); void PerformOnTheFlyBoundFunctionCall(int& p_rSomeData); };
LambdaFunctionPerformanceTest.cpp :
#include "stdafx.h" #include "LambdaFunctionPerformanceTest.h" using namespace std::tr1::placeholders; CLambdaFunctionPerformanceTest::CLambdaFunctionPerformanceTest() { m_fnMemberLambdaFunction = [](int& p_rSomeData) { p_rSomeData++; }; m_fnMemberBoundFunction = std::bind(&CLambdaFunctionPerformanceTest::RegularFunction, this, _1); } void CLambdaFunctionPerformanceTest::RegularFunction(int& p_rSomeData) { p_rSomeData++; } void CLambdaFunctionPerformanceTest::PerformRegularFunctionCall(int& p_rSomeData) { RegularFunction(p_rSomeData); } void CLambdaFunctionPerformanceTest::PerformLambdaFunctionCall(int& p_rSomeData) { m_fnMemberLambdaFunction(p_rSomeData); } void CLambdaFunctionPerformanceTest::PerformBoundFunctionCall(int& p_rSomeData) { m_fnMemberBoundFunction(p_rSomeData); } void CLambdaFunctionPerformanceTest::PerformOnTheFlyLambdaFunctionCall(int& p_rSomeData) { auto fnOurLambdaFunction = [](int& p_rSomeData) { p_rSomeData++; }; fnOurLambdaFunction(p_rSomeData); } void CLambdaFunctionPerformanceTest::PerformOnTheFlyBoundFunctionCall(int& p_rSomeData) { std::bind(&CLambdaFunctionPerformanceTest::RegularFunction, this, p_rSomeData); }
stdafx.h :
#pragma once #include <functional>
main.cpp :
#include <iostream> #include <boost/timer/timer.hpp> #include "LambdaFunctionPerformanceTest.h" using namespace std; using boost::timer::cpu_timer; class TimerWrapper { private: cpu_timer m_Timer; public: std::string GetTime() { return boost::timer::format(m_Timer.elapsed()); } }; int main () { cout << "Running bechmarks:\n\n"; const int ciIterationCount = 1000000000; { int iTestData = 0; CLambdaFunctionPerformanceTest Tester; TimerWrapper Timer; for (int i = 0; i < ciIterationCount; i++) { Tester.PerformRegularFunctionCall(iTestData); } cout << "PerformRegularFunctionCall: " << Timer.GetTime() << "\n\n"; } { int iTestData = 0; CLambdaFunctionPerformanceTest Tester; TimerWrapper Timer; for (int i = 0; i < ciIterationCount; i++) { Tester.PerformLambdaFunctionCall(iTestData); } cout << "PerformLambdaFunctionCall: " << Timer.GetTime() << "\n\n"; } { int iTestData = 0; CLambdaFunctionPerformanceTest Tester; TimerWrapper Timer; for (int i = 0; i < ciIterationCount; i++) { Tester.PerformBoundFunctionCall(iTestData); } cout << "PerformBoundFunctionCall: " << Timer.GetTime() << "\n\n"; } { int iTestData = 0; CLambdaFunctionPerformanceTest Tester; TimerWrapper Timer; for (int i = 0; i < ciIterationCount; i++) { Tester.PerformOnTheFlyLambdaFunctionCall(iTestData); } cout << "PerformOnTheFlyLambdaFunctionCall: " << Timer.GetTime() << "\n\n"; } { int iTestData = 0; CLambdaFunctionPerformanceTest Tester; TimerWrapper Timer; for (int i = 0; i < ciIterationCount; i++) { Tester.PerformOnTheFlyBoundFunctionCall(iTestData); } cout << "PerformOnTheFlyBoundFunctionCall: " << Timer.GetTime() << "\n\n"; } system("pause"); return 0; }
Kas liecia testavima.. praleidziu 5 kartus sita daikta ir paimu vidurkius. Kiekvienas funkciju call’inimo test-case’as yra leidziamas atskirai tam tikra kieki kartu (sio atveju 1000000000). Nieko blatno
Cia ne koks mokslinis tyrimas galu gale.. padaryta idomumo delei
Beje, zinoma suprantu kad testas yra labai simplistinis.. (galbut reiktu sudetingesne funkcija naudoti o ne tokia kur skaiciuka vis didina.. na bet bendram vaizdui isgaut cia jau pakanka, kaip tuoj pamatysit). Tiesa laikai paimti be debugerio, kompiliojant Release rezimu
Kompiliatorius – MSVC 2010 jei kam idomu.
Pereinam prie rezultatu (turbut idomiausia dalis). Testai buvo leidziami ant Intel Core i7-2600K CPU (nematau prasmes rasyt kitu komponentu nes jie tikrai cia nieko apart nebent laiko (kuris cia mum nesvarbus, svarbu kiek procentaliai skirias rezultatai vieni nuo kitu) tikrai neitakojo) Visu pirma leidau atveji be jokiu kodo optimizaciju.. ir gavau stai ka:
Running bechmarks:
PerformRegularFunctionCall: 6.587718s wall, 6.567642s user + 0.000000s
system = 6.567642s CPU (99.7%)
PerformLambdaFunctionCall: 18.149572s wall, 18.127316s user + 0.000000s
system = 18.127316s CPU (99.9%)
PerformBoundFunctionCall: 45.048972s wall, 45.053089s user + 0.000000s
system = 45.053089s CPU (100.0%)
PerformOnTheFlyLambdaFunctionCall: 6.805728s wall, 6.786043s user + 0.000000s
system = 6.786043s CPU (99.7%)
PerformOnTheFlyBoundFunctionCall: 30.481592s wall, 30.466995s user + 0.000000s
system = 30.466995s CPU (100.0%)
Taigi realiai tas ‘PerformRegularFunctionCall’ yra iprastas case. Kaip ir buvo galima tiketis, lambda pasikurimas on-the-fly (‘PerformOnTheFlyLambdaFunctionCall’ case’as) kerta biski per performance.. bet tikrai ne tiek daug kiek galvojau. Labiausiai nustebino kaip elgias std::function bei std::bind atvejai. std::function tiek kai po ja yra lambda (‘PerformLambdaFunctionCall’ case’as), tiek kai po ja yra bind’as i member function’a (‘PerformBoundFunctionCall’ case’as) rodo labai dideli performance penalty. Vien bind’as (‘PerformOnTheFlyBoundFunctionCall’ case’as) gan smarkiai pakapoja.. BET aisq nepamirskim kad cia yra be optimizaciju. Kompileriai siais laikais garseja savo naglom optimizacijom, taigi bandom ijungt /O2 ir /GL ir ziurim ka turim:
Running bechmarks:
PerformRegularFunctionCall: 0.000003s wall, 0.000000s user + 0.000000s
system = 0.000000s CPU (n/a%)
PerformLambdaFunctionCall: 2.170792s wall, 2.168414s user + 0.000000s
system = 2.168414s CPU (99.9%)
PerformBoundFunctionCall: 3.526073s wall, 3.525623s user + 0.000000s
system = 3.525623s CPU (100.0%)
PerformOnTheFlyLambdaFunctionCall: 0.000001s wall, 0.000000s user + 0.000000s
system = 0.000000s CPU (n/a%)
PerformOnTheFlyBoundFunctionCall: 0.000001s wall, 0.000000s user + 0.000000s
system = 0.000000s CPU (n/a%)
Haha..
Nu aisq..suoptimizuot tokius cases kokius as jam cia padaviau manau yra baika. Ypac kai yra fiksuoti ciklo reziai. Bet mestelkim ta visa dabar i sali.. ir ziurim i trend’a, kuris visgi islieka ties tuom, jog on-the-fly funkciju kurimas nera toks jau skausmingas. Kas idomu, ‘PerformOnTheFlyLambdaFunctionCall’ ir ‘PerformOnTheFlyBoundFunctionCall’ net greiciau vykdomi negu regular function call’ai
bet cia vel gi optimizacijos pasidarbavo. Manau ne visad vaizdas bus toks jau grazus. Bet labai nuvyle std::function performance (net nzn ka cia daugiau pasakyt.. bandziau visaip pakonfigint kompileri bet negavau geresnio rezultato negu matomas cia). Na bet aisq neverta del to perdaug sukt galvos sakyciau..tam ir yra profileriai. Jei matot kad performance sucks – leidziat, nustatot vieta kur yra bottleneck, ir tada optimizuojat. Manau nustebtumete ant kiek visgi daug duoda kodo optimizacijos stage kompiliavimo metu
Bet kreivos rankos vistiek sugeba pagadint reikala, cia jau kas be ko
Tai tiek siam kartui. Tikiuosi buvo idomu ir kamnors galbut tai bus naudinga ![]()
P.S. gal kas pasigedo old-schooliniu C++ function pointeriu.. bet per velai apie juos prisimiau tad deja tai nepakliuvo i testa :/
Pirmoji pazintis su C++ AMP ir ispudziai
Vakar vakare pries miega suziurejau C++ AMP pristatyma, rodyta per siu metu BUILD konferencija. Kazkaip cia jis mane ikvepe ir siandien nutariau pasibandyt kaip cia visas sitas daiktas veikia. Juk nesinori kad Visual Studio 11 Developer Preview pasidengtu dulkemis
Trumpai tariant.. C++ AMP – tai turbut jau nemazai kam zinamo PPL ispletimas, leidziantis islygiagretinta koda vykdyti su GPU per DirectCompute (apie kuri jau seip nemazai esu snekejes praeituose post’uose). Taigi, C# turi savo TPL (Task Parallel Library), o C++ PPL (Parallel Patterns Library). Vnz realiai cia analogai, kuriu pagalba galima nesunkiai vykdyti kazka lygiagreciai ir sitaip isspaust daugiau sulciu is siolaikiniu multi-core procu. Ok.. zodis ‘nesunkiai’ cia gal nelabai tinka, nebent jei algoritmas simple. Real-world situacijose ne retai tenka is naujo isradinet dvirati siekiant tinkamai panaudot multithreading’a.. bet sis post’as ne apie tai, tad pasistengsiu nenukrypt i pievas
Pats PPL zinoma jau stipriai palengvina darba (na bent jau jo dali). Kaip ten bebutu, kai isgirdau apie C++ AMP tai sis visas reikalas labai suintrigavo. Nes seip kad paleist kazka su GPGPU tenka nemazai pavargt.. na ir aplamai reik daug papildomu ziniu igaut. C++ AMP zymiai palengvina sia uzduoti..cia tereik perprast principus ir jau good to go. Plius ir pakeitimai kalbos sintaksei isties minimalus (cia per daug apie tai nesnekesiu, norintys gali pasiziuret post’o pradzioj pateikta linka i pristatyma arba seip nete pasiskaityt). Esme tame jog kompiliatorius pats sugeneruoja visa DirectX inicializavimo koda ir tuo paciu HLSL, kuris jau bus vykdomas ant GPU. Taigi is esmes susitaupo begale laiko ir pastangu.. plius, kadangi cia DirectCompute paremtas solution’as – jis veiks ant visu HW vendoriu. Na aisq visad yra ‘the catch’, kaip ir sio atveju – reik turet DX11 palaikancia HW. Visgi.. bonusas tame, kad neliekam priristi prie kazkokio tai konkretaus HW vendorio.. plius kaip aiskino pristatyme – yra dirbama ir prie kitokio tipo sita reikala realizuojanciu zemesnio lygio framework’o daliu, kurie under the hood gales ateity pvz kad ir OpenGL ar dar kokiu kitu velniu remtis. Vnz pagal mane perspektyvos cia geros ir dideles.
Taciau zinoma man iskart kylo klausimas del nasumo, kuri mes prarandam del viso sito ‘generic’ stuff. Deja, kolkas dar nespejau atlikti palyginamojo tyrimo, bet ateityje mastau toki pasidaryt (seip idomu ir tiek). Reiktu sioje vietoje palygint pvz gerai parasyta HLSL su tuom ka cia prigeneruoja ir pan. situacijas. Vnz.. tikrai dziaugiuosi kad MS juda gera kryptimi sioje vietoje (IMO). Kas dar labai nustebino – GPGPU debugging supportas! Va ko jau labai senai truksta GPU programinge.. nu yra keli solutionai bet cia kalbama apie integracija tiesiai i VS, ir plius del to atsirado papildomai nemazai irankiu, kurie pravers debuginant bet koki CPU parallel koda.. kas manau yra tiesiog super !!!
Tiesa..iskart nusivyliau, nes pasirodo jog under Windows 7 GPGPU debugingas neveikia… :/ reik Windows 8. Tiesa neaisku ar cia tik dabar ar taip bus ir galutineje versijoje.. Tikiuosi, kad veliau palaikys ir kitas OS. Su AMP aplamai yra keleta ‘gotchas’, tad siulau pasiziuret cia kad paskui bereikalo neskaudetu galva tiems kas nores issibandyt sita daikta
Seip turiu isirases Windows 8 Dev Preview, bet i virtualke.. o sitam daiktui reik normalaus DX 11 driverio..taigi cia no go. Vnz reiks laukt betos.
Ok, gryztam prie rimto reikalo (source code
). Pasibandymui pasirasiau miniatiurini pvz..kuris tiesiog pakelia vektoriuje esancias reiksmes kvadratu. Kaip jau sakiau, siandien tik norejau pasibandyt ar sitas daiktas isvis kompiliojas ir veikia.. tad nereik ant manes stumt del pvz paprastumo, ok ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include <stdio.h> #include <iostream> #include <ppl.h> #include <amp.h> using namespace std; using namespace Concurrency; template <typename _T> static void Init(vector<_T>& p_rvIn) { for (_T i = 0; i < (_T)p_rvIn.size(); i++) { p_rvIn[i] = i; } } template <typename _T> static void PrintResults(const vector<_T>& p_rvOut) { for_each(p_rvOut.begin(), p_rvOut.end(), [](_T value) { cout << value << endl; }); } template <typename _T> static void ComputeOnCPU(const vector<_T>& p_rvIn, vector<_T>& p_rvOut) { parallel_for(0, (int)p_rvIn.size(), [&](int i) { p_rvOut[i] = p_rvIn[i] * p_rvIn[i]; }); } template <typename _T> static void ComputeOnGPU(const vector<_T>& p_rvIn, vector<_T>& p_rvOut) { array_view<const _T, 1> inView(p_rvIn.size(), p_rvIn); array_view<writeonly<_T>,1> outView(p_rvOut.size(), p_rvOut); parallel_for_each(outView.grid, [=](index<1> i) restrict(direct3d) { outView[i] = inView[i] * inView[i]; }); } template <typename _T> static void PerformTestRun(int p_iSize) { vector<_T> vContainerIn(p_iSize); vector<_T> vContainerOut(p_iSize); Init(vContainerIn); cout << "\n\nCPU " << typeid(_T).name() << " results: \n"; ComputeOnCPU(vContainerIn, vContainerOut); PrintResults(vContainerOut); cout << "\n\nGPU " << typeid(_T).name() << " results: \n"; ComputeOnGPU(vContainerIn, vContainerOut); PrintResults(vContainerOut); } int main () { const int iSize = 100; PerformTestRun<int>(iSize); PerformTestRun<float>(iSize); PerformTestRun<unsigned int>(iSize); PerformTestRun<double>(iSize); system("pause"); return 0; } |
Vnz cia tiesiog prasibandau kaip atliekami veiksmai su ivairiais kintamuju tipais. Viskas kaip ir veikia bei gale gaunu teisingus rezultatus
Tiesa..del to ‘gotcha’ tenka sita koda kompiliuoti kaip ‘Release’ nes kitaip negali nauduot ‘const’ view’uose. Ka padarysi.. seip kadangi as jau zinau kaip dirba DirectCompute ir DirectX tai mazdaug isiavziduoju ka jis ten prigeneruoja ir kaip tie visi ‘const’ ir ‘writeonly’ padeda padidint greitaveika, na bet cia i tai nesileisiu nes nematau pointo per daug lyst i smulkmenas. Sio pvz tikslas tikrai nera isspaust sultis is HW
Ka noriu pabriezt tai..ant kiek nedaug is esmes pasileke kodas lyginant ComputeOnCPU ir ComputeOnGPU metodus. Aisku, norint realizuot kazka sudetingesnio pakeitimu butu daugiau.. bet pamate kiek reiktu prirasyt norint tai realizuot paciam per DX + DirectCompute kad tai veiktu ir grazintu rezultatus turbut nusiverstumet nuo kedes
Aisku kaip diena kad solution’as parasytas pvz su kokia CUDA veiks daug greiciau negu per DirectCompute.. BET visgi cia mes isliekam universalus..uz ka ir tenka sumoket
Reziumuojant galiu pasakyt tik tiek kad esu labai patenkintas siom naujovem. Ateity reiks butinai palygint C++ AMP ir native implementacijos nasuma o seip tai good job VS Team !!!
Smagumai su C++ ir lambda to function pointer
Sveiki,
Siandien darbe mum su kolega kilo diskusija iskilus problemai kai bandem ‘pakist’ lambda israiska i metoda, kuris tikejos function pointer’io. Funkcijos struktura buvo aprasyta su typedef, o pati funkcija buvo reikalinga sortingui atlikti CListBox klaseje (ar kazkam ten pan). Beda yra ganetinai akivaizdi: kam ten apsirasinet papildoma struktura jei butu galima paprasciausiai pakist reiksmes su lambda ir butu kaip ir problem solved.. Daug maziau kodo, kompaktiskai atrodo. Lambdos bei anonimines funkcijos pagal mane isvis yra god send dalykas, labai fun kad jis pasieke ir C++
Vienu zodziu sitas visas reikalas mane ganetinai sudomino, tad nutariau apie tai papostint bei nuodugniau cia viska patyrineti.
Googlinant pavyko issiaiskint kad VC 10 (yep, cia kalba eina apie Visual C++ kompiliatoriu) nepalaiko lambda funkciju konvertavimo i funkciju pointerius :/ Panasu, kad tai ale buvo pakeitimas, kuris nespejo ieiti i VS 2010 RTM’o versija, taciau dabar yra fixed ir turetu but prieinamas sekancioje versijoje. Na bet pirmai gal pasiziurekim kame cia beda isvis.. Pasirasiau trumpa kodo pvz, kuris atvaizduoja sita problema:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> using namespace std; typedef int (*function)(int, int); static int functionBox(function func) { return func(5, 5); } int main() { cout << functionBox([](int a, int b) -> int { return a + b; }) << endl; // error cout << functionBox([](int a, int b) -> int { return a - b; }) << endl; // error int externalValue = 10; cout << functionBox([=](int a, int b) -> int { return a - b + externalValue; }) << endl; // error cin.get(); return 0; } |
Kaip pazymejau komentaruose, neveikia nei paprastas lambdos pakisimas nei pakisimas su kintamuju capture’inimu. Kaip jau minejau, sitas dalykas turetu but ‘ok’ sekancioje VC versijoje, t.y. 11. Cia ganetinai nesenai kaip tik pasirode Visual Studio 11 Developer Preview.. kas suteike puikia proga paziuret kaip yra istesu. Taigi..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> using namespace std; typedef int (*function)(int, int); static int functionBox(function func) { return func(5, 5); } int main() { cout << functionBox([](int a, int b) { return a + b; }) << endl; // ok cout << functionBox([](int a, int b) { return a - b; }) << endl; // ok int externalValue = 10; cout << functionBox([=](int a, int b) { return a - b + externalValue; }) << endl; // still an error !!! cin.get(); return 0; } |
Nu ir ka.. tikrai veikia! Tik deja be kintamuju capture’inimo :/ (yep, bandziau tiek capture by ref, tiek capure by value). Matyt yra kazkokios problemos sioje vietoje ir neina ju taip paprastai issprest.. Tad nors ir lambdos nuo 11 versijos geriau draugauja su function pointeriais, bet panasu kad cia nera suteikiama visiska laisve, kokios noretusi (bent jau man tai tikrai). Nu aisku reikia nepamirsti, jog pavyzdys bandytas su DEVELOPER PREVIEW versija, gal situacija dar pasikeis isejus RTM’ui (taciau as asmeniskai kazkaip tuom abejoju).
Zinoma, anokia cia problema jei mes galime modifikuoti funkciju aprasus.. pasidarom pvz ten ne typedefed funkcijos parametra o kokio std::function arba panaudojam templates ir bedos kaip nebuta.. Va kaip tai atrodytu su std::function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> #include <functional> using namespace std; static int functionBox(function<int(int, int)> func) { return func(5, 5); } int main() { cout << functionBox([](int a, int b) -> int { return a + b; }) << endl; // ok cout << functionBox([](int a, int b) -> int { return a - b; }) << endl; // ok int externalValue = 10; cout << functionBox([=](int a, int b) -> int { return a - b + externalValue; }) << endl; // ok cin.get(); return 0; } |
Va kaip tai atrodytu su templates (tiek tipo paskelbimas su decltype, tiek paprastas dedukcijos metodas puikiai veikia):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <iostream> using namespace std; template<typename _FuncType> static int functionBox(_FuncType func) { return func(5, 5); } int main() { auto lambda = [](int a, int b) -> int { return a + b; }; cout << functionBox<decltype(lambda)>(lambda) << endl; // ok cout << functionBox([](int a, int b) -> int { return a - b; }) << endl; // ok int externalValue = 10; cout << functionBox([=](int a, int b) -> int { return a - b + externalValue; }) << endl; // ok cin.get(); return 0; } |
Taigi, kaip matom – alternatyvu tikrai yra. Taciau deja, ne viska galima taip paprastai pamodifikuot..o kai kur net isvis priejimo nera (pvz jei naudoji kokia lib kurios sources neturi). Bet vistiek smagu kad progresas sioje vietoje yra bei kad C++ irgi sulaukia tinkamo demesio ir naujoviu, o ne tik pvz C# (kuris atrodo kad populiareja su kiekviena diena). Kitas dalykas – zinoma ne gyvybes ir mirties klausimas cia sitokio funkcionalumo palaikymas, tad kai kurie turbut drasiai numotu ranka i visa si reikala ir verstusi be to. Bet.. na, cia kaip kam
Savaites geriausi track’ai (52) + darbo planas
Sveiki,
Kazkaip visai ner apie ka rasyt pastaruoju metu..tad blog’as daugiau ar maziau yra apmires.. deja. Yra minciu porai projekteliu bet atvirai pasakius nelabai yra jiem laiko tad taip viskas ir stovi vietoje
Isduosiu paslapti – ruosiuos perdaryt per nauja mano siektiek kreiva 3D engine (jam reik gan didelio overhaul norint ji paverst kazkuom isties naudingu), kuri naudojau magistriniam darbe. Perdarinesiu su tikriausiai vel gi ant C#, tik si kart naudosiu SharpDX o ne SlimDX, nes tas variantas mazesni overhead uzdeda permetant viska i native code ir atgal. Pirmai masciau daryt grynai su C++, bet kazkaip man gaila savo laiko. Kita vertus megstu C++ nes pilnai kontrolioju tai, kas vyksta.. tuo tarpu kai C# buna trashina atminti arba ne laiku sumasto prasukti GC. Ir overall, C++ zymiai greitesnis daiktas. Na bet.. .NET ir C# dbr smarkiai juda i prieki ir atsisakyt tokiu stipriu tools’u del nelabai didelio performance hit’o man kazkaip nesinori.. Todel ir linktu kolkas prie C#’inio varianto. SharpDX aplamai atrodo kolkas lb neblogai tad bus galima isbandyt jegas prie sito daikto pasitaikius palankiai progai.
Taigi is esmes kolkas galiu Jus nudziugint tik trance muzikos doze, vis sis tas
Klausom ir miegaujames…
Savaites geriausi track’ai (51)
Sveiki gyvi,
Tesiu jau iprasta visiems rubrika.. Taigi, be jokio tusciazodziavimo siulau pasiklausyti geros muzikos ir pasikelti nuotaika sau ir/ar aplinkiniams
Savaites geriausi track’ai (50)
Sveiki,
Manau jau prikaupiau pakankamai nemazai nauju ar tiesiog seip geru dainu/kuriniu, tad pats laikas jais pasidalinti su Jumis. Kaip ten bebutu, visgi tai 50-imtas “Savaites geriausiutrack’u” rubrikos leidinys, tad jis privalo buti bent kazkuom ypatingas
Tikiuosi, kad rasit cia kazka gero, kas bent biski praskaidrins ta rutinini gyvenima.
Go!
Read more
Chess Horse Puzzle Solver
Sveiki,
Jau senokai vis ruosiaus parasyt apie viena dalyka..bet niekaip nebuvo laiko/noro ir t.t. Taigi va pagaliau prisiruosiau
Ok.. visu pirma tai turbut daug kam nlb aisku prie ko cia tas toks post’o pavadinimas..
Tuoj viskas paaiskinsiu. Na seip dauguma, kas gaudos anglu kalboje, jau turbut suprato kas cia mazdaug yra..bet jauciu dar neaisq kas cia per puzzle ir prie ko cia chess
Taigi, neskubam, viskam savo laikas.
Cia pries kelias sav rasinejaus per Skype su vienu draugu ir kazkaip netyciom kalba uzklido apie visokius game puzzles ir pan dalykus. Jis man papasakojo kad viena kart per kazkoki game jam reikejo issprest viena puzzle, kurioje yra duotas tuscias chess (sachmatu) laukas ir zirgas. Uzduotis yra tokia, kad pradejus is tam tikro langelio, reik aplankyt visus chess board’o laukus po karta (t.y. negalima ant vieno lauko atsistoti du kartus). Na manau zinot kaip zirgas sachmatuose vaiksto..tad cia tikrai nera taip simple kaip atrodo
Jis dar pasake kad kazkaip jam ten irgi nesigavo tada paprastu budu sios mysles imint ir kazkuris jo pazistamas pasikodino jam app, skirta siai problemai spresti. Na..mane pati irgi jau tada sudomino sitas uzdavinys..tad apsiemiau parasyt programke jam spresti
Ka kita diena ir padariau…
Na o gavosi stai kas (kaireje – screen’as tik paleidus app, desineje – kai problema jau yra isspresta):

Is esmes uztrukau apie 3.5 h prie sito daikto (~400 eil. gavos), o kuriau ji su C#. Tuoj papasakosiu siektiek apie technine jo puse, jei kam idomu – galit pasiskaityt. Is esmes skaiciavymai yra vykdomi su rekursine funkcija (pasirenkau toki approach del to kad is esmes, bunant bet kuriam langelyje, galimi veiksmai, kurios reik atlikt, lieka tie patys). Galimi veiksmai (ivairus ejimai) is kiekvieno langelio sio atveju yra 8. Taigi patekus pvz i tam tikra langeli yra bandoma atlikti 8 zirgo ejimo variantus (is eiles, masciau gal padaryt kad random tvarka bandytu..4fun, bet taip ir nepadariau
). Ju eigoj yra tikrinama ar tas ejimas nebus uz lentos ribu bei ar tas lengelis jau nera aplankytas. Fail atveju yra bandomas kitas ejimo variantas.. Jeigu gaunas, kad tas langelis isvis yra FAIL (negalima niekur is jo nueit) – sokama per viena rekursijos lygi atgal (i langeli, is kurio buvo patekta i si konkretu langeli) ir ten yra bandomi kiti ejimo variantai. Jei langelis OK (dar neaplankytas is yra ant lentos) – sokama vienu rekursijos lygiu gylyn ir ten jau yra atliekami visi sie aprasyti veiksmai. Tiesa, kiekviename rekursijo lygyjy yra pasidaroma board’o ir praeito path’o kopijos, kad negadint duomenu, kuriais buvo vadovaujamsi kai buvo keliaujama iki sio konkretaus langelio. Yep, efektyvumo prasme cia biski.. shit
be to app su C# ir ta vieta tikrai nedziugina performance’o, beet..pasistengiau maksimaliai ja optimizuot.
Is esmes dar norejau implementuoti multithreading’a, taciau patingejau.. tad dbr viskas sukas ant 1 core
na bet savo darba atlieka. Tiesiog tenka biski ilgiau palaukt. Tiesa, cia visgi yra 2 thread’ai: 1 UI, ir 1 skaiciavimams. Taciau toki dalyka neskaitau realiu multithreading’u, nes is to negaunama jokia nauda skaiciavimams. Cia tiesiog seip..kad kol skaiciuoja nelagintu UI. Beveik visur taip darau kur tik atsiranda kokie nors rimtesni skaiciavimai
Beje siame app’e dar yra galimybe vizualiai perziureti nueita kelia.. (playback mygtukas, matosi screen’uose). Ten tiesiog pereina per visa path atzymint langelius ekrane kas 500ms. Nieko blatno. Tas board’o langelis tai paprastas Panel su overridintom piesimo funkcijom tam ispiest lauka ir nuspalvint reikiamus langelius ir tiek. Simple bet patraukliai atrodo
Atrodo tiek apie sia maza app. Visa kita aisq is UI. O ir beabejo imesiu parsisiuntimo linka.. tad galesit pasiziureti patys (jei kam bus idomu). Tiesa, ten v1.1 dbr.. tas .1 prisimete snd (realizavau veiksmu Stop galimybe). Pries tai vienintelis budas cancel’inti buvo uzdaryt app langa (cia tuo atveju kai uzknisa laukt rezultato.. ar seip..nervai nelaiko
). Tuo atveju irgi viskas ten graziai numirsta ir procesas dingsta, na bet su Stop mygtukais yra idomiau
Taigi.. gal kam pravers, tad siulau atsisiunti ir issibandyti Chess Horse Puzzle Solver (tiesa, reikia tureti isirasius .NET 4.. nieko as ten is to 4 nenaudoju, na bet buildinu by default viska jam ir tiek
). Tikiuosi, kad kamnors buvo idomu
Gaila kad pastaruoju metu nlb daug yra laiko, kuri galeciau skirti 4fun programavimui :/
Savaites geriausi track’ai (49)
Pagaliau pribrendo siu keliu savaiciu geriausiu trance ir kitu pan zanru kuriniu sarasas, kuriuo ir skubu pasidalinti..
No comments
Judam i prieki
Sveiki,
Gal yra tokiu kas pasigedo manes.. tai skubu pranesti jog vis dar esu gyvas
Tiesiog pastaruoju metu nelabai yra apie ka rasyti, tad blogas ir merdi.. Nu zinoma, kaip ten bebutu (nors ir su lagais) bet tesiu ta ‘Savaites geriausiu tracku’ post’u serija, kurioje jau irgi greit bus imesta nauja dalis
Jau kaip ir issilaikiau ta savo vargana magistra, viskas ten buvo nice.. ir net pasiemiau diploma su pagyrimu
vot kaip!
Po siu dziugiu ivykiu ieskojau darbo ir ji radau. Dar kolkas tik nzn kaip cia man viskas ten seksis, bet vnz nuo ateinancio pirmadienio pradedu dirbti va cia C++/C# developeriu. Aplamai pastaruoju metu tiesiog bandziau turiningai pailseti arba pasvesti, kad bent kiek pajust ta vasaros skoni nes jo jau tuoj nebeliks kada ragaut. Dar siektiek pavirsutiniskai pasigilinau i WPF, WCF ir ASP.NET (cia .NET technologijos) kad tas praejes laikas visai nebutu ismestas veltui. Zinoma, kadangi dabar yra vasara – tai ir namie ir prie ju tenka papluset karts nuo karto, tad ir tai atima biski laiko. Vnz ziuresiu kaip cia viskas eis..gal ir bloge pradesiu daugiau rasyt jei tik bus apie ka
Taip ir gyvenu.. kolkas gyvas, ir drasiai su pakelta galva zengiu toliau i sekanti gyvenimo etapa

