2013-07-01 42 views
11

Tôi muốn hỏi bạn điều gì có thể gây ra sự khác biệt này. Nếu tôi biên dịch các chương trình sau và chạy THE SAME BINARIES - trên một số nền tảng, kết quả từ mã C++ nhanh hơn nhiều so với Haskell, trên trường hợp khác là ngược lại.Mã C++ và Haskell khác nhau trong thời gian thực hiện trên các máy khác nhau

Bổ sung có sự khác biệt lớn về hiệu suất của các tệp nhị phân cuối cùng theo nền tảng mà chúng được xây dựng trên đó. (Mỗi nền tảng sử dụng cùng một cờ và cùng một phiên bản của LVM và clang)

Mã được tối ưu hóa và sẽ hoạt động với hiệu suất tương tự - xem: Can Haskell optimize function calls the same way Clang/GCC does?.

Tôi muốn hỏi bạn, làm cách nào có thể.

C++:

#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"); 
} 

biên soạn với mã 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." 

biên soạn với ghc -O3 --make -fforce-recomp -fllvm ghc-test.hs KẾT QUẢ

(thử nghiệm những chương trình CÙNG trên nền tảng khác nhau)

// 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 
+3

Đầu ra của trình biên dịch có thể được tối ưu hóa cho các bộ chip khác nhau. Tôi sẽ lặp lại những gì tôi đã nói cho câu hỏi cuối cùng của bạn: kiểm tra đầu ra lắp ráp. – chrisaycock

+0

@chrisaycock Tôi không thấy nhận xét của bạn lần trước - Tôi sẽ làm điều đó –

+14

@ H2CO3: "C++ là một ngôn ngữ được biên dịch, Haskell là một ngôn ngữ được giải thích". Điều này là sai. GHC là một trình biên dịch. Nó tạo ra mã nguồn gốc. Các ngôn ngữ không được giải thích và biên dịch vốn có, nhưng người ta có thể viết một thông dịch viên hoặc trình biên dịch cho bất kỳ ngôn ngữ thực tế nào, kể cả C++. –

Trả lời

16

Nếu tôi biên dịch các chương trình sau và chạy những chương trình CÙNG - trên một số nền tảng một trong những kết quả của C++ là nhanh hơn nhiều so với Haskell một, trên khác tình hình là ngược lại.

Bổ sung có sự khác biệt lớn về hiệu suất của các tệp nhị phân cuối cùng theo nền tảng mà chúng được xây dựng trên đó. (Mỗi nền tảng sử dụng cờ giống nhau và các phiên bản tương tự của LVM và kêu vang)

Bạn đang nhìn thấy tác động của các chi tiết hoạt động pesky của máy tính thực:

  • mối liên kết tối ưu hóa
  • phiên bản khác nhau của thư viện được tải động
  • chất lượng tạo mã lắp ráp cho kiến ​​trúc vi định sẵn
  • truy cập vào hướng dẫn chuyên ngành
  • bộ nhớ cache kích thước hệ thống
  • điều hành lên lịch, cấp phát, ...
  • độ trễ bộ nhớ

Có một số lượng lớn các mã và phần cứng khác nhau giữa hai nền tảng, có nghĩa là bạn kết thúc đo những thứ khác nhau .

Không có lý do gì để mong đợi hiệu suất giống nhau hoặc thậm chí trong cùng một tỷ lệ. Đối với các tiêu chuẩn vi mô, không phải là bất thường khi lật các thứ tự tương đối khi di chuyển các nền tảng.

Các vấn đề liên quan