Коды С++ и Haskell отличаются временем выполнения на разных машинах

Я хочу спросить вас, что может вызвать эту разницу. Если я скомпилирую следующие программы и запустил ОДИНАКОВЫЕ БИНАРЫ - на некоторых платформах результат, полученный в результате кода С++, намного быстрее, чем у Haskell, в противном случае ситуация противоположна.

Дополнительно существует большая разница в производительности финальных бинарных файлов, в соответствии с той платформой, на которой они были построены. (Каждая платформа использует те же флаги и те же версии LVM и clang)

Коды оптимизированы и должны работать с одинаковой производительностью - см.: Может ли Haskell оптимизировать функцию вызова так же, как Clang/GCC делает?.

Я хочу спросить вас, как это возможно.

Код С++:

#include <cstdio>
#include <cstdlib>

int b(const int x){
    return x+5;
}

int c(const int x){
    return b(x)+1;
}

int d(const int x){
    return b(x)-1;
}

int a(const int x){
    return c(x) + d(x);
}

int main(int argc, char* argv[]){
    printf("Starting...\n");
    long int iternum = atol(argv[1]);
    long long int out = 0;
    for(long int i=1; i<=iternum;i++){
        out += a(iternum-i);
    }
    printf("%lld\n",out);
    printf("Done.\n");
}

скомпилирован с clang++ -O3 main.cpp

Код haskell:

module Main where
import qualified Data.Vector as V
import System.Environment
b :: Int -> Int
b x = x + 5
c x = b x + 1
d x = b x - 1
a x = c x + d x
main = do
   putStrLn "Starting..."
   args <- getArgs
   let iternum = read (head args) :: Int in do
      putStrLn $ show $ V.foldl' (+) 0 $ V.map (\i -> a (iternum-i))
         $ V.enumFromTo 1 iternum
      putStrLn "Done."

скомпилирован с ghc -O3 --make -fforce-recomp -fllvm ghc-test.hs

РЕЗУЛЬТАТЫ (тестирование САЙНЫХ двоичных файлов на разных платформах)

// binaries compiled on Ubuntu:
Ubuntu x64 @ Intel i7-3610QM CPU @ 2.30GHz : C++:0.775s, GHC:1.01s
Gentoo x64 @ Intel i7-Q720   CPU @ 1.6GHz  : C++:3.6s,   GHC:2.1s

// binaries compiled on Gentoo:
Ubuntu x64 @ Intel i7-3610QM CPU @ 2.30GHz : C++:0.782s, GHC:1.01s
Gentoo x64 @ Intel i7-Q720   CPU @ 1.6GHz  : C++:2.3s,   GHC:1.3s

Ответ 1

Если я скомпилирую следующие программы и запустил ТЕОРЕМНЫЕ БИНАРЫ - на некоторых платформах результат, полученный в результате кода С++, намного быстрее, чем у Haskell, в противном случае ситуация противоположна.

Дополнительно существует большая разница в производительности финальных бинарных файлов, в соответствии с той платформой, на которой они были построены. (Каждая платформа использует те же флаги и те же версии LVM и clang)

Вы видите влияние назойливых оперативных данных реальных компьютеров:

  • оптимизация компоновщика
  • различные версии динамически загружаемых библиотек
  • качество генерации кода сборки для данной микро архитектуры
  • доступ к специализированным инструкциям
  • размеры кеша
  • планировщик операционных систем, распределитель,...
  • задержки памяти

Там огромное количество кода и оборудования, которые отличаются между двумя платформами, означает, что вы в конечном итоге измеряете разные вещи.

Нет причин ожидать, что производительность будет одинаковой или даже в том же соотношении. Для микро-бенчмарков нет ничего необычного, чтобы переворачивать относительные упорядочения при перемещении платформ.