Là Fortran dễ dàng tối ưu hóa hơn C cho các tính toán nặng?


410

Thỉnh thoảng tôi đọc rằng Fortran là hoặc có thể nhanh hơn C để tính toán nặng. Điều đó có thực sự đúng không? Tôi phải thừa nhận rằng tôi hầu như không biết Fortran, nhưng mã Fortran tôi đã thấy cho đến nay không cho thấy rằng ngôn ngữ có các tính năng mà C không có.

Nếu đó là sự thật, xin vui lòng cho tôi biết tại sao. Xin đừng nói với tôi ngôn ngữ hoặc lib nào tốt cho việc bẻ khóa số, tôi không có ý định viết một ứng dụng hoặc lib để làm điều đó, tôi chỉ tò mò.


53
Không thực sự chủ quan từ các câu trả lời dưới đây. Tiêu đề chính xác là "Có bất kỳ lý do kiến ​​trúc cơ bản nào tại sao trình biên dịch Fortran MIGHT tạo ra mã tối ưu hóa tốt hơn trình biên dịch C" nhưng đó chỉ là cách chọn nit.
Martin Beckett

3
Câu hỏi tiêu đề không quá chủ quan vì nó là một sự hiểu lầm, tôi nghĩ. Câu hỏi chi tiết hơn là không chủ quan.
jfm3

1
Tôi không nghĩ ai sẽ học được nhiều điều từ điều này ngoài câu trả lời là "Có" và "Không" cùng một lúc, và thay đổi dựa trên trình biên dịch, nguồn, CPU, bố cục bộ nhớ, v.v. Ngáp.
dùng7116

1
Tôi không nghĩ rằng câu hỏi hoặc câu trả lời là chủ quan. Nhưng nếu bạn nghĩ rằng lá cờ này giúp được bất cứ ai, tôi sẽ ổn với nó.
quinmars

2
@sixlettervariabled mặc dù bạn và tôi đã biết câu trả lời, đó là một câu hỏi xảy ra với hầu hết mọi người sớm trong sự nghiệp của họ và điều quan trọng là phải hiểu câu trả lời. Thay vì đăng một bình luận bác bỏ tại sao không tìm thấy câu trả lời mà bạn đồng ý và đưa ra +1
MarkJ

Câu trả lời:


447

Các ngôn ngữ có bộ tính năng tương tự. Sự khác biệt về hiệu suất xuất phát từ việc Fortran nói rằng răng cưa không được phép, trừ khi sử dụng câu lệnh THIẾT BỊ. Bất kỳ mã nào có bí danh đều không hợp lệ, Fortran, nhưng tùy thuộc vào người lập trình và không phải là trình biên dịch để phát hiện các lỗi này. Do đó, trình biên dịch Fortran bỏ qua các bí danh có thể có của con trỏ bộ nhớ và cho phép chúng tạo mã hiệu quả hơn. Hãy xem ví dụ nhỏ này trong C:

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

Chức năng này sẽ chạy chậm hơn so với đối tác Fortran sau khi tối ưu hóa. Tại sao như vậy? Nếu bạn viết các giá trị vào mảng đầu ra, bạn có thể thay đổi các giá trị của ma trận. Rốt cuộc, các con trỏ có thể chồng lên nhau và trỏ đến cùng một đoạn bộ nhớ (bao gồm cả intcon trỏ!). Trình biên dịch C buộc phải tải lại bốn giá trị ma trận từ bộ nhớ cho tất cả các tính toán.

Trong Fortran trình biên dịch có thể tải các giá trị ma trận một lần và lưu trữ chúng trong các thanh ghi. Nó có thể làm như vậy bởi vì trình biên dịch Fortran giả định các con trỏ / mảng không trùng nhau trong bộ nhớ.

May mắn thay, restricttừ khóa và răng cưa nghiêm ngặt đã được đưa vào tiêu chuẩn C99 để giải quyết vấn đề này. Nó cũng được hỗ trợ trong hầu hết các trình biên dịch C ++. Từ khóa cho phép bạn cung cấp cho trình biên dịch một gợi ý rằng lập trình viên hứa rằng một con trỏ không bí danh với bất kỳ con trỏ nào khác. Bí danh nghiêm ngặt có nghĩa là lập trình viên hứa rằng các con trỏ thuộc loại khác nhau sẽ không bao giờ trùng nhau, ví dụ như double*sẽ không trùng lặp với một int*(với ngoại lệ cụ thể char*void*có thể trùng lặp với bất cứ điều gì).

Nếu bạn sử dụng chúng, bạn sẽ nhận được cùng tốc độ từ C và Fortran. Tuy nhiên, khả năng chỉ sử dụng restricttừ khóa với các chức năng quan trọng về hiệu suất có nghĩa là các chương trình C (và C ++) an toàn hơn và dễ viết hơn. Ví dụ, hãy xem xét mã Fortran không hợp lệ : CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30), mà hầu hết các trình biên dịch Fortran sẽ vui vẻ biên dịch mà không có bất kỳ cảnh báo nào nhưng đưa ra một lỗi chỉ xuất hiện trên một số trình biên dịch, trên một số phần cứng và với một số tùy chọn tối ưu hóa.


26
Tất cả đều đúng và hợp lệ, jeff. Tuy nhiên, tôi không xem xét việc "giả sử không có răng cưa" an toàn. Nó có thể phá vỡ mã được kế thừa từ các dự án khác theo những cách tinh tế đến mức tôi không muốn sử dụng nó. Tôi đã trở thành một nazi hạn chế vì lý do đó :-)
Nils Pipenbrinck

3
Đến điểm thứ hai của tôi, bạn không phải sử dụng công cụ biên dịch không có bí danh. Chỉ cần viết mã để tải dựa trên con trỏ được gán vào một biến tự động trước và sau đó làm việc với tự động hóa từ đó. Nó sẽ trông dài dòng hơn, nhưng nó sẽ tối ưu hóa hoàn hảo bởi trình biên dịch.
Cao Jeff

33
Một ví dụ điển hình là sự tồn tại đơn thuần của memcpy () so với memmove (). Không giống như memcpy (), memmove () đối phó với các vùng chồng lấp, do đó memcpy () có thể nhanh hơn memmove (). Vấn đề này là lý do đủ để ai đó bao gồm hai chức năng thay vì một chức năng vào thư viện tiêu chuẩn.
jfs

12
Tôi nghĩ đó là quan điểm của Sebastian - vì sự phức tạp / linh hoạt của việc xử lý bộ nhớ C, thậm chí một thứ đơn giản như bộ nhớ chuyển động là khó khăn.
Martin Beckett

3
call transformVí dụ của bạn không có nhiều ý nghĩa.
Vladimir F

163

Vâng, vào năm 1980; vao năm 2008? phụ thuộc

Khi tôi bắt đầu lập trình một cách chuyên nghiệp, sự thống trị tốc độ của Fortran chỉ là thử thách. Tôi nhớ đã đọc về nó trong Tiến sĩ Dobbs và nói với các lập trình viên lớn tuổi hơn về bài báo - họ đã cười.

Vì vậy, tôi có hai quan điểm về điều này, lý thuyết và thực tế. Về lý thuyết, Fortran ngày nay không có lợi thế nội tại đối với C / C ++ hoặc thậm chí bất kỳ ngôn ngữ nào cho phép mã lắp ráp. Trong thực tế, Fortran ngày nay vẫn được hưởng những lợi ích của di sản lịch sử và văn hóa được xây dựng xung quanh việc tối ưu hóa mã số.

Cho đến và bao gồm cả Fortran 77, các cân nhắc về thiết kế ngôn ngữ đã được tối ưu hóa làm trọng tâm chính. Do trạng thái của lý thuyết và công nghệ trình biên dịch, điều này thường có nghĩa là hạn chế các tính năng và khả năng để cung cấp cho trình biên dịch những bức ảnh tốt nhất trong việc tối ưu hóa mã. Một sự tương đồng tốt là nghĩ về Fortran 77 như một chiếc xe đua chuyên nghiệp hy sinh các tính năng cho tốc độ. Ngày nay trình biên dịch đã trở nên tốt hơn trên tất cả các ngôn ngữ và các tính năng cho năng suất lập trình viên được đánh giá cao hơn. Tuy nhiên, vẫn có những nơi người dân chủ yếu quan tâm đến tốc độ trong điện toán khoa học; những người này rất có thể đã được thừa hưởng mã, đào tạo và văn hóa từ những người mà chính họ là lập trình viên của Fortran.

Khi một người bắt đầu nói về tối ưu hóa mã, có nhiều vấn đề và cách tốt nhất để cảm nhận điều này là ẩn giấu nơi mọi người có công việc là có mã số nhanh . Nhưng hãy nhớ rằng mã nhạy cảm nghiêm trọng như vậy thường chỉ là một phần nhỏ trong các dòng mã tổng thể và rất chuyên biệt: Rất nhiều mã Fortran cũng "không hiệu quả" như nhiều mã khác trong các ngôn ngữ khác và thậm chí không được tối ưu hóa một mối quan tâm chính của mã như vậy .

Một nơi tuyệt vời để bắt đầu tìm hiểu về lịch sử và văn hóa của Fortran là wikipedia. Mục nhập Fortran Wikipedia là tuyệt vời và tôi rất đánh giá cao những người đã dành thời gian và nỗ lực để làm cho nó có giá trị cho cộng đồng Fortran.

(Một phiên bản rút gọn của câu trả lời này sẽ là một nhận xét trong chủ đề xuất sắc được bắt đầu bởi Nils nhưng tôi không có nghiệp lực để làm điều đó. nội dung thông tin và chia sẻ trái ngược với cuộc chiến nảy lửa và sự cố chấp ngôn ngữ, đó là trải nghiệm chính của tôi với chủ đề này. Tôi bị choáng ngợp và phải chia sẻ tình yêu.)


1
liên kết: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/ không còn hoạt động. Có một liên kết thay thế?
nathanielng

64

Ở một mức độ nào đó, Fortran đã được thiết kế để giữ cho tối ưu hóa trình biên dịch. Ngôn ngữ hỗ trợ toàn bộ hoạt động mảng nơi trình biên dịch có thể khai thác song song (đặc biệt trên bộ xử lý đa lõi). Ví dụ,

Phép nhân ma trận dày đặc chỉ đơn giản là:

matmul(a,b)

Định mức L2 của vectơ x là:

sqrt(sum(x**2))

Ngoài ra, các câu lệnh như FORALL, PURE& ELEMENTALthủ tục, vv giúp tiếp tục tối ưu hóa mã. Ngay cả con trỏ trong Fortran cũng không linh hoạt như C vì lý do đơn giản này.

Tiêu chuẩn Fortran sắp tới (2008) có các mảng đồng cho phép bạn dễ dàng viết mã song song. G95 (mã nguồn mở) và trình biên dịch từ CRAY đã hỗ trợ nó.

Vì vậy, có Fortran có thể nhanh chóng đơn giản vì trình biên dịch có thể tối ưu hóa / song song hóa nó tốt hơn C / C ++. Nhưng một lần nữa giống như mọi thứ khác trong cuộc sống, có trình biên dịch tốt và trình biên dịch xấu.



1
Cấu foralltrúc không được dùng nữa vì trình biên dịch không thể tối ưu hóa mã tốt. Sự thay thế là do concurrent. Ngoài ra, mã sqrt(sum(x**2))trông không hiệu quả, bởi vì trình biên dịch có thể xây dựng toàn bộ vectơ x**2. Tôi đoán rằng một vòng lặp là tốt hơn, nhưng chắc chắn là tốt nhất để gọi norm2hàm nội tại .
A. Hennink

39

Thật buồn cười khi rất nhiều câu trả lời ở đây từ việc không biết ngôn ngữ. Điều này đặc biệt đúng đối với các lập trình viên C / C ++, những người đã mở và sử dụng mã FORTRAN 77 cũ và thảo luận về các điểm yếu.

Tôi cho rằng vấn đề tốc độ chủ yếu là câu hỏi giữa C / C ++ và Fortran. Trong một mã Huge, nó luôn phụ thuộc vào lập trình viên. Có một số tính năng của ngôn ngữ mà Fortran vượt trội hơn và một số tính năng mà C làm. Vì vậy, vào năm 2011, không ai có thể thực sự nói cái nào nhanh hơn.

Về bản thân ngôn ngữ, Fortran hiện nay hỗ trợ các tính năng Full OOP và nó hoàn toàn tương thích ngược. Tôi đã sử dụng Fortran 2003 một cách triệt để và tôi sẽ nói rằng thật thú vị khi sử dụng nó. Ở một số khía cạnh, Fortran 2003 vẫn đứng sau C ++ nhưng hãy xem xét cách sử dụng. Fortran chủ yếu được sử dụng cho tính toán số và không ai sử dụng các tính năng OOP C ++ ưa thích vì lý do tốc độ. Trong điện toán hiệu năng cao, C ++ hầu như không có nơi nào để đi (hãy nhìn vào tiêu chuẩn MPI và bạn sẽ thấy rằng C ++ đã bị phản đối!).

Ngày nay, bạn có thể chỉ cần lập trình ngôn ngữ hỗn hợp với Fortran và C / C ++. Thậm chí có giao diện cho GTK + trong Fortran. Có trình biên dịch miễn phí (gfortran, g95) và nhiều trình biên dịch thương mại xuất sắc.


8
Bạn có thể vui lòng thêm một nguồn, kinh nghiệm cụ thể hoặc viện khoa học / cơ quan tính toán hiệu năng cao đang rời khỏi C ++ cho các dự án trong tương lai hoặc viết lại các dự án c ++ sang ngôn ngữ khác. Tôi chỉ hỏi bởi vì tôi biết ít nhất hai tổ chức khoa học, Sandia và CERN, sử dụng rất nhiều c ++ cho mô hình hiệu suất cao của họ. Ngoài ra, Sandia đã chuyển đổi một trong những phần mềm mô hình hóa của họ (LAMMPS) từ fortran sang c ++, thêm vào một số cải tiến tuyệt vời.
Zachary Kraus

7
LAMMPS được viết bằng C ++ cực kỳ đơn giản, không tận dụng được hầu hết các tính năng hiện đại của ngôn ngữ. Nó đại diện cho C ++ mà các lập trình viên Fortran biết C viết sau khi học C ++ 98. Điều này không có nghĩa là LAMMPS được viết kém, chỉ là nó không phải là ví dụ bạn muốn trích dẫn khi ủng hộ C ++ trong HPC.
Jeff

30

Có một số lý do tại sao Fortran có thể nhanh hơn. Tuy nhiên, số tiền họ quan trọng là không quan trọng hoặc có thể được xử lý xung quanh dù sao đi nữa, điều đó không quan trọng. Lý do chính để sử dụng Fortran hiện nay là duy trì hoặc mở rộng các ứng dụng cũ.

  • Từ khóa PURE và ElementAL trên các chức năng. Đây là những chức năng không có tác dụng phụ. Điều này cho phép tối ưu hóa trong một số trường hợp nhất định trong đó trình biên dịch biết cùng chức năng sẽ được gọi với cùng các giá trị. Lưu ý: GCC triển khai "thuần túy" như một phần mở rộng cho ngôn ngữ. Trình biên dịch khác có thể là tốt. Phân tích giữa các mô-đun cũng có thể thực hiện tối ưu hóa này nhưng rất khó.

  • bộ tiêu chuẩn của các hàm xử lý các mảng, không phải các phần tử riêng lẻ. Những thứ như sin (), log (), sqrt () lấy mảng thay vì vô hướng. Điều này làm cho nó dễ dàng hơn để tối ưu hóa các thói quen. Tự động vector hóa mang lại lợi ích tương tự trong hầu hết các trường hợp nếu các hàm này là nội tuyến hoặc nội trang

  • Kiểu dựng sẵn phức tạp. Về lý thuyết, điều này có thể cho phép trình biên dịch sắp xếp lại hoặc loại bỏ các hướng dẫn nhất định trong một số trường hợp nhất định, nhưng có khả năng bạn sẽ thấy lợi ích tương tự với struct {double re, im; }; thành ngữ được sử dụng trong C. Nó làm cho sự phát triển nhanh hơn mặc dù các toán tử làm việc trên các loại phức tạp trong fortran.


1
"nhưng có khả năng bạn sẽ thấy lợi ích tương tự với { double re, im; };thành ngữ struct được sử dụng trong C". Trình biên dịch C rất có thể sẽ trả về cấu trúc đó ở dạng sret với không gian phân bổ ngăn xếp của người gọi, chuyển một con trỏ tới callee để lấp đầy nó. Điều đó chậm hơn nhiều lần so với trả về nhiều giá trị trong các thanh ghi như trình biên dịch Fortran. Lưu ý rằng C99 đã sửa lỗi này trong trường hợp đặc biệt phức tạp.
Jon Harrop

Tôi không chắc chắn tôi đồng ý với lý do chính của bạn. Cá nhân tôi thích sử dụng fortran cho mã nặng toán học trong đó mảng và hàm toán học là phần quan trọng nhất của mã. Nhưng tôi biết thực tế ở rất nhiều tổ chức chính phủ và ngân hàng họ vẫn tiếp tục sử dụng fortran để duy trì hoặc mở rộng mã kế thừa. Cá nhân tôi đã sử dụng fortran để mở rộng mã giáo sư về bằng tiến sĩ của mình. ủy ban viết.
Zachary Kraus

Tuyên bố của bạn, "lý do chính để sử dụng Fortran hiện nay là duy trì hoặc mở rộng các ứng dụng cũ", là hoàn toàn sai. Tôi chưa thấy bất kỳ ngôn ngữ lập trình nào khác thậm chí từ xa gần với các tính năng mà Fortran cung cấp, đặc biệt là cho các ứng dụng Toán học. Bạn đã đặt tên cho một vài trong số chúng, chẳng hạn như hỗ trợ mảng tuyệt vời, tích hợp các hàm số học, hàm thuần túy hoặc nguyên tố phức tạp - và tôi cũng có thể đặt tên nhiều hơn. Điều đó là đủ để chứng minh tuyên bố của bạn ở trên là sai.
Pap

28

Tôi nghĩ rằng điểm mấu chốt có lợi cho Fortran là nó là một ngôn ngữ phù hợp hơn một chút để diễn đạt toán học dựa trên vectơ và mảng. Vấn đề phân tích con trỏ được chỉ ra ở trên là có thật trong thực tế, vì mã di động thực sự không thể cho rằng bạn có thể nói với trình biên dịch một cái gì đó. Luôn luôn có một lợi thế để thể hiện các computaitons theo cách gần với hình thức của miền. C thực sự không có mảng nào cả, nếu bạn nhìn kỹ, chỉ cần một thứ gì đó giống như vậy. Fortran có những cuộc tranh luận thực sự. Điều này làm cho việc biên dịch dễ dàng hơn đối với một số loại thuật toán nhất định đối với các máy song song.

Đi sâu vào những thứ như hệ thống thời gian chạy và các quy ước gọi vốn, C và Fortran hiện đại đủ giống nhau đến mức khó có thể thấy điều gì sẽ tạo ra sự khác biệt. Lưu ý rằng C ở đây thực sự là cơ sở C: C ++ là một vấn đề hoàn toàn khác với các đặc tính hiệu suất rất khác nhau.


25

Không có thứ gọi là một ngôn ngữ nhanh hơn ngôn ngữ khác, vì vậy câu trả lời thích hợp là không .

Điều bạn thực sự phải hỏi là "mã được biên dịch với trình biên dịch Fortran X nhanh hơn mã tương đương được biên dịch với trình biên dịch C Y?" Câu trả lời cho câu hỏi đó tất nhiên phụ thuộc vào hai trình biên dịch bạn chọn.

Một câu hỏi khác mà người ta có thể đặt ra là dọc theo dòng "Cho cùng một lượng nỗ lực để tối ưu hóa trong trình biên dịch của họ, trình biên dịch nào sẽ tạo ra mã nhanh hơn?" Câu trả lời cho điều này trong thực tế sẽ là Fortran . Trình biên dịch Fortran có lợi thế certian:

  • Fortran đã phải cạnh tranh với hội trở lại vào ngày mà một số người thề sẽ không bao giờ sử dụng trình biên dịch, vì vậy nó được thiết kế cho tốc độ. C được thiết kế linh hoạt.
  • Thị trường ngách của Fortran đã bị khủng hoảng số. Trong mã miền này không bao giờ là đủ nhanh. Vì vậy, luôn có rất nhiều áp lực để giữ cho ngôn ngữ hiệu quả.
  • Hầu hết các nghiên cứu về tối ưu hóa trình biên dịch được thực hiện bởi những người quan tâm đến việc tăng tốc mã bẻ khóa số Fortran, vì vậy tối ưu hóa mã Fortran là một vấn đề được biết đến nhiều hơn so với tối ưu hóa bất kỳ ngôn ngữ được biên dịch nào khác và trước tiên các cải tiến mới xuất hiện trong trình biên dịch Fortran.
  • Biggie : C khuyến khích sử dụng con trỏ nhiều hơn Fortran. Điều này làm tăng đáng kể phạm vi tiềm năng của bất kỳ mục dữ liệu nào trong chương trình C, khiến chúng khó tối ưu hóa hơn nhiều. Lưu ý rằng Ada cũng tốt hơn C trong lĩnh vực này và là Ngôn ngữ OO hiện đại hơn nhiều so với Fortran77 thường thấy. Nếu bạn muốn một ngôn ngữ OO có thể tạo mã nhanh hơn C, đây là một tùy chọn cho bạn.
  • Do một lần nữa do thích hợp với số lượng lớn, khách hàng của trình biên dịch Fortran có xu hướng quan tâm nhiều hơn đến tối ưu hóa so với khách hàng của trình biên dịch C.

Tuy nhiên, không có gì ngăn cản ai đó nỗ lực vào việc tối ưu hóa trình biên dịch C của họ và khiến nó tạo ra mã tốt hơn trình biên dịch Fortran của nền tảng của họ. Trên thực tế, doanh số lớn hơn do trình biên dịch C tạo ra khiến kịch bản này khá khả thi


4
Tôi đồng ý. Và tôi có thể nói thêm rằng khi Fortran được giới thiệu (đó là ngôn ngữ cấp cao đầu tiên) vào cuối thập niên 50 đầu thập niên 60, nhiều người đã nghi ngờ về hiệu quả của nó. Do đó, các nhà phát triển của nó đã phải chứng minh rằng Fortran có thể hiệu quả và hữu ích và chuẩn bị "tối ưu hóa nó đến chết" chỉ để chứng minh quan điểm của họ. C đến muộn hơn nhiều (sớm đến giữa những năm 70) và không có gì để chứng minh, có thể nói như vậy. Nhưng vào thời điểm này, rất nhiều mã Fortran đã được viết nên cộng đồng khoa học bị mắc kẹt và vẫn còn. Tôi không lập trình Fortran nhưng tôi đã học cách liên kết để gọi chương trình con Fortran từ C ++.
Olumide

3
Các nghiên cứu về tối ưu hóa trình biên dịch đã đa dạng hơn bạn nghĩ. Ví dụ, lịch sử triển khai LISP đầy những thành công trong việc thực hiện số khủng hoảng nhanh hơn Fortran (vẫn là đối thủ mặc định để thách thức). Ngoài ra, một phần lớn của tối ưu hóa trình biên dịch đã nhắm vào các biểu diễn trung gian của trình biên dịch, điều đó có nghĩa là, sự khác biệt về ngữ nghĩa sang một bên (như bí danh), chúng áp dụng cho bất kỳ ngôn ngữ lập trình nào của một lớp nhất định.
Người đàn ông hư không

2
Ý tưởng được lặp đi lặp lại rất nhiều, nhưng hơi khó tin khi nói rằng không có hậu quả nào cho hiệu quả vốn có đối với thiết kế ngôn ngữ lập trình. Một số tính năng ngôn ngữ lập trình nhất thiết dẫn đến sự thiếu hiệu quả vì chúng giới hạn thông tin có sẵn tại thời gian biên dịch.
Praxeolitic

@Praxeolitic - Điều đó khá chính xác (đó là lý do tại sao tôi hài lòng rằng tôi đã nói không có điều đó).
TED

@TED ​​Thành thật mà nói, trở lại đây vài tháng sau tôi không biết tại sao tôi lại để lại bình luận đó cho câu trả lời của bạn. Có lẽ tôi có ý định để nó ở một nơi khác? XP
Praxeolitic

22

Có một mục khác trong đó Fortran khác với C - và có khả năng nhanh hơn. Fortran có các quy tắc tối ưu hóa tốt hơn C. Trong Fortran, thứ tự đánh giá của một biểu thức không được xác định, cho phép trình biên dịch tối ưu hóa nó - nếu muốn buộc một thứ tự nhất định, người ta phải sử dụng dấu ngoặc đơn. Trong C, thứ tự chặt chẽ hơn nhiều, nhưng với các tùy chọn "-fast", chúng sẽ thoải mái hơn và "(...)" cũng bị bỏ qua. Tôi nghĩ Fortran có một cách nằm độc đáo ở giữa. (Chà, IEEE làm cho cuộc sống trở nên khó khăn hơn vì những thay đổi thứ tự đánh giá nhất định yêu cầu không xảy ra tràn, điều này phải được bỏ qua hoặc cản trở việc đánh giá).

Một lĩnh vực khác của quy tắc thông minh hơn là số phức. Không chỉ mất đến C 99, C mới có chúng, các quy tắc chi phối chúng cũng tốt hơn ở Fortran; do thư viện gfortran của Fortran được viết một phần bằng C nhưng thực hiện ngữ nghĩa của Fortran, GCC đã có được tùy chọn (cũng có thể được sử dụng với các chương trình C "thông thường"):

-fcx-fortran-quy tắc Nhân và chia phức tạp tuân theo quy tắc Fortran. Việc giảm phạm vi được thực hiện như một phần của phép chia phức tạp, nhưng không có kiểm tra xem kết quả của phép nhân hoặc phép chia phức tạp có phải là "NaN + I * NaN" hay không, với nỗ lực giải cứu tình huống trong trường hợp đó.

Các quy tắc bí danh được đề cập ở trên là một phần thưởng khác và cũng - ít nhất là về nguyên tắc - các hoạt động toàn mảng, nếu được tối ưu hóa đúng bởi trình tối ưu hóa của trình biên dịch, có thể dẫn mã nhanh hơn. Về phía contra là hoạt động nhất định mất nhiều thời gian hơn, ví dụ: nếu một người thực hiện gán cho một mảng phân bổ, có rất nhiều kiểm tra cần thiết (phân bổ lại? [Tính năng Fortran 2003], có các bước tiến, v.v.), làm cho hoạt động đơn giản phức tạp hơn đằng sau hậu trường - và do đó chậm hơn, nhưng làm cho ngôn ngữ mạnh mẽ hơn. Mặt khác, các hoạt động mảng với giới hạn và sải chân linh hoạt giúp viết mã dễ dàng hơn - và trình biên dịch thường tối ưu hóa mã tốt hơn so với người dùng.

Tổng cộng, tôi nghĩ rằng cả C và Fortran đều nhanh như nhau; sự lựa chọn nên là ngôn ngữ nào mà người ta thích nhiều hơn hoặc sử dụng các hoạt động toàn bộ mảng của Fortran và tính di động tốt hơn của nó sẽ hữu ích hơn - hay giao tiếp tốt hơn với các thư viện giao diện người dùng và hệ thống đồ họa trong C.


Có ý nghĩa gì để "giải cứu" trong trường hợp Nan + INan? Điều làm cho vô số khác với NaN là vô số được ký kết. Các hoạt động liên quan đến các trường hợp không phức tạp sẽ mang lại một dấu hiệu sai lệch mang lại NaN và tôi thấy không có lý do gì các số phức nên làm khác. Nếu một bội số (DBL_MAX, DBL_MAX) bằng (2,2), bình phương kết quả và sau đó bình phương kết quả đó, thì dấu hiệu của kết quả là gì khi không có tràn? Một thay vì nhân nó với (1.001, DBL_MAX) là gì? Tôi coi (NaN, NaN) là câu trả lời đúng và bất kỳ sự kết hợp nào giữa vô cực và NaN là vô nghĩa.
supercat

14

Không có gì về ngôn ngữ Fortran và C làm cho ngôn ngữ này nhanh hơn ngôn ngữ kia cho các mục đích cụ thể. Có những điều về trình biên dịch cụ thể cho từng ngôn ngữ này, điều này tạo thuận lợi cho một số tác vụ nhất định hơn các ngôn ngữ khác.

Trong nhiều năm, các trình biên dịch Fortran tồn tại có thể tạo ra ma thuật đen cho các thói quen số của bạn, làm cho nhiều tính toán quan trọng cực kỳ nhanh chóng. Các trình biên dịch C đương đại không thể làm điều đó là tốt. Kết quả là, một số thư viện mã lớn đã phát triển ở Fortran. Nếu bạn muốn sử dụng những thư viện tuyệt vời, đã được thử nghiệm, tuyệt vời này, bạn hãy thoát ra khỏi trình biên dịch Fortran.

Các quan sát không chính thức của tôi cho thấy rằng ngày nay mọi người mã hóa các công cụ tính toán nặng nề của họ bằng bất kỳ ngôn ngữ cũ nào và nếu phải mất một thời gian họ sẽ tìm thấy thời gian trên một số cụm tính toán rẻ tiền. Định luật Moore làm cho tất cả chúng ta ngu ngốc.


11
Gần như thay đổi điều này. Vấn đề là Fortran không có một số lợi thế vốn có. Tuy nhiên, bạn khá đúng rằng điều quan trọng cần xem xét là trình biên dịch chứ không phải ngôn ngữ.
TED

14

Tôi so sánh tốc độ của Fortran, C và C ++ với điểm chuẩn Levine-Callahan-Dongarra cổ điển từ netlib. Phiên bản đa ngôn ngữ, với OpenMP, là http://sites.google.com.vn/site/tprincesite/levine-callahan-dongarra-vector Chữ C xấu hơn, vì nó bắt đầu bằng dịch tự động, cộng với việc chèn hạn chế và pragma cho một số trình biên dịch. C ++ chỉ là C với các mẫu STL khi áp dụng. Theo quan điểm của tôi, STL là một túi hỗn hợp để xem nó có cải thiện khả năng bảo trì hay không.

Chỉ có bài tập tối thiểu về chức năng tự động trong lớp để xem mức độ cải thiện tối ưu hóa ở mức độ nào, vì các ví dụ này dựa trên thực tiễn Fortran truyền thống, nơi ít phụ thuộc vào lớp lót.

Trình biên dịch C / C ++, từ trước đến nay, việc sử dụng rộng rãi nhất lại thiếu tính năng vector hóa tự động, trong đó các điểm chuẩn này phụ thuộc rất nhiều.

Re bài đăng xuất hiện ngay trước đây: có một vài ví dụ trong đó dấu ngoặc đơn được sử dụng trong Fortran để đưa ra thứ tự đánh giá nhanh hơn hoặc chính xác hơn. Trình biên dịch C đã biết không có tùy chọn để quan sát dấu ngoặc đơn mà không vô hiệu hóa các tối ưu hóa quan trọng hơn.


Bản dịch xấu xí là cần thiết để khắc phục vấn đề răng cưa. Bạn phải cung cấp cho các biến giả của trình biên dịch để nói với nó rằng các biến byref được triển khai như các con trỏ có thể được tối ưu hóa đăng ký.
David

12

Tôi là một lập trình viên sở thích và tôi "trung bình" ở cả hai ngôn ngữ. Tôi thấy việc viết mã Fortran nhanh dễ hơn mã C (hoặc C ++). Cả Fortran và C đều là ngôn ngữ "lịch sử" (theo tiêu chuẩn ngày nay), được sử dụng nhiều và có trình biên dịch thương mại và miễn phí được hỗ trợ tốt.

Tôi không biết liệu đó có phải là một sự thật lịch sử hay không nhưng Fortran cảm thấy như nó được xây dựng để được song song / phân phối / véc tơ / bất cứ thứ gì nhiều lõi. Và ngày nay, nó gần như là "số liệu tiêu chuẩn" khi chúng ta nói về tốc độ: "nó có mở rộng không?"

Đối với cpu crunching tinh khiết tôi yêu Fortran. Đối với bất cứ điều gì liên quan đến IO, tôi thấy làm việc với C. dễ dàng hơn (dù sao cũng khó khăn trong cả hai trường hợp).

Bây giờ, tất nhiên, đối với mã chuyên sâu toán học song song, bạn có thể muốn sử dụng GPU của mình. Cả C và Fortran đều có giao diện CUDA / OpenCL tích hợp ít nhiều (và giờ là OpenACC).

Câu trả lời khách quan vừa phải của tôi là: Nếu bạn biết cả hai ngôn ngữ đều kém / kém thì tôi nghĩ Fortran nhanh hơn vì tôi thấy việc viết mã song song / phân tán trong Fortran dễ dàng hơn C. (một khi bạn hiểu rằng bạn có thể viết fortran "freeform" và không chỉ mã F77 nghiêm ngặt)

Đây là câu trả lời thứ 2 cho những người sẵn sàng đánh giá thấp tôi vì họ không thích câu trả lời thứ nhất: Cả hai ngôn ngữ đều có các tính năng cần thiết để viết mã hiệu suất cao. Vì vậy, nó phụ thuộc vào thuật toán bạn đang triển khai (cpu chuyên sâu? Io chuyên sâu? Bộ nhớ?), Phần cứng (cpu? Đa lõi? Phân phối siêu máy tính? GPGPU? FPGA?), Kỹ năng của bạn và cuối cùng là trình biên dịch. Cả C và Fortran đều có trình biên dịch tuyệt vời. (Tôi thực sự ngạc nhiên về trình biên dịch Fortran tiên tiến nhưng trình biên dịch C cũng vậy).

PS: Tôi rất vui vì bạn đã loại trừ libs một cách cụ thể vì tôi có rất nhiều điều tồi tệ để nói về libs GUI của Fortran. :)


11

Tôi đã làm một số toán học mở rộng với FORTRAN và C trong một vài năm. Từ kinh nghiệm của bản thân, tôi có thể nói rằng FORTRAN đôi khi thực sự tốt hơn C nhưng không phải vì tốc độ của nó (người ta có thể khiến C hoạt động nhanh như FORTRAN bằng cách sử dụng kiểu mã hóa phù hợp) mà là do các thư viện được tối ưu hóa rất tốt như LAPACK và vì song song lớn. Theo ý kiến ​​của tôi, FORTRAN thực sự rất khó xử lý và các ưu điểm của nó không đủ tốt để loại bỏ nhược điểm đó, vì vậy bây giờ tôi đang sử dụng C + GSL để thực hiện các phép tính.


10

Bất kỳ sự khác biệt về tốc độ giữa Fortran và C sẽ là một chức năng tối ưu hóa trình biên dịch và thư viện toán học cơ bản được sử dụng bởi trình biên dịch cụ thể. Không có gì nội tại đối với Fortran sẽ làm cho nó nhanh hơn C.

Dù sao, một lập trình viên giỏi có thể viết Fortran bằng bất kỳ ngôn ngữ nào.


@Scott Clawson: bạn có -1'd và tôi không biết tại sao. + 1'd để khắc phục điều này. Tuy nhiên, một điều cần tính đến là Fortran đã tồn tại lâu hơn rất nhiều cha mẹ của chúng tôi. Đã dành rất nhiều thời gian để tối ưu hóa đầu ra của trình biên dịch: D
user7116

Tôi đồng ý. Tôi vừa mới đăng một câu trả lời rất giống nhau song song.
Cao Jeff

Vấn đề bí danh con trỏ trong C đã được đưa ra bởi những người khác, nhưng có một số phương pháp mà lập trình viên có thể sử dụng trên các trình biên dịch hiện đại để giải quyết vấn đề đó, vì vậy tôi vẫn đồng ý.
Cao Jeff

1
@Kluge: "Không có gì nội tại đối với Fortran sẽ khiến nó nhanh hơn C". Bí danh con trỏ, trả về các giá trị ghép trong các thanh ghi, các cấu trúc số cấp cao hơn tích hợp ...
Jon Harrop

9

Tôi chưa nghe nói rằng Fortan nhanh hơn đáng kể so với C, nhưng nó có thể hiểu được trong một số trường hợp, nó sẽ nhanh hơn. Và chìa khóa không nằm ở các tính năng ngôn ngữ có mặt, mà là ở những tính năng (thường) vắng mặt.

Một ví dụ là con trỏ C. Con trỏ C được sử dụng khá nhiều ở mọi nơi, nhưng vấn đề với con trỏ là trình biên dịch thường không thể biết liệu chúng có trỏ đến các phần khác nhau của cùng một mảng hay không.

Ví dụ: nếu bạn đã viết một thói quen strcpy trông như thế này:

strcpy(char *d, const char* s)
{
  while(*d++ = *s++);
}

Trình biên dịch phải làm việc theo giả định rằng d và s có thể là các mảng chồng lấp. Vì vậy, nó không thể thực hiện tối ưu hóa sẽ tạo ra kết quả khác nhau khi các mảng trùng nhau. Như bạn mong đợi, điều này hạn chế đáng kể loại tối ưu hóa có thể được thực hiện.

[Tôi nên lưu ý rằng C99 có một từ khóa "hạn chế" rõ ràng cho các trình biên dịch rằng các con trỏ không trùng nhau. Cũng lưu ý rằng Fortran cũng có con trỏ, với ngữ nghĩa khác với C, nhưng con trỏ không phổ biến như trong C.]

Nhưng quay trở lại vấn đề C so với Fortran, có thể hình dung rằng trình biên dịch Fortran có thể thực hiện một số tối ưu hóa có thể không thực hiện được đối với chương trình C (được viết đơn giản). Vì vậy, tôi sẽ không quá ngạc nhiên bởi yêu cầu này. Tuy nhiên, tôi hy vọng rằng sự khác biệt hiệu suất sẽ không nhiều như vậy. [~ 5-10%]


9

Nhanh chóng và đơn giản: Cả hai đều nhanh như nhau, nhưng Fortran đơn giản hơn. Cái gì thực sự nhanh hơn cuối cùng phụ thuộc vào thuật toán, nhưng dù sao cũng không có sự khác biệt về tốc độ. Đây là những gì tôi học được trong một hội thảo về Fortran tại trung tâm điện toán hiệu năng cao, trụ sở ở Đức năm 2015. Tôi làm việc với cả Fortran và C và chia sẻ ý kiến ​​này.

Giải trình:

C được thiết kế để viết hệ điều hành. Do đó, nó có nhiều tự do hơn cần thiết để viết mã hiệu suất cao. Nói chung, điều này không có vấn đề gì, nhưng nếu không lập trình cẩn thận, người ta có thể dễ dàng làm chậm mã.

Fortran được thiết kế để lập trình khoa học. Vì lý do này, nó hỗ trợ viết mã cú pháp nhanh, vì đây là mục đích chính của Fortran. Trái ngược với dư luận, Fortran không phải là ngôn ngữ lập trình lỗi thời. Tiêu chuẩn mới nhất của nó là năm 2010 và các trình biên dịch mới được xuất bản một cách thường xuyên, vì hầu hết các mã hiệu suất cao được viết ở Fortran. Fortran tiếp tục hỗ trợ các tính năng hiện đại như các chỉ thị của trình biên dịch (trong C pragmas).

Ví dụ: Chúng tôi muốn đưa ra một cấu trúc lớn làm đối số đầu vào cho hàm (fortran: chương trình con). Trong hàm, đối số không bị thay đổi.

C hỗ trợ cả hai, gọi theo tham chiếu và gọi theo giá trị, đây là một tính năng tiện dụng. Trong trường hợp của chúng tôi, lập trình viên có thể vô tình sử dụng cuộc gọi theo giá trị. Điều này làm chậm mọi thứ đáng kể, vì cấu trúc cần được sao chép trong bộ nhớ trước.

Fortran chỉ làm việc với cuộc gọi bằng cách tham chiếu, điều này buộc lập trình viên phải sao chép cấu trúc bằng tay, nếu anh ta thực sự muốn một cuộc gọi bằng thao tác giá trị. Trong trường hợp của chúng tôi, fortran sẽ tự động nhanh như phiên bản C với cuộc gọi theo tham chiếu.


Bạn có thể viết một ứng dụng song song riêng trong C (nghĩa là không gọi bất kỳ thư viện nào không?). Không. Bạn có thể viết một ứng dụng song song riêng trong Fortran không? Vâng, theo một vài cách khác nhau. Ergo, Fortran "nhanh hơn". Mặc dù, công bằng mà nói, vào năm 2010 khi bạn viết bình luận của mình, sự hỗ trợ cho các tính năng song song và đồng mảng của Fortran có lẽ không phổ biến như bây giờ.
Remorker Mali

@MaliRemorker Ông đã viết bài này vào năm 2016, không phải vào năm 2010
Kowalski

Theo tôi, chi phí chung của việc tạo ra các quy trình song song không phải là yếu tố phù hợp nhất để ngôn ngữ lập trình được gọi là 'nhanh'. Liên quan hơn là những cân nhắc thực tế, giống như một sự hòa bình của mã không thực hiện. Vì vậy, nó không giúp ích gì nếu bạn tiết kiệm thời gian một lần (khi tạo quy trình song song) và lãng phí nó trên nhiều lõi sau này. Thuật ngữ 'nhanh' cũng nên xem xét các mã không song song. Vì lý do này, tôi không thể thấy một lập luận chống lại quan điểm của tôi. Có lẽ bình luận của bạn là một câu trả lời độc lập?
Markus Dutschke

8

Nói chung FORTRAN chậm hơn C. C có thể sử dụng các con trỏ mức phần cứng cho phép lập trình viên tối ưu hóa bằng tay. FORTRAN (trong hầu hết các trường hợp) không có quyền truy cập vào các bản hack địa chỉ bộ nhớ phần cứng. (VAX FORTRAN là một câu chuyện khác.) Tôi đã sử dụng và tắt FORTRAN kể từ những năm 70. (Có thật không.)

Tuy nhiên, bắt đầu từ thập niên 90, FORTRAN đã phát triển để bao gồm các cấu trúc ngôn ngữ cụ thể có thể được tối ưu hóa thành các thuật toán song song vốn có thể thực sự hét lên trên bộ xử lý đa lõi. Ví dụ, Vectorizing tự động cho phép nhiều bộ xử lý xử lý đồng thời từng phần tử trong một vectơ dữ liệu. 16 bộ xử lý - 16 phần tử vector - quá trình xử lý mất 1/16 thời gian.

Trong C, bạn phải quản lý các luồng của riêng mình và thiết kế thuật toán của bạn một cách cẩn thận để đa xử lý, sau đó sử dụng một loạt các lệnh gọi API để đảm bảo rằng sự song song xảy ra đúng.

Trong FORTRAN, bạn chỉ phải thiết kế thuật toán của mình một cách cẩn thận để đa xử lý. Trình biên dịch và thời gian chạy có thể xử lý phần còn lại cho bạn.

Bạn có thể đọc một chút về Fortran hiệu suất cao , nhưng bạn tìm thấy rất nhiều liên kết chết. Tốt hơn hết là bạn nên đọc về Lập trình song song (như OpenMP.org ) và cách FORTRAN hỗ trợ điều đó.


6
@ S.Lott: Tôi không thể tưởng tượng được mã C khủng khiếp sẽ trông như thế nào để làm tốt như Fortran được viết đơn giản cho hầu hết các mã chúng tôi có ở đây ... và tôi là một lập trình viên C. Bạn sẽ có được hiệu suất tốt hơn từ mã đơn giản hơn trong Fortran. Không phải là bạn hoặc tôi không thể tìm thấy một ví dụ. : D
user7116

2
@Greg Rogers: Bạn sẽ phải giải quyết vấn đề của bạn với những người tham gia Fortran Vector chứ không phải tôi. Tôi chỉ báo cáo những gì tôi đọc. polyhedron.com/absoftlinux
S.Lott

2
-1 // "Nói chung FORTRAN chậm hơn C. Điều này đúng với hầu hết mọi thứ." tại sao? // một đối số dựa trên sự dễ dàng sử dụng đa luồng trong Fortran vs C không nói lên điều gì về hiệu suất.
steabert

4
@ S.Lott: "đa luồng chỉ tồn tại cho hiệu suất". Ơ, không.
Jon Harrop

4
@ S.Lott: "Việc sử dụng con trỏ của C gần như ở cấp độ phần cứng cho phép C nhanh hơn Fortran". Ơ, không
Jon Harrop

5

Mã nhanh hơn không thực sự phù hợp với ngôn ngữ, là trình biên dịch để bạn có thể thấy "trình biên dịch" ms-vb tạo ra mã đối tượng cồng kềnh, chậm hơn và dư thừa được gắn với nhau bên trong một ".exe", nhưng powerBasic tạo ra quá cách mã tốt hơn. Mã đối tượng được tạo bởi trình biên dịch C và C ++ được tạo trong một số pha (ít nhất là 2) nhưng theo thiết kế, hầu hết các trình biên dịch Fortran có ít nhất 5 pha bao gồm tối ưu hóa mức cao, do đó, theo thiết kế, Fortran sẽ luôn có khả năng tạo mã được tối ưu hóa cao. Vì vậy, cuối cùng là trình biên dịch không phải là ngôn ngữ bạn nên yêu cầu, trình biên dịch tốt nhất mà tôi biết là Trình biên dịch Intel Fortran vì bạn có thể tải nó trên LINUX và Windows và bạn có thể sử dụng VS làm IDE, nếu bạn đang tìm kiếm trình biên dịch tigh giá rẻ bạn luôn có thể chuyển tiếp trên OpenWatcom.

Thông tin thêm về điều này: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

Fortran có các thói quen I / O tốt hơn, ví dụ, cơ sở do ngụ ý mang lại sự linh hoạt mà thư viện chuẩn của C không thể phù hợp.

Trình biên dịch Fortran trực tiếp xử lý cú pháp phức tạp hơn có liên quan và vì cú pháp như vậy không thể dễ dàng chuyển thành dạng chuyển đối số, C không thể thực hiện nó một cách hiệu quả.


1
Bạn có điểm chuẩn nào cho thấy Fortran đánh bại C cho I / O không?
Jeff

3

Sử dụng các tiêu chuẩn và trình biên dịch hiện đại, không!

Một số người ở đây đã gợi ý rằng FORTRAN nhanh hơn vì trình biên dịch không cần phải lo lắng về việc khử răng cưa (và do đó có thể đưa ra nhiều giả định trong quá trình tối ưu hóa). Tuy nhiên, điều này đã được xử lý trong C kể từ tiêu chuẩn C99 (tôi nghĩ) với việc bao gồm từ khóa hạn chế. Về cơ bản, nó cho trình biên dịch biết rằng trong phạm vi cho trước, con trỏ không được đặt bí danh. Hơn nữa, C cho phép số học con trỏ thích hợp, trong đó những thứ như răng cưa có thể rất hữu ích về mặt hiệu suất và phân bổ tài nguyên. Mặc dù tôi nghĩ rằng phiên bản gần đây hơn của FORTRAN cho phép sử dụng các con trỏ "phù hợp".

Đối với việc triển khai hiện đại, C nói chung vượt trội so với FORTRAN (mặc dù nó cũng rất nhanh).

http://benchmarkgame.alioth.debian.org/u64q/fortran.html

BIÊN TẬP:

Một lời chỉ trích công bằng về điều này dường như là điểm chuẩn có thể bị sai lệch. Đây là một nguồn khác (liên quan đến C) đặt kết quả trong nhiều ngữ cảnh hơn:

http://julialang.org/benchmark/

Bạn có thể thấy rằng C thường vượt trội hơn Fortran trong hầu hết các trường hợp (một lần nữa cũng thấy những lời chỉ trích dưới đây cũng áp dụng ở đây); như những người khác đã tuyên bố, điểm chuẩn là một khoa học không chính xác, có thể dễ dàng tải để ưu tiên một ngôn ngữ hơn các ngôn ngữ khác. Nhưng nó đặt trong bối cảnh làm thế nào Fortran và C có hiệu suất tương tự.


4
Người ta sẽ là một kẻ ngốc khi tin bất cứ điều gì về Fortran từ một bài đăng giả định rằng nó vẫn là FORTRAN. Điều đó đã thay đổi hơn 25 năm trước. Các thử nghiệm đó không thể so sánh các ngôn ngữ, vì chúng sử dụng trình biên dịch từ các nhà cung cấp khác nhau mặc dù cả Intel và GCC đều có trình biên dịch cho cả C và Fortran. Do đó những so sánh đó là vô giá trị.
Vladimir F

2

Fortran có thể xử lý mảng, đặc biệt là mảng đa chiều, rất thuận tiện. Các phần tử cắt của mảng đa chiều trong Fortran có thể dễ dàng hơn nhiều so với C / C ++. C ++ hiện có các thư viện có thể thực hiện công việc, chẳng hạn như Boost hoặc Eigen, nhưng chúng nằm sau tất cả các thư viện bên ngoài. Trong Fortran các chức năng này là nội tại.

Việc Fortran nhanh hơn hay thuận tiện hơn để phát triển chủ yếu phụ thuộc vào công việc bạn cần hoàn thành. Là một người tính toán khoa học cho địa vật lý, tôi đã thực hiện hầu hết các tính toán ở Fortran (ý tôi là Fortran hiện đại,> = F90).


1
Và việc Fortran có nhanh hơn hay không cũng phụ thuộc vào: trình biên dịch bạn sử dụng (nó quan trọng!), Cho các công việc tính toán cho dù bạn áp dụng song song hóa phù hợp với mã và cách viết mã của bạn.
Kai

1

Điều này là nhiều hơn một chút chủ quan, bởi vì nó đi vào chất lượng của trình biên dịch và nhiều hơn bất cứ điều gì khác. Tuy nhiên, để trả lời trực tiếp hơn câu hỏi của bạn, nói từ quan điểm ngôn ngữ / trình biên dịch, không có gì về Fortran trên C sẽ làm cho nó nhanh hơn hoặc tốt hơn C. Nếu bạn đang thực hiện các phép toán nặng, nó sẽ đi xuống chất lượng của trình biên dịch, kỹ năng của lập trình viên trong từng ngôn ngữ và các thư viện hỗ trợ toán học nội tại hỗ trợ các hoạt động đó để cuối cùng xác định cái nào sẽ nhanh hơn cho việc thực hiện nhất định.

EDIT: Những người khác như @Nils đã đưa ra quan điểm tốt về sự khác biệt trong việc sử dụng con trỏ trong C và khả năng bí danh có lẽ làm cho việc triển khai ngây thơ nhất trong C. Tuy nhiên, có nhiều cách để giải quyết điều đó trong C99 , thông qua các cờ tối ưu hóa trình biên dịch và / hoặc trong cách viết C thực sự được viết. Điều này cũng được đề cập trong câu trả lời @Nils và các bình luận tiếp theo sau câu trả lời của anh ấy.


Nghe có vẻ như một bài kiểm tra điểm chuẩn của một thuật toán. Mà mất ít thời gian hơn, FORTRAN hoặc C? Không có vẻ chủ quan với tôi. Có lẽ tôi đang thiếu một cái gì đó.
S.Lott

1
Không đồng ý. Bạn đang so sánh các trình biên dịch, không phải ngôn ngữ. Tôi nghĩ rằng câu hỏi ban đầu là nếu có bất cứ điều gì về NGÔN NGỮ làm cho nó vốn đã tốt hơn. Các câu trả lời khác ở đây đang đi vào một số khác biệt đáng nghi ngờ, nhưng tôi nghĩ rằng hầu hết chúng ta đồng ý rằng chúng đang ở trong tiếng ồn.
Cao Jeff

Đây không phải là phân tích O (n) của các thuật toán. Đó là hiệu suất. Đừng xem làm thế nào hiệu suất có thể là một khái niệm độc lập thực hiện giả thuyết. Đoán tôi đang thiếu một cái gì đó.
S.Lott

1
-1: "không có gì về Fortran trên C sẽ khiến nó nhanh hơn hoặc tốt hơn C". Ơ, không.
Jon Harrop

0

Hầu hết các bài viết đã trình bày các lập luận hấp dẫn, vì vậy tôi sẽ chỉ thêm 2 xu tục ngữ vào một khía cạnh khác.

Cuối cùng, fortran nhanh hơn hoặc chậm hơn về sức mạnh xử lý có thể có tầm quan trọng của nó, nhưng nếu phải mất gấp 5 lần thời gian để phát triển một thứ gì đó ở Fortran vì:

  • nó thiếu bất kỳ thư viện tốt nào cho các nhiệm vụ khác với crunching số thuần túy
  • nó thiếu bất kỳ công cụ tử tế nào cho tài liệu và kiểm tra đơn vị
  • đó là một ngôn ngữ có độ biểu cảm rất thấp, tăng vọt số lượng dòng mã.
  • nó có khả năng xử lý chuỗi rất kém
  • nó có một số lượng lớn các vấn đề trong số các trình biên dịch và kiến ​​trúc khác nhau khiến bạn phát điên.
  • nó có một chiến lược IO rất kém (ĐỌC / VIẾT các tệp tuần tự. Có, các tệp truy cập ngẫu nhiên tồn tại nhưng bạn đã bao giờ thấy chúng được sử dụng chưa?)
  • nó không khuyến khích thực hành phát triển tốt, mô đun hóa.
  • thiếu hiệu quả một trình biên dịch mã nguồn mở hoàn toàn chuẩn, tuân thủ đầy đủ (cả gfortran và g95 đều không hỗ trợ mọi thứ)
  • khả năng tương tác rất kém với C (mangling: một dấu gạch dưới, hai dấu gạch dưới, không có dấu gạch dưới, nói chung là một dấu gạch dưới nhưng hai nếu có một dấu gạch dưới khác.

Sau đó, vấn đề là không liên quan. Nếu một cái gì đó chậm, hầu hết thời gian bạn không thể cải thiện nó vượt quá giới hạn nhất định. Nếu bạn muốn một cái gì đó nhanh hơn, thay đổi thuật toán. Cuối cùng, thời gian máy tính là rẻ. Thời gian của con người là không. Giá trị sự lựa chọn làm giảm thời gian của con người. Nếu nó làm tăng thời gian máy tính, dù sao nó cũng có hiệu quả về chi phí.


3
bị hạ thấp bởi vì mặc dù bạn nêu ra những điểm thú vị làm tăng thêm thảo luận về lợi ích / nhược điểm của các ngôn ngữ khác so với các ngôn ngữ khác (mà tôi không hoàn toàn đồng ý), đây thực sự không phải là một câu trả lời cho câu hỏi ...
steabert

@steabert: trên thực tế, tôi đã nóiI will just add the proverbial 2 cents to a different aspect
Stefano Borini

1
+1 từ tôi cho một số câu trả lời không nitpicky. Như bạn đã nói, Fortran có thể nhanh hơn trong một số nhiệm vụ hiếm hoi (chưa từng thấy cá nhân nào). Nhưng lượng thời gian bạn lãng phí cho việc duy trì một ngôn ngữ không thể nhầm lẫn sẽ phá hỏng mọi lợi thế có thể.
André Bergner

10
-1. Bạn dường như đang nghĩ về Fortran về F77. Điều đó đã được thay thế bởi F90, F95, F03 F08.
Kyle Kanos

4
Bị từ chối vì nó nói riêng về một mặt của sự đánh đổi. Tốc độ phát triển có thể quan trọng đối với hầu hết các chương trình chung, nhưng điều đó không làm cho nó trở thành sự đánh đổi hợp lệ duy nhất. Các lập trình viên của Fortran thường là các nhà khoa học / kỹ sư đánh giá cao sự đơn giản của ngôn ngữ (FORmula TRANslation cực kỳ dễ học và thành thạo. C / C ++ thì không ), các thư viện tuyệt vời (thường được sử dụng từ các ngôn ngữ khác) và tốc độ (ví dụ như mô phỏng thời tiết phải mất nhiều ngày ở Fortran, nhưng vài tháng nếu được viết hoàn toàn bằng các ngôn ngữ khác).
BraveNewCurrency

-3

Theo truyền thống, Fortran không đặt các tùy chọn như -fp: rict (mà ifort yêu cầu kích hoạt một số tính năng trong USE IEEE_arithatures, một phần của tiêu chuẩn f2003). Intel C ++ cũng không đặt -fp: nghiêm ngặt như một mặc định, nhưng điều đó là bắt buộc để xử lý ERRNO, chẳng hạn, và các trình biên dịch C ++ khác không giúp tắt ERRNO một cách thuận tiện hoặc giảm tối ưu hóa như giảm simd. gcc và g ++ đã yêu cầu tôi thiết lập Makefile để tránh sử dụng kết hợp nguy hiểm -O3 -ffast-math -fopenmp -march = tự nhiên. Khác với những vấn đề này, câu hỏi về hiệu suất tương đối trở nên kén chọn hơn và phụ thuộc vào các quy tắc địa phương về lựa chọn trình biên dịch và tùy chọn.


Các bản cập nhật gcc gần đây đã khắc phục sự cố với sự kết hợp của Openmp và toán học nhanh.
tim18

Câu trả lời này thực sự là về việc người dùng không hiểu các cờ mặc định cho trình biên dịch của họ chứ không phải ngôn ngữ.
Jeff
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.