Fortran derleyicileri gerçekten C derleyicilerinden daha hızlı kod üretir mi?


17

Üniversitede okurken Fortran derleyicilerinin eşdeğer bir program için C derleyicilerinden daha hızlı kod ürettiği fikrini sık sık duydum.

Anahtar akıl yürütme şöyle gitti: Bir Fortran derleyicisi kod satırı başına ortalama 1,1 işlemci talimatı verirken, C derleyicisi kod satırı başına ortalama 1,6 işlemci talimatı yayar - tam sayıları hatırlamıyorum ama fikir, C derleyicilerinin belirgin şekilde daha fazla makine kodu yayması ve bu nedenle daha yavaş programlar üretmesiydi.

Böyle bir karşılaştırma ne kadar geçerlidir? Fortran derleyicilerinin C derleyicilerinden daha hızlı programlar ürettiğini veya tam tersini söyleyebilir miyiz ve bu fark neden var?


19
Bu, Fortran programlarının C'den daha ayrıntılı olduğu anlamına gelebilir ... Anlamlı bir karşılaştırma sadece her iki dilde de aynı işlevselliği uygulayarak ve elde edilen makine kodunu (boyut ve hız) karşılaştırarak yapılabilir.
Péter Török

Ayrıca, oluşturulan kod paralel yürütmeyi destekliyor mu?

@ Péter Török, Fortran'daki BLAS ve LAPACK'in C / C ++ bağlantı noktalarından çok daha iyi performans gösterdiği anlamına geliyor. Şimdi boşluk hızla azalıyor.
SK-logic

6
Yalnızca bir derleyicinin, her iki dilde de% 100 eşdeğer bir programınız varsa, derleyicilerini bilen ve performansı hesaba katabilen uzmanlar tarafından yazıldığında daha hızlı kod ürettiğini iddia edebilirsiniz.
Falcon

Eski Fortran, özyinelemeyi desteklemedi ve bu nedenle, her bir işlevin argümanları için statik olarak ayrılmış bir alan olacağından işlev çağrısı bağımsız değişkenlerini yığına zorlamak zorunda değildi. Bu, daha hızlı olmasının nedenlerinden biridir. Sanırım burada daha eksiksiz bir cevap bulabilirsiniz: amazon.com/Programming-Language-Pragmatics-Third-Edition/dp/…
Pedro Rolo

Yanıtlar:


36

IIRC, Fortran'ın daha hızlı olduğu söylenmesinin temel nedenlerinden biri işaretçi takma adının olmamasıdır , böylece C derleyicilerinin kullanamayacağı optimizasyonları kullanabilirler:

FORTRAN'da, işlev bağımsız değişkenleri birbirlerinin takma adı olmayabilir ve derleyici bunu yapmadığını varsayar. Bu mükemmel bir optimizasyon sağlar ve FORTRAN'ın hızlı bir dil olarak itibarının önemli bir nedenidir. (Diğer adın FORTRAN işlevi içinde yine de olabileceğini unutmayın. Örneğin, A bir diziyse ve i ve j aynı değere sahip endeksler ise, A [i] ve A [j], Neyse ki, taban dizisi aynı ada sahip olması gerektiğinden, A [i] ve A [j] 'nin diğer adı kullanamayacağı durumları belirlemek için dizin analizi yapılabilir.)

Ama burada başkalarıyla aynı fikirdeyim: Bir kod satırı için oluşturulan montajcı talimatları ortalama sayısını karşılaştırmak tam bir saçmalıktır. Örneğin, modern bir x86 çekirdeği, aynı kayıtlara erişmezlerse iki komutu paralel olarak yürütebilir. Böylece (teorik olarak) aynı talimatlar için sadece yeniden sıralayarak % 100'lük bir performans artışı elde edebilirsiniz . İyi derleyiciler ayrıca daha hızlı kod almak için daha fazla montaj talimatı üretecektir (döngü açma, satır içi düşünme). Montajcı talimatlarının toplam sayısı, bir kod parçasının performansı hakkında çok az şey söyler.


Daha iyi optimizasyonların bir başka nedeni, karmaşık sayılar için yerel destektir.
SK-logic

Fortran IV için kesinlikle doğru. Modern FORTRAN'larda hala işaretçiler, dinamik meory vb. Bulunmadığından emin değilim
Ingo

2
Bu, oyun endüstrisinde C ve C ++ 'da gelişirken sık sık biraz satır içi montaja düşmemizin nedeni de budur. İnsanlar istedikleri sıklıkta "derleyiciler insanların derleme yazmasından daha iyi optimizasyon yapabileceğini" iddia edebilirler, gerçekte, işaretçi takma adı çoğu zaman yapamayacakları anlamına gelir . Elle yazabileceğimiz kod, derleyicinin yayması için teknik olarak yasadışı olurdu, çünkü işaretçi takma hakkında hiçbir şey yapmaz.
Carson63000

5
C'nin restrictanahtar sözcüğü, bir işlevin yazarının bir işaretçinin takma adı olmadığını belirtmesini sağlar. Bu farkın giderilmesi için yeterli mi yoksa daha fazlası var mı?
bk.

@ C: C'nin "kısıtlama" saldırıları "sorunun yarısı"; belirli bir işaretçinin kullanım ömrü boyunca başka bir şey takma olmayacağını söylemeyi mümkün kılar, ancak bir derleyiciye, adresi bir işleve iletilen bir nesnenin, işlev döndükten sonra hiçbir şeyle yumuşatılmayacağını söylemenin bir yolu yoktur.
supercat

8

Tamamen geçersiz karşılaştırma.

İlk olarak, @ Péter Török'ün belirttiği gibi, üretilen hatların sayısı için geçerli bir karşılaştırma olması için önce Fortran ve C'den eşdeğer programlarda satır sayısını karşılaştırmanız gerekir .

İkincisi, daha az kod satırı her zaman daha hızlı programlara eşit değildir . Tüm makine talimatları yürütmek için aynı sayıda döngü gerçekleştirmez , ancak bellek erişimi , önbellekleme vb. Gibi başka sorunlarınız da vardır .

Bunun da ötesinde, daha az sayıda yürütme satırı (yani Satır Sayısı! = Yürütülen Satır Sayısı ) ile sonuçlandığı için uzun kod çalışmaları daha hızlı olabilir .


5

Dan doğrudur, daha uzun programlar daha yavaş programlar anlamına gelmez. Yaptıklarına büyük ölçüde bağlıdır.

Fortran'da uzman değilim, biraz biliyorum. Onları karşılaştırdığımda, iyi yazılmış C'nin Fortran'dan daha karmaşık veri yapıları ve işlevsellik ile performansta çok daha iyi olacağını düşünüyorum. Birisi (lütfen) burada yanılıyorsam beni düzeltin, ama Fortran'ın C'den biraz daha düşük bir seviyede olduğunu düşünüyorum. Eğer öyleyse, Fortran'da bazı sorunların daha hızlı çıkacağından eminim.

Başka bir şey, ilk bakışta derleyicilerin daha hızlı olup olmadığını sorduğunuzu sanıyordum. Aslında Fortran'ın benzer miktarda kod için daha hızlı derleneceğini düşünüyorum, ancak ortaya çıkan program ve nasıl çalıştığı farklı bir hikaye olacak. Ayrıştırmak daha kolaydır.


2
Karmaşık veri yapıları kullanıyorsanız FORTRAN muhtemelen yanlış seçimdir. FORTRAN, basit sayıları çok hızlı bir şekilde düzeltmek için optimize edilmiştir.
Zachary K

4

Bence bunun bir kısmı FORTRAN derleyicilerinin bazı matematik türlerini çok hızlı yapmak için tasarlandıkları. Bu yüzden insanlar FORTRAN'ı hesaplamaları olabildiğince hızlı yapmak için kullanıyorlar


4

Açıklama, C'nin bebeklik döneminde olduğu eski günlerde (70'lerin sonlarında) doğru olabilir ve Fortran tüm büyük üreticiler tarafından desteklendi ve oldukça optimize edildi. Erken Fortrans, IBM mimarisine dayanıyordu, eğer aritmetik gibi basit şeyler montaj talimatı başına kesinlikle bir ifade olurdu. Bu, 3 yollu sıçramalar olan Data General ve Prime gibi eski makineler için geçerlidir. Bu, 3 yollu atlama olmayan modern komut setleri üzerinde çalışmaz.

Kod satırları kod ifadelerine eşit değildir. Fortran'ın önceki sürümleri satır başına yalnızca bir ifadeye izin verdi. Fortran'ın sonraki sürümleri satır başına birden fazla ifade alabilir. C, satır başına birden çok ifadeye sahip olabilir. Intel IVF (eski adıyla CVF, MS Powerstation) ve Intel C gibi daha hızlı üretim derleyicilerinde, ikisi arasında gerçekten bir fark yoktur. Bu derleyiciler oldukça optimize edilmiştir.


4

Eski stil FORTRAN, bir dizinin bir bölümünü başlangıç ​​dizisini ve bitiş aboneliğini veya öğe sayısını belirten bir veya daha fazla tamsayı ile birlikte tüm diziye bir başvuru iletmek için gereken bir işlevin kullanılabilir olmasını isteyen bir programcının olmasını gerektiriyordu. . C , eleman sayısıyla birlikte ilgilenilen kısmın başlangıcına bir işaretçi geçirmeyi basitleştirmeyi mümkün kılar . Doğrudan terimlerle, bu işleri daha hızlı hale getirir (üç yerine iki şey geçirir). Ancak dolaylı olarak, bir derleyicinin gerçekleştirebileceği optimizasyon türlerini sınırlayarak işleri yavaşlatabilir.

İşlevi düşünün:

void diff(float dest[], float src1[], float src2[], int n)
{
  for (int i=0; i<n; i++)
    dest[i] = src1[i] - src2[i];
}

bir derleyici her bir işaretçinin bir dizinin başlangıcını tanımlayacağını biliyorsa, herhangi bir x! = y için, hedef [x üzerindeki işlemlerden dolayı dizinin öğelerine paralel veya herhangi bir sırayla etki edecek kod üretebilir. ] src1 [y] veya src2 [y] 'i etkilemez. Örneğin, bazı sistemlerde bir derleyici aşağıdakilere eşdeğer kod üretmekten yararlanabilir:

void dif(float dest[], float src1[], float src2[], int n)
{
  int i=0;
  float t1a,t1b,t2a,t2b,tsa,tsb;
  if (n > 2)
  {
    n-=4;
    t1a = src1[n+3]; t1b = src2[n+3]; t1b=src2[n+2]; t2b = src2[n+2];
    do
    {
      tsa = t1a-t2a;
      t1a = src1[n+1]; t2a = src2[n+1]; 
      tsb = t2b-t2b;
      dest[n+3] = tsa;
      t1b = src1[n]; t2b = src2[n]; 
      n-=2;
      dest[n+4] = tsb;
    } while(n >= 0);
    ... add some extra code to handle cleanup
  }
  else
    ... add some extra code to handle small values of n
}

Bir değeri yükleyen veya hesaplayan her işlemde, değerle bu değeri kullanan bir sonraki işlem arasında en az bir işlem daha bulunduğunu unutmayın. Bazı işlemciler, bu koşullar sağlandığında farklı işlemlerin işlenmesiyle çakışabilir ve böylece performansı artırabilir. Bununla birlikte, bir C derleyicisinin kodun ortak bir dizinin kısmen çakışan bölgelerine işaretçiler geçirmeyeceğini bilmesinin bir yolu olmadığından , bir C derleyicisinin yukarıdaki dönüşümü yapamayacağını unutmayın. Ancak, eşdeğer kod verilen FORTRAN derleyicileri böyle bir dönüşüm yapabilir ve yaptılar.

Bir C programcısı, döngüyü açan ve bitişik geçişlerin işlemlerini üst üste bindiren kodu açıkça yazarak karşılaştırılabilir bir performans elde etmeye çalışabilirken, bir derleyicinin bunları hafıza. Bir FORTRAN derleyicisinin eniyileştiricisi, belirli bir senaryoda hangi serpiştirme formlarının en iyi performansı sağlayacağına dair bir programcıdan daha fazlasını bilir ve bu tür kararlar genellikle bu tür derleyicilere bırakılır. C99 bir ekleyerek biraz C'nin durumu iyileştirmek için çalıştı ederken restricteleme eğer, o sadece burada kullanılabilecek dest[]hem ayrı bir dizi oldu src1[]ve src2[]ya programcı tüm davalarına bakacak döngünün ayrı versiyonlarını eklenirse destayrık oldusrc1ve src2nerede src1[]ve desteşitti ve src2ayrıktı, nerede src2[]ve dest[]eşitti ve src1ayrıktı ve üç dizinin hepsi eşitti. FORTRAN, aksine, aynı kaynak kodunu ve aynı makine kodunu kullanmakta zorlanmadan dört vakayı da ele alabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.