ное 22 2011

Нуждата от многоядрени процесори

Category: Dev,embedded,НонсенсLucho @ 17:02


Част I

Защо аджеба имаме многоядрени процесори в стандартните персонални компютри?

Не е защото програмите са супер добри в изпълнението на паралелни задачи. Програмите в обикновените компютри не са добри в изпълнението на паралелни задачи, защото хората, които ги пишат рядко измислят паралелни алгоритми за решаването на даден проблем.

Да вземем например процесор с 64 ядра. Всъщност дори и с 64 ядра… имаме 1 шина (северния мост), за достъп до паметта. Как 64 ядра могат ефективно да пишат и четата от паметта? Да не говорим за кеш кохийранс и потенциалните проблеми породени от false sharing-a.

Проблемът на многоядрените процесори са хората-мислещи-последователно-вместо-паралелно-защото-така-са-свикнали и достъпът до споделени ресурси. 64 ядра vs. една памет, един кеш, един кернел… и още много неща, които са по едно. Как 64 неща могат да работят ефективно с едно нещо едновремено и да са в синхрон – това е проблемът.

Защо нямаме едно ядро, което да върви на 64*3GHz?

Много уместен въпрос! Процесор с честота 192GHz звучи като решение на изначалния проблем – Защо да не си караме с едноядрен процесор на супер висока честота?

well…

  • Скоростта на светлината във вакуум е ~300 000 000 м/сек.
  • 192GHz са 192 000 000 000 такта в секунда

Простата сметка 300 000 000 / 192 000 000 000 = 1.5mm , показва че този процесор трябва да е голям около 1 милиметър (кв., куб.), за да може часовникът да разпространи сигнала си в него 192 милиарда пъти в секунда… и това са някакви груби, половинчати сметки. Това, което се опитвам да ви накарам да осъзнаете е че:

  1. Не може да поберете процесор в такова пространство.
  2. Ако поберете процесор в такова пространство ще ви трябва нещо по-студено от течен азот за да го охладите. Ще ви трябва и малка електроцентралка, за да го захраните.
  3. Ако успеете да намерите нещо по-бързо от светлината… good for you!

Част II

Единственият начин да имаме повече изчислителна мощ със сегашните закони на физиката е като имаме повече изчислителни устройства, които работят паралелно. За това си купувате 2-4-8 ядрени процесори на ниска честота (2 GHz).

Но един процес винаги върви на едно ядро – т.е. ако имате един единствен процес и искате да върви бързо, тогава ви трябва едно единствено ядро на висока честота (4 GHz например, вместо 2GHz). Това е миниатюрна частичка от един друг голям проблем – Ако имате програма, която изчислява някакъв резултат за X секунди на процесор с 1 ядро, нямате гаранция че ако пуснете програмата на процесор с 8 ядра със същата честота, тя ще върви 8 пъти по-бързо. Нещо повече, вашата програма може да върви дори по-бавно от колкото на 4 ядра. Т.е. вашият софтуер може да не се скалира добре върху многоядрена архитектура.

Това е като да си хирург в 13-ти век… взимаш някакъв труп и пориш, и изучаваш, и не разбираш, и си блъскаш главата… и след 100-200 години вече всичко е ясно и човечеството вече знае как работи човешкото тяло.

Ние сме в 13-ти век :-)


Етикети: ,


сеп 27 2011

Циганите на сапун!

Category: Нонсенс,СоциалниLucho @ 14:55

Ха-ха! Излъгахте се да кликнете на статията и сега ще четете!

Няма да правя обширен коментар на това, което се случва в последните дни, защото вече има над 9000 такива в мрежата. Ще кажа само няколко неща:

1. Паленето на имущество от разгневена тълпа с вили и факли е демоде… беше интересно през средата на 15-ти век. Както и паленето на вещици.

2. Ултрасите са наркомани и боклуци – нещо като онези „англичани“, които палиха Лондон, но те поне носеха маркови анцузи Adidas (официален спонсор на първенството по подпалвачество).

3. Хората не се раждат расисти, а стават такива. Това, че съществуват много крадливи мангали, не значи че всички цигани или турци или българи са такива, но някак си е по-лесно да набиеш един циганин на улицата отколкото да набиеш един полицай, следовател или съдя, който не е вкарал крадливия мангал в затвора и не си е свършил работата.

4. Запалете всички онези институции, които не си вършат работата, заради които има образи като „цар Киро“ и заради, които хората ще почнат да се избиват един-другиго скоро. Насилието ражда насилие, за това поне да е насочено към истинския корен на проблема.

5. Ако има едно нещо, което трябва да се промени, и то веднага, това е образователната система. Хора, които стават студенти с двойки на кандидат студентските изпити нямат място в университетите. Не може учениците да излизат от училищата без да владеят английски поне на основно ниво. Стъпка по стъпка се приближаваме до нивото на повечето африкански държави.. но за разлика от тях, нашето население не говори френски или английски свободно. И не живеем в затворена икономика вече, че да не ни пука дали ще се разбираме с чужденците.

6. Трябват ни компании, които създават технологии. Няма нужда да са високи технологии. Ако ще да правят резервни части за Опели пак е нещо. Няма как да оцелеем само от туризъм или от земеделие – няма. Няма как да оцелеем и само с рекламаджии, маркетингови експерти и икономисти. За съжаление нямаме и залежи от петрол… само шистов газ. За това трябва да произвеждаме нещо, което физически да може да се пипне и да има стойност, за да може да се продаде и да се получат пари за него. Така работи света.

7. Много е важно бизнеса да преподава в университетите. До там сме я докарали, че академичната общност и бизнеса нямат нищо общо. По-добре да се даде възможност на няколко компании да разработят свои учебни програми, които да се преподават в университетите и поне студентите като завършат ще знаят, къде ще работят и с какво ще се занимават. Съжалявам, но нямаме място за научен развой вече, защото БАН и бизнеса се движат в различни посоки, когато се стигне до развойна дейност. Може би и международните компании ще се поинтересуват от нас като видят, че ще могат да подготвят бъдещите си кадри, а не просто да получават някакви хора с дипломи и съмнителни знания.

Това искам да кажа. Забравете за здравеопазване и пенсионно осигуряване. Не ни се получава да правим нещата паралелно. Дайте поне да направим образованието ефективно, защото без добро образование и технологии не се различаваме особено много от повечето африкански държави…. освен с това че не говорим английски.



сеп 12 2011

IKEA, но в Стокхолм… не в София

Category: НеБългария,СоциалниLucho @ 22:36

Може би не знаете, но от около 3 седмици живея и уча в Стокхолм, Швеция. Накратко – тук е много готино и скъпо. По-скъпо от Германия – факт. Скъпо е но, пък храната в стола на университета всъщност е много по-вкусна от тази в немски стол и безкрайно много по-вкусна от български стол. Накратко искам дакажа, че тук стандарта на живот просто е по-висок.

Днес реших да се разходя до Икеа и да видя аджеба какво толкова интересно има. Имаше доста интересно.

В съзнанието ми Икеа винаги е било синоним на безбожно скъпи мебели, които са за западно европейската или американската средна класа. За това са виновни учебниците ми по немски в 8-ми клас и Fight Club. Оказа се, че мебелите не са скъпи и че ако не друго поне изглеждат добре и се комбинират добре.

Като казвам, че мебелите не са скъпи може да не ми се доверявате напълно, защото почти не съм влизал в български мебелен салон и никога не съм се вълнувал от цени. Не знам дали е нормално кожен диван да струва 600 евро например.

Както и да е направих малко снимки с ужасно качество, но поне се виждат цени (цените са в шведски крони – 10 крони = 1.15 евро):

Не особено скъпа кухня за 10000 крони (без техниката). Ако искате и вградената техника – още 9000 крони. Сумарно – 2200 евро.

Готина кухня – 23000 крони, ако искате и вградената техника + 21000 крони. Сумарно отива към 5000 евро.

Не се залъгвайте по снимките. Шкавчетата тук не са просто дърво с рафтове. Икеа си разбират от работата и пространството е добре измислено. Това, което прилича на тясно, обикновено шкафче, всъщност може да е високо чекмедже, което да се плъзга плавно и в което да си държите тенджерите например.

За да не съм голословен и да видите, че пространството наистина се използва добре ето и нещото, което ми хареса най-много (и снимката стана възможно най-скапана :( ):

 

Това е гардероб. Бтв, на шведски гардероб си се казва „гардероб“ :D. Имаш място за обувки, за костюми, малко чекмеджета и едни черни неща, които са кутии от плат/картон в които може да си слагате каквото ви скимне. Цената на всяко от четирите крила е около 1700 крони. Т.е. сумарната цена е около 7000 крони или около 800 евро. Не е много евтино, а?!

Не особено красивите дивани почват от 330 евро и в зависимост от размера достигат до към 1200 евро. Диван с табуретки излиза майка си и баща си в общи линии, но не обърнах особено внимание на холни обзавеждания.

Евтин стол за около 70 евро – от опит знам, че тези столове се разпадат след 3-4 години ползване и вероятно, може да си намерите такъв от Mr.Bricoladge за 100-и-нещо лева.

Доста окей стол за 200 евро.

В Икеа няма кой знае какви столове… или поне аз не видях.

PS3 + Табло за проверка на зрението :D

Шкафовете до стената са 4550 крони, дивана е 7300 крони, шкафовете зад дивана са 2200 крони и масата отпред е 1000 крони. Всичко – 15050 крони или около 1700 евро. Хм, не изглежда толкова много.

В Икеа имаше и много дреболии на ниски цени – чаши, закачалки, лампи за под 10 крони, 10 батерии за 17 крони.

Настолна лампа за 9 евро.

Лампа със соларен панел…

В Икеа им и шведски ресторантчета и закусвални. Кафе и канелена сладка за 5 крони… в Швеция трудно може да си намерите кафе за по-малко от 10 крони.

И понеже почна да се шуми, че мебелите от Икеа в България ще са по-скъпи от Икеа магазините в други държави, си взех шведски каталог на Икеа за 2012. Може да ме питате за цени ако искате :)

 


Етикети: ,


юли 24 2011

Game of Life (javascript + html5’s canvas)

Category: Dev,HTML5,WebLucho @ 23:55

Тези дни отново ме загриза съвестта, че не работя по някакъв сайд-проект – мой собствен или open source и за това днес реших да почета и понапиша Game of Life.

Оказа се доста прост алгоритъм с доста интересна история, която и сами може да си прочетете :-)

Демо може да видите тук: http://dailyffs.com/life/

Сорсът е тук: https://gist.github.com/1102964

Коментарът към сорса от страна на @skanev е тук: https://twitter.com/skanev/status/95213748092026880

Това, което искам да кажа в тази статия е, че колкото и да са бързи съвремените Javascript engine-и и колкото и разни светила и икони на браузър вендорите да се хвалят, че производителността скача многократно от версия до версия, това не значи че не може да забързате всичко още малко много. Цената на „забързването“ е „угрозняване“ и оптимизиране на кода. В моя конкретен случай – на една функция, която се вика 60000 пъти на преизчисление.

Въпросната фунцкия:


function getLiveNeighbours(id, data) {
  var x = id % canvas.width;
  var y = parseInt(id / canvas.width);

  var cnt = 0;
  for (var i = -1; i < 2; i++) {
    for (var j = -1; j < 2; j++) {
      if ((i != 0 || j != 0) &&
        !(x+i < 0 || x+i >= canvas.width || y+j < 0 || y+j >= canvas.height) &&
        data.data[4*((y+j)*canvas.width+(x+i))] != THE_BLACK) {
        cnt++;
      }
    }
  }
  return cnt;
}

Простата оптимизация на кода включва:

  1. Премахване на извикването на функцията (тялото на функцията се ползва директно) – спестява 60000 извиквания и времето за изпълнение на една итерация пада от 500ms на 270ms
  2. Заменяне на двата вложени цикъла проверяващи за броя на съседни клетки – от 270ms на 150ms
  3. Опростяване на пресмятанията (премахване на умножения) – от 150ms на 60ms
  4. Създаване на локални референции към често използваните данни (вместо постоянни извиквания от типа „obj.data“ при изчисленията се създава и използва локална променлива) – от 60ms на 50ms
// (4)
var width = canvas.width*4;
var d = data.data;
var nd = newdata.data;
var cw = canvas.width;
var ch = canvas.height;
var base = 0;

for (var i = 0; i < d.length/4; i++) {
  var x = i % cw;
  var y = parseInt(i / cw);

  var cnt = 0;
  // (1), (2), (3)
  if (x > 0 && d[base-4] != THE_BLACK) cnt++;
  if (x < cw-1 && d[base+4] != THE_BLACK) cnt++;
  if (x > 0 && y > 0 && d[base-4-width] != THE_BLACK) cnt++;
  if (y > 0 && d[base-width] != THE_BLACK) cnt++;
  if (x < cw-1 && y > 0 && d[base+4-width] != THE_BLACK) cnt++;
  if (x > 0 && y < ch-1 && d[base-4+width] != THE_BLACK) cnt++;
  if (y < ch-1 && d[base+width] != THE_BLACK) cnt++;
  if (x < cw-1 && y < ch-1 && d[base+4+width] != THE_BLACK) cnt++;
  ...

В крайна сметка производителността скочи 10 пъти, макар логиката на кода да изглежда по-зле от преди. Не, че преди изглеждаше много красива, но все пак :D

Разбира се има и още един доста по-умен начин за техническа оптимизация – Web Workers. Те са панацеята на всички проблеми, началото и края, давид и голиат, содом и гомор, ин и ян… за тях може да почетете тази статия - Mandelbrot + Web Workers

Забележка:

  • става дума за проста техническа оптимизация на кода, а не за подобрения на алгоритъма!
  • вероятно оптимизациите в javascript engine-ите не се фокусират върху случаи на извикване на функция 60 хиляди пъти… а би трябвало.

Етикети: , , ,


юли 23 2011

Прозрение

Category: Dev,WebLucho @ 15:17

Преди няколко дни започнах да пиша малко плъгинче (първия ми плъгин акшуъли) за Django, което да филтрира браузъри в зависимост от useragent-а им. Идеята ми беше филтрирането да става в зависимост от версията на браузъра… идея, която работеше преди 5 години. Останах си с тази идея до момента, в който видях няколко useragent-a от мобилни устройства и таблети. Накратко един с един нямат общо, но това което си остава при всички е версията на layout engine-a.

Това е хора. Забравете за IE X или Firefox Y и  т.н., това което ще направи сайта ви да работи на десктоп, телефон и таблет е версията на layout engine-a в комбинация с данните от тези таблички: http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29 и http://caniuse.com/

 

 



юли 14 2011

Upload на blob като файл чрез AJAX

Category: Dev,WebLucho @ 10:10

Заглавието и на мен не ми говори нищо, за това ще се опитам да обясня с прости думи казуса.

Наскоро забелязах, че при изпращането на голям скрийншот в http://screenshoot.me се случват някакви неприятни неща. По-точно грешка 413 Request entity too large. Оказа се, че хостингът ми не позволява изпращане на POST заявки с параметри по-големи от 1-2мб. За сметка на това пък позволява качване на файлове до 20мб. До тук единственото нещо, което ме притесняваше е дали може да „симулирам“ изпращане на файл чрез AJAX. Оказа се че може. FUCK YEAH!

Всъщност може да си префасонирате цялата заявка както ви скимне, което е много готино и същевремено много жалко, защото десетките хиляди фронт-енд дивелъпъри, ползващи jQuery и нямащи понятие от javascript никога няма да узнаят за този факт.

Вероятно бъркам, просто се опитвам да си обясня защо на всяко интервю винаги питат „а ти с jQuery знаеш ли как да работиш“ все едно манюъла е 500 страници и ти трябва висше :).

Та реших да разширя леката библиотечка („парче код“ е правилната дума), която ползвам за AJAX обаждания и съответно резултата е тук – https://github.com/lucho870601/ajax-blob-upload

Накратко:

jx.generateBoundary = function(fieldsData) { // Функция, която генерира уникален разделител валиден за всеки фрагмент
  var boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
  for (var i = 0; i < fieldsData.length; i++) {
    if (fieldsData[i].indexOf(boundary) > -1) {
      // generate new boundary and check all fields again
      boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
      i = 0;
    }
  }
  return boundary;
};

jx.loadFile = function(url, fileData, fileName, callback, opt) {
  var http = this.init(); //The XMLHttpRequest object is recreated at every call - to defeat Cache problem in IE
  if(!http||!url) return;
  var parts = url.split('?');
  var url = parts[0];
  var parameters = parts[1] ? parts[1].split('&') : [];

  var fieldsData = [fileData];
  for (var i = 0; i < parameters.length; i++) {
    fieldsData.push(parameter[i][1]);
  }

  var boundary = this.generateBoundary(fieldsData);
  var body = '';
  for (var i = 0; i < parameters.length; i++) {
    // строим фрагментите за данни
    var p = parameters[i].split('=');
    body += "--" + boundary + "\r\n\
Content-Disposition: form-data; name='"+p[0]+"'\r\n\
\r\n\
"+(p[1] || '')+"\r\n";
  }

  // фрагмента за псевдо-файла
  body += "--" + boundary + "\r\n\
Content-Disposition: form-data; name='" + fileName + "'; filename='" + fileName + "'\r\n\
Content-Type: application/octet-stream\r\n\
\r\n\
"+ fileData + "\r\n\
--" + boundary + "--\r\n";

  http.open("POST", url, true);
  http.setRequestHeader("Content-Type", "multipart/form-data; boundary="+boundary);
  http.setRequestHeader("Content-Length", body.length);
  http.setRequestHeader("Connection", "close");
  ...
  http.send(body);
};

… и получавате данните си като файл накрая.

Кофтито в цялата история е, че не мога да убедя браузъра ми да не слага „charset“ и вероятно заради това blob-а пристига в съвсем друг вид. За това пък решението е доста лесно – кодиране на бинарните данни в base64. Неприятно е, че request-а ще набъбне с 1/3 повече и ще трябва да отворите и decode-нете файла сами. На теория декодирането на файла трябва да стане автоматично с Content-Transfer-Encoding директива, но на практика не стана :D

Удачно е да ползвате този подход не само при гореописания проблем, но и винаги, когато пращате индустриални количества бинарни данни, защото получаването на файл е по-бързо и ангажира по-малко ресурси отколкото получаването на данните като параметър.  Поне така ми се струва :-P

П.П. Преди да имплементирам алтернативното решение се помъчих да увелича лимита на размера на POST заявките с конфигуриране на .htaccess и ini_set на разни магически PHP параметри, но непотръгна.


Етикети: , ,


юли 08 2011

Software Engineering != Software Development

Category: DevLucho @ 17:27

Ще ви го повторя 50 пъти, пък дано отворите wikipedia най-накрая

Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development
Software Engineering != Software Development

Етикети: ,


« Предишна страницаСледваща страница »