Не отпускает меня эта[1][2] вычислительная задачка. Нафигачил её теперь на js. С блэкджеком и шлюхами Web workers. В итоге получилось около 40 секунд(в Chrome) — быстрее чем нативный код (сгенерированный gcc-4.4 с -O3) в один поток! Выложена на GitHub Pages. Файл с исходными данными.
Пример функции на C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
double F(int number_of_equation, double time, double y[DIM], double G){//Right-hand of dynamical system double value; switch (number_of_equation) { // RIGHT-HANDS OF DIFFERENTIAL EQUATIONS SYSTEM: /* If You have another dimention (DIM is define in "#define DIM YOU_DIM_NUMBER") of system then add or remove your equations*/ case 0: /* First equation */ value = y[1]*(1/C2-cos(y[0])*cos(y[0])/(A1+B2)-sin(y[0])*sin(y[0])/(A1+A2))-DELTA/C2-eps/C2/nu*sin(nu*time); break; case 1: /* 2_equation */ value = -(G*G-y[1]*y[1])*(1/(A1+A2)-1/(A1+B2))*sin(y[0])*cos(y[0]); break; // default: value=0; break; } return value; } |
Та же функция на javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function F(number_of_equation, time, y, G) {//Right-hand of dynamical system var value; switch (number_of_equation) { // RIGHT-HANDS OF DIFFERENTIAL EQUATIONS SYSTEM: /* If You have another dimention (DIM is define in "#define DIM YOU_DIM_NUMBER") of system then add or remove your equations*/ case 0: /* First equation */ value = y[1]*(1/C2-Math.cos(y[0])*Math.cos(y[0])/(A1+B2)-Math.sin(y[0])*Math.sin(y[0])/(A1+A2))-DELTA/C2-eps/C2/nu*Math.sin(nu*time); break; case 1: /* 2_equation */ value = -(G*G-y[1]*y[1])*(1/(A1+A2)-1/(A1+B2))*Math.sin(y[0])*Math.cos(y[0]); break; // default: value=0; break; } return value; } |
Как видим, изменений практически нет.
Ну и пара слов о Web Workers. Работа с ними организована примерно так:
Запуск:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
for(var i = 0; i < 4; i++){ var input = new Object(); //fill input myWorkers[i] = new Worker("worker.js"); myWorkers[i].onmessage = function (oEvent) { if(task_exists){ //fill inp myWorkers[oEvent.data.thread].postMessage(inp); } //postprocess output data }; myWorkers[i].postMessage(inp); } |
Сам Worker:
1 2 3 4 |
//process definition self.onmessage = function(e) { self.postMessage(process(e.data)); }; |