Emscripten — где производительность?

Вот для простой программки есть исходники на

С++
#include <iostream>

using namespace std;

#include <sys/time.h>
#include <unistd.h>

static double GetMilliseconds(){
	struct timeval time;
	gettimeofday(&time, NULL);
	
	return (time.tv_sec*1000.0 + time.tv_usec/1000.0);
}


int i=0;
int fib(int x) {i++;
  if (x < 2) {
    return 1;
  } else {
    return fib(x - 1) + fib(x - 2);
  }
}


int main() {

double t0 = GetMilliseconds();


int result = fib(35);



double ms = GetMilliseconds()-t0;

cout << "time ms: "<< ms << "res: "<<i<<"-"<<result<<endl;


cin.get();

  return 0;
}


и JS
var i=0;
		function fib(x) {i++;
		  if (x < 2) {
			return 1;
		  } else {
			return fib(x - 1) + fib(x - 2);
		  }
		}
	
    window.onload = function(){


	
      var time = new Date().getTime();

	  
	  var result = fib(35);
		


      document.write(new Date().getTime()-time+"<br>res: "+i+"-"+result);


    }


В основном блоке количество операций идентично

После [сборки и] запуска получаю следующую картину:

  1. pure JS 180-200ms
  2. em++ 500-600ms
  3. em++ -O3 180-200ms
  4. g++ 180-200ms
  5. g++ -O350-60ms


Почему так? Ладно там без -О3 выдает дикие вещи. Но скомпилированный через em++ код далеко от скорости на g++ -O3 и ничем не быстрее чистого JS на том же V8. Причем показатели одинаковы что в FF, что в Chrome.
  • Вопрос задан
  • 349 просмотров
Пригласить эксперта
Ответы на вопрос 2
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Попробовал написать рекурсивный фибоначи на чистом asm.js:
(function(std, env, heap) {
    'use asm';
    function fib(n) {
        n = n|0;
        if((n|0) < (2|0)) {
            return 1|0;
        }
        return (fib((n|0) - (1|0)) + fib((n|0) - (2|0)))|0;
    }
    return fib;
}(
    {},
    null,
    new ArrayBuffer(0)
));

Действительно медленнее чем на js
Причина очевидна: asm.js не оптимизируется никак, это готовые инструкции для виртуальной машины (например v8)
Обычный js перед компиляцией прогоняется через оптимизатор, который успешно преобразует хвостовые рекурсии в цикл

Делаем вывод, emscripten пока не умеет оптимизировать хвостовые рекурсии
И кстати какую опцию оптимизации вы отдавали в em++ ?

P.S. насчет производительности, у меня хэширующий алгоритм (crc64 с солью) после полного переписывания с js на asm.js дал прирост производительности в 21.7 раз (node 6.3.1 v8 5.0.71.57)
Ответ написан
gbg
@gbg Куратор тега C++
Любые ответы на любые вопросы
При таких вопросах надо смотреть ассемблерный листинг. Полагаю, gcc выкинул все вычисления и засадил константу.

Уж рекурсию он точно должен был раскрутить.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы