Anahtar kelime "kayıt" C?


273

registerAnahtar kelime C dilinde ne yapar ? Optimizasyon için kullanıldığını ancak herhangi bir standartta açıkça tanımlanmadığını okudum. Hâlâ alakalı mı ve öyleyse ne zaman kullanırsınız?


42
Register anahtar kelimesi C'de ne yapar? göz ardı edilir :)
bestsss

19
@bestsss Tamamen göz ardı edilmedi. registerDeğişkenin adresini bulmaya çalışın .
qrdl

Yanıtlar:


341

Derleyiciye değişkenin yoğun bir şekilde kullanılacağına ve mümkünse bir işlemci kaydında tutulmasını öneriyoruz.

Çoğu modern derleyici bunu otomatik olarak yapar ve onları seçmekten biz insanlardan daha iyidir.


18
ACM sunumlarımın düzeltilmesi için kayıt denedim ve bazen gerçekten yardımcı oldu. Ancak gerçekten dikkatli olmalısınız, çünkü kötü seçimler performansı düşürür.
ypnos

81
İyi bir sebep değil 'kayıt' kullanmak: Eğer 'kayıt' ilan değişkenin adresini alamaz
Adam Rosenfield

23
Bazı / birçok derleyicinin register anahtar sözcüğünü (tamamen yasal olan) tamamen yok sayacağını unutmayın.
Euro Micelli

5
ypnos: Aslında ACM ICPC problemleri için bir çözümün hızı algoritma seçimine bu mikro optimizasyonlardan çok daha fazla bağlıdır. 5 saniyelik zaman sınırı, özellikle Java yerine C kullanılırken, doğru bir çözüm için genellikle yeterlidir.
Joey

66
@Auro: Bunu muhtemelen biliyorsunuzdur, ancak açık olmak gerekirse, bir registerdeğişkenin adresinin alınmasını önlemek için derleyicinin bulunması gerekir ; bu sadece zorunlu etkisi registeranahtar kelime. Bu bile optimizasyonları iyileştirmek için yeterlidir, çünkü değişkenin sadece bu fonksiyon içinde değiştirilebileceğini söylemek önemsiz hale gelir.
Dale Hagglund

69

Derleyici kayıttan ziyade değişkeni bellekte tutmaya karar verse bile, hiç kimse kayıt değişkeninin adresini alamayacağınızı söylemediğine şaşırdım.

Yani registersize hiçbir şey kazanmak (neyse derleyici değişkeni nereye koyacağına kendisi karar verir) ve &operatörü kaybetmek - kullanmak için bir neden yok.


94
Aslında bir sebep var. Değişkenin adresini alamamanız gerçeği bazı optimizasyon fırsatları sağlar: derleyici değişkenin takma adı olmayacağını kanıtlayabilir.
Alexandre C.

8
Derleyiciler önemsiz durumlarda takma adın oluşmadığını kanıtlamak konusunda korkunç bir şeydir, bu yüzden registerderleyici bir kayıt defterine koymasa bile bunun için yararlıdır.
Miles Rout

2
@AlexandreC, Miles, derleyiciler bir değişkenin herhangi bir yerde alınıp alınmadığını kontrol etmede mükemmel durumdadır. Örtüşmenin algılanmasındaki diğer zorluklardan bağımsız olarak, size hiçbir şey satın almadığını yeniden ifade etmek. K + R C'yi ilk oluşturduğunda , bu derleyicinin aslında aşağıdaki kodu incelemeden önce beyanı görmeye ilişkin kayıt tahsis kararını verdiği için önceden kullanılmayacağını ve kullanılmayacağını bilmek faydalı oldu . Bu yüzden yasak yürürlüktedir. 'Register' anahtar kelimesi artık eskimiş durumda.
greggo

25
Bu mantıkla const, size hiçbir şey kazanmadığı için de işe yaramaz, sadece bir değişkeni değiştirme yeteneğini kaybedersiniz. registergelecekte hiç kimsenin bir değişkenin adresini düşünmeden almasını sağlamak için kullanılabilir. registerYine de kullanmak için hiçbir neden yoktu .
Tor Klingberg

34

Derleyiciye, değişkeni saklamak için RAM yerine bir CPU kaydı kullanmayı denemesini söyler. Kayıtlar CPU'da ve erişim RAM'den çok daha hızlı. Ancak bu sadece derleyiciye bir öneridir ve takip etmeyebilir.


8
C kullananlar için ilave değer ++, C ++, bir kayıt değişkenin adresini çekmenize olanak verir
Will

5
@Will: ... ancak derleyici büyük olasılıkla anahtar kelimeyi görmezden gelecektir. Cevabımı gör.
bwDraco

Evet, öyle görünüyor ki 'register' C ++ 'da bir plasebo, C kodunun C ++ olarak derlenmesine izin vermek için sadece orada. Ve referans veya const referansı ile geçirmeye izin verirken yasaklamak ve değiştirmek çok mantıklı olmaz ve referansla geçmek olmadan C ++ 'ı ciddi şekilde kırmışsınızdır.
greggo

22

Bu sorunun C ile ilgili olduğunu biliyorum, ancak C ++ için aynı soru bu sorunun tam bir kopyası olarak kapatıldı. Dolayısıyla bu cevap C için geçerli olmayabilir.


C ++ 11 standardının son taslağı N3485 , 7.1.1 / 3'te bunu söylüyor:

Bir registertanımlayıcı, uygulamaya bu şekilde bildirilen değişkenin yoğun bir şekilde kullanılacağına dair bir ipucudur. [ not: İpucu yok sayılabilir ve çoğu uygulamada değişkenin adresi alınırsa yok sayılır. Bu kullanım kullanımdan kaldırıldı ... —end not ]

C ++ 'da (ancak C değil ), standart, bildirilen bir değişkenin adresini alamayacağınızı belirtmez register; ancak, bir CPU kaydında depolanan bir değişkenin ömrü boyunca kendisiyle ilişkilendirilmiş bir bellek konumu olmadığından, adresini almaya çalışmak geçersiz olur ve derleyici register, adresin alınmasına izin vermek için anahtar kelimeyi yoksayar .


17

Optimize ediciler bu konuda yapabileceğinizden daha iyi kararlar verdiklerinden, en az 15 yıldır geçerli değildir. İlgili olduğunda bile, SPARC veya M68000 gibi çok sayıda kayıt içeren bir CPU mimarisinde, çoğu derleyici tarafından kendi amaçları için ayrılmış olan kayıtların azlığıyla Intel'den çok daha mantıklıydı.


13

Aslında register, derleyiciye değişkenin programdaki herhangi bir şeyle takma olmadığını söyler (char'ın bile değil).

Bu, çeşitli durumlarda modern derleyiciler tarafından kullanılabilir ve derleyiciye karmaşık kodda biraz yardımcı olabilir - basit kodda derleyiciler bunu kendi başlarına çözebilir.

Aksi takdirde hiçbir amaca hizmet etmez ve kayıt tahsisi için kullanılmaz. Derleyiciniz yeterince modern olduğu sürece, bunu belirtmek genellikle performans düşüşüne neden olmaz.


"derleyiciye söyler .." hayır, söylemez. Onun adresini almak sürece tüm oto değişkenler, bu özelliği vardır ve belirli analiz kullanımları aşan şekillerde kullanırız. Yani, derleyici bunu register anahtar sözcüğünü kullanıp kullanmadığınıza bakılmaksızın koddan bilir. O kadar 'kayıt' anahtar yasadışı böyle bir yapıyı yazmak için yapar olur, ancak anahtar kelimeyi kullanın ve yoksa yok öyle bir şekilde adres almak, sonra derleyici hala güvenli olduğunu bilir. Bu tür bilgiler optimizasyon için çok önemlidir.
greggo

1
@greggo: registerAdresi almayı çok kötü yasaklar, aksi takdirde bir değişkenin adresinin harici bir işleve geçmesine rağmen bir derleyicinin kayıt optimizasyonlarını uygulayabileceği durumları bildirmesi yararlı olabilir (değişken belirli bir çağrı için belleğe boşaltılabilir , ancak işlev geri döndüğünde, derleyici tekrar adresi hiç alınmamış bir değişken olarak ele alabilir).
supercat

@supercat Derleyici ile hala çok zor bir konuşma olacağını düşünüyorum. Derleyiciye söylemek istediğiniz buysa, ilk değişkeni üzerinde '&' olmayan ikinci bir değişkene kopyalayıp sonra birincisini bir daha kullanmayarak yapabilirsiniz.
greggo

1
@greggo: eğer söyleyen barbir olan registerdeğişken bir derleyici onun boş olabilir yerini foo(&bar);ile int temp=bar; foo(&temp); bar=temp;ancak adresini alarak baraşırı karmaşık bir kural gibi görünebilir olmaz en başka bağlamlarda yasak olacaktır. Değişken başka türlü bir kayıt defterinde tutulabiliyorsa, ikame kodu daha küçük hale getirecektir. Değişkenin yine de RAM'de tutulması gerekirse, ikame kodu daha büyük hale getirir. Değişikliğin derleyiciye yapılıp yapılmayacağı sorusunu bırakmak her iki durumda da daha iyi kodlamaya yol açacaktır.
supercat

1
@greggo: registerDerleyicinin adresin alınmasına izin verip vermemesine bakılmaksızın, global değişkenler üzerinde bir kalifikasyona izin vermek , bir global değişken kullanan satır içi bir işlevin bir döngü içinde tekrar tekrar çağrılması durumunda bazı hoş optimizasyonlara izin verir. Ben bu değişken döngü yinelemeleri arasında bir kayıt tutulması için başka bir yol düşünemiyorum - değil mi?
supercat

13

Optimizasyon için kullanıldığını ancak herhangi bir standartta açıkça tanımlanmadığını okudum.

Aslında olduğu net bir şekilde Cı standardında tanımlandığı gibidir. N1570 taslak bölüm 6.7.1 paragraf 6'dan alıntı yapılması (diğer sürümler aynı ifadeye sahiptir):

Depolama sınıfı belirleyicisine sahip bir nesne için tanımlayıcı bildirimi, nesneye registererişimin mümkün olduğunca hızlı olmasını önerir. Bu tür önerilerin ne kadar etkili olduğu uygulama tanımlıdır.

Tekli &operatör register, ve ile tanımlanan bir nesneye uygulanamaz.register harici bir bildirimde kullanılamaz.

registerNitelikli nesnelere özgü birkaç (oldukça belirsiz) kural vardır :

  • Bir dizi nesnesinin registertanımlanamayan bir davranışı var.
    Düzeltme: ile bir dizi nesnesi tanımlamak yasaldırregister , ancak böyle bir nesne ile yararlı bir şey yapamazsınız (bir dizine dizin oluşturmak, ilk öğesinin adresini almayı gerektirir).
  • _Alignas(C11 yeni) belirteci böyle bir nesne için uygulanamaz.
  • va_startMakroya iletilen parametre adı register-kalifiye ise, davranış tanımsızdır.

Birkaç tane daha olabilir; standardın taslağını indirin ve ilgileniyorsanız "kayıt ol" terimini arayın.

Adından da anlaşılacağı gibi, asıl anlamı, registerbir nesnenin CPU kaydında saklanmasını gerektiriyordu. Ancak derleyicilerin optimize edilmesindeki iyileştirmelerle, bu daha az kullanışlı hale geldi. C standardının modern versiyonları CPU kayıtlarına değinmez, çünkü artık böyle bir şey olduğunu varsaymazlar (buna gerek yoktur) (kayıt kullanmayan mimariler vardır). Ortak bilgelik, registerbir nesne bildirimine başvurmanın , oluşturulan kodun kötüleşme olasılığının daha yüksek olmasıdır , çünkü derleyicinin kendi kayıt tahsisine müdahale eder. Yararlı olduğu birkaç durum olabilir (örneğin, bir değişkene ne sıklıkta erişileceğini gerçekten biliyorsanız ve bilginiz modern bir optimizasyon derleyicisinin anlayabileceğinden daha iyidir).

Başlıca somut etkisi, registerbir nesnenin adresini alma girişimini engellemesidir. Bu, bir optimizasyon ipucu olarak özellikle yararlı değildir, çünkü yalnızca yerel değişkenlere uygulanabilir ve bir optimizasyon derleyicisi böyle bir nesnenin adresinin alınmadığını kendisi görebilir.


Peki bu programın davranışı gerçekten C standardına göre tanımlanmamış mı? C ++ 'da iyi tanımlanmış mı? Ben C ++ iyi tanımlanmış düşünüyorum.
Destructor

@ Yıkıcı: Neden tanımsız olsun ki? Hiçbir yok registerbu ne sen düşünme eğer ulaşım kolaylığı dizi nesnesi.
Keith Thompson

Üzgünüm main () dizi bildiriminde kayıt anahtar kelimesini yazmayı unuttum. C ++ 'da iyi tanımlanmış mı?
Destructor

registerDizi nesneleri tanımlamakta yanılmışım ; cevabımda güncellenen ilk madde işaretine bakın. Böyle bir nesneyi tanımlamak yasaldır, ancak onunla hiçbir şey yapamazsınız. Eğer eklerseniz registertanımına syer senin Örneğin , program aynı kısıtlama yoktur C. C ++ (a kısıtlama ihlali) yasadışı registerprogramı geçerli C olurdu böylece ++, (ancak kullanarak registeranlamsız olurdu).
Keith Thompson

@KeithThompson: registerAnahtar kelime, böyle bir değişkenin adresini almak yasal olsaydı yararlı bir amaca hizmet edebilirdi, ancak yalnızca semantiğin, adresi alındığında bir geçici dosyaya kopyalayarak ve geçici dosyadan yeniden yükleyerek etkilenmeyeceği durumlarda sonraki sıra noktasında. Bu, derleyicilerin, adresinin alındığı herhangi bir yerde yıkanması şartıyla, değişkenin tüm işaretçi erişimlerinde güvenli bir şekilde bir kayıtta tutulabileceğini varsaymasına izin verecektir.
supercat

9

Hikaye zamanı!

C, dil olarak bir bilgisayarın soyutlamasıdır. Bir bilgisayarın ne yaptığı, hafızayı manipüle eden, matematik, şeyleri basan vb.

Ancak C sadece bir soyutlamadır. Ve nihayetinde, senden elde ettiği şey Meclis dilidir. Montaj CPU'nun okuduğu dildir ve kullanırsanız CPU açısından bir şeyler yaparsınız. CPU ne yapar? Temel olarak, bellekten okur, matematik yapar ve belleğe yazar. CPU sadece bellekteki sayılar üzerinde matematik yapmakla kalmaz. İlk olarak, CPU içinde a adlı bir sayıyı bellekten belleğe taşımalısınız kayıt. Bu numaraya ne yapmanız gerekiyorsa işinizi bitirdikten sonra, normal sistem belleğine geri taşıyabilirsiniz. Neden sistem belleğini kullanıyorsunuz? Kayıtların sayısı sınırlıdır. Modern işlemcilerde sadece yüz bayt alırsınız ve eski popüler işlemciler daha da fevkalade sınırlıydı (6502'nin ücretsiz kullanımınız için 3 8 bit kaydı vardı). Yani, ortalama matematik işleminiz şöyle görünür:

load first number from memory
load second number from memory
add the two
store answer into memory

Bunların çoğu matematik değil. Bu yükleme ve depolama işlemleri, işlem sürenizin yarısına kadar sürebilir. C, bilgisayarların bir soyutlaması olarak, programcıların kayıtların kullanımı ve hokkabazlığı endişesini serbest bıraktı ve sayı ve tür bilgisayarlar arasında değiştiği için C, kayıt tahsisi sorumluluğunu sadece derleyiciye yerleştirir. Bir istisna dışında.

Bir değişken bildirdiğinizde registerderleyicisine "Yo, bu değişkenin çok kullanılmasını ve / veya kısa ömürlü olmasını istiyorum. Sen olsaydım, bunu bir kayıtta tutmaya çalışırdım." C standardı derleyicilerin aslında hiçbir şey yapması gerekmediğini söylediğinde, bunun nedeni C standardı için hangi bilgisayarı derlediğinizi bilmiyor ve yukarıdaki 6502 gibi olabilir. ve numaranızı saklayacak yedek kayıt yok. Ancak, adresi alamayacağınızı söylediğinde, bunun nedeni, kayıtların adreslerinin olmamasıdır. Onlar işlemcinin elleri. Derleyici size bir adres vermek zorunda olmadığından ve hiçbir zaman bir adrese sahip olamadığından, derleyiciye birkaç optimizasyon açıktır. Örneğin, numarayı her zaman bir kayıt defterinde tutabilir. Öyle değil t Bilgisayar belleğinde nerede depolandığı konusunda endişelenmeniz gerekir (tekrar geri almanın ötesinde). Hatta başka bir değişkene çevirebilir, başka bir işlemciye verebilir, değişen bir konum verebilir, vb.

tl; dr: Çok fazla matematik yapan kısa ömürlü değişkenler. Aynı anda çok fazla beyan etmeyin.


5

Derleyicinin gelişmiş grafik renklendirme algoritmasıyla uğraşıyorsunuz. Bu, kayıt tahsisi için kullanılır. Pekala, çoğunlukla. Derleyiciye bir ipucu görevi görür - bu doğru. Ancak bir kayıt değişkeninin adresini alma izniniz olmadığından tamamen göz ardı edilmez (derleyicinin, şimdi merhametinize göre, farklı davranmaya çalışacağını unutmayın). Hangi bir şekilde onu kullanmamanızı söylüyor.

Anahtar kelime uzun, uzun geri kullanıldı. İşaret parmağınızı kullanarak hepsini sayabilecek kadar az kayıt olduğunda.

Ancak, dediğim gibi, kullanımdan kaldırılmış olması onu kullanamayacağınız anlamına gelmez.


13
Bazı eski donanımların modern Intel makinelerinden daha fazla kaydı vardı. Kayıt sayımlarının yaş ve CPU mimarisi ile ilgisi yoktur.
SADECE benim doğru görüşüm

2
@JUSTMYcorrectOPINION Gerçekten de, X86'da altı tane vardır ve 'kayıt' için adanmışlık için en fazla 1 veya 2 bırakır. Aslında, bu kadar çok kod yazılan veya zayıf bir makineye taşındığı için, bunun 'register' anahtar kelimesinin plasebo haline gelmesine büyük katkıda bulunduğundan şüpheleniyorum - herhangi bir kayıt olmadığında kayıtların ipucunda bulunmanın bir anlamı yok. İşte biz 4+ yıl sonra ve neyse ki x86_64 14'e yükseltti ve ARM şimdi de büyük bir şey.
greggo

4

Sadece karşılaştırma için (herhangi bir gerçek dünya amaç olmadan) biraz demo: çıkartırken registerher değişken önce anahtar kelimeleri, bu kod parçası, benim i7 (GCC) üzerinde 3.41 saniye sürer ile register 0.7 saniyede aynı kod tamamlanıncaya.

#include <stdio.h>

int main(int argc, char** argv) {

     register int numIterations = 20000;    

     register int i=0;
     unsigned long val=0;

    for (i; i<numIterations+1; i++)
    {
        register int j=0;
        for (j;j<i;j++) 
        {
            val=j+i;
        }
    }
    printf("%d", val);
    return 0;
}

2
Gcc 4.8.4 ve -O3 ile hiçbir farkım yok. -O3 ve 40000 tekrarlamalar olmadan, ben olsun belki 50 ms az bir 1.5s toplam zaman üzerinde, ama bu bile statistaclly anlamlı olup olmadığını bilmek onu yeterince kez çalıştırmak vermedi.
zstewart

CLANG 5.0 ile hiçbir fark yok, platform AMD64. (ASM çıkışını kontrol ettim.)
ern0

4

Aşağıdaki kodu kullanarak kayıt anahtar kelimesini QNX 6.5.0 altında test ettim:

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>

int main(int argc, char *argv[]) {
    uint64_t cps, cycle1, cycle2, ncycles;
    double sec;
    register int a=0, b = 1, c = 3, i;

    cycle1 = ClockCycles();

    for(i = 0; i < 100000000; i++)
        a = ((a + b + c) * c) / 2;

    cycle2 = ClockCycles();
    ncycles = cycle2 - cycle1;
    printf("%lld cycles elapsed\n", ncycles);

    cps = SYSPAGE_ENTRY(qtime) -> cycles_per_sec;
    printf("This system has %lld cycles per second\n", cps);
    sec = (double)ncycles/cps;
    printf("The cycles in seconds is %f\n", sec);

    return EXIT_SUCCESS;
}

Aşağıdaki sonuçları aldım:

-> 807679611 döngü geçti

-> Bu sistem saniyede 3300830000 devire sahiptir

-> Saniye cinsinden döngü sayısı ~ 0.244600

Ve şimdi int olmadan kayıt:

int a=0, b = 1, c = 3, i;

Bende var:

-> 1421694077 döngü geçti

-> Bu sistem saniyede 3300830000 devire sahiptir

-> Saniye cinsinden döngü sayısı ~ 0.430700


2

Kayıt, derleyiciye kodlayıcının bu değişkenin, değişken kullanım için mevcut olan birkaç kayıttan birinde depolanmasını haklı çıkaracak kadar yazıldığını / okunacağını düşündüğünü bildirir. Kayıtlardan okuma / yazma genellikle daha hızlıdır ve daha küçük bir op kodu seti gerektirebilir.

Günümüzde bu, pek çok derleyicinin optimize edicisi, bu değişken için bir kayıt kullanılıp kullanılmayacağını ve ne kadar süreyle kullanılacağını belirlemede sizden daha iyi olduğu için çok yararlı değildir.


2

Yetmişli yıllarda, C dilinin en başında, programcının derleyiciye ipuçları vermesine izin vermek için değişkenin çok sık kullanılacağını ve bunun akıllıca olması gerektiğini bildirmek için register anahtar sözcüğü eklenmiştir. değerini işlemcinin dahili kaydından birinde tutun.

Günümüzde, optimize ediciler, kayıtlarda tutulması daha olası değişkenleri belirlemek için programcılardan çok daha verimlidir ve optimizer her zaman programlayıcının ipucunu dikkate almaz.

Pek çok kişi yanlışlıkla register anahtar kelimesini kullanmamanızı tavsiye ediyor.

Bakalım neden!

Register anahtar kelimesinin ilişkili bir yan etkisi vardır: bir kayıt türü değişkenine başvuramazsınız (adresini alamazsınız).

Başkalarına kayıt kullanmamalarını tavsiye eden insanlar bunu yanlış bir ek argüman olarak görürler.

Bununla birlikte, bir kayıt değişkeninin adresini alamayacağınızı bilmenin basit gerçeği, derleyicinin (ve optimize edicisinin) bu değişkenin değerinin bir işaretçi aracılığıyla dolaylı olarak değiştirilemeyeceğini bilmesini sağlar.

Komut akışının belirli bir noktasında, bir kayıt değişkeni değerinin bir işlemci kaydına atanmışsa ve kayıt başka bir değişkenin değerini almak için kullanılmadığında, derleyici yeniden yüklemeye gerek olmadığını bilir bu kayıttaki değişkenin değeri. Bu pahalı gereksiz bellek erişiminden kaçınmaya izin verir.

Kendi testlerinizi yapın ve en iç döngülerinizde önemli performans geliştirmeleri elde edeceksiniz.

c_register_side_effect_performance_boost


1

Desteklenen C derleyicilerinde, değişkenin gerçek bir işlemci kaydında tutulması için kodu optimize etmeye çalışır.


1

Genel registerkayıt ayırma optimizasyonu (/ Oe derleyici bayrağı) etkinleştirildiğinde, Microsoft'un Visual C ++ derleyicisi anahtar sözcüğü yok sayar .

Anahtar kelimeyi MSDN'ye kaydetme konusuna bakın .


1

Kayıt anahtar kelimesi derleyiciye belirli bir değişkeni hızlı bir şekilde erişilebilir olması için CPU kayıtlarında saklamasını söyler. Bir programcının bakış açısından register anahtar sözcüğü, bir programda yoğun olarak kullanılan değişkenler için kullanılır, böylece derleyici kodu hızlandırabilir. Derleyiciye değişkenin CPU kayıtlarında mı yoksa ana bellekte mi tutulacağına bağlı olmasına rağmen.


0

Kayıt, derleyiciye söz konusu değişkeni kayıtlarda ve sonra bellekte depolayarak bu kodu optimize etmek için kullanılır. derleyici için bir taleptir, derleyici bu talebi değerlendirebilir veya etmeyebilir. Değişkenlerinizin bir kısmına çok sık erişilmesi durumunda bu özelliği kullanabilirsiniz. Örn: Bir döngü.

Bir şey daha, bir değişkeni kayıt olarak bildirirseniz, belleğe kaydedilmediğinden adresini alamazsınız. CPU kaydında tahsisini alır.


0

gcc 9.3 asm çıkışı, optimizasyon bayrakları kullanmadan (bu yanıttaki her şey optimizasyon bayrakları olmadan standart derleme anlamına gelir):

#include <stdio.h>
int main(void) {
  int i = 3;
  i++;
  printf("%d", i);
  return 0;
}
.LC0:
        .string "%d"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 3
        add     DWORD PTR [rbp-4], 1
        mov     eax, DWORD PTR [rbp-4]
        mov     esi, eax
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 0
        leave 
        ret
#include <stdio.h>
int main(void) {
  register int i = 3;
  i++;
  printf("%d", i);
  return 0;
}
.LC0:
        .string "%d"
main:
        push    rbp
        mov     rbp, rsp
        push    rbx
        sub     rsp, 8
        mov     ebx, 3
        add     ebx, 1
        mov     esi, ebx
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        add     rsp, 8
        pop     rbx
        pop     rbp
        ret

Bu ebxhesaplama için kullanılacak güçler , yani yığına itilmesi ve fonksiyonun sonunda geri yüklenmesi gerektiği için geri yüklenmesi gerekir. registerdaha fazla kod satırı ve 1 bellek yazma ve 1 bellek okuma üretir (gerçekçi olmasına rağmen, hesaplama yapıldıysa bu 0 R / W'ye optimize edilebilirdi esi, C ++ 'ları kullanarak olan şey budur const register). Kullanılmaması register2 yazma ve 1 okumaya neden olur (her ne kadar yük iletme deposu okumada gerçekleşir). Bunun nedeni, değerin doğrudan yığın üzerinde bulunması ve güncellenmesi gerektiğidir, böylece doğru değer adresle (işaretçi) okunabilir. registerbu gereksinimi yoktur ve gösterilemez. constve registertemelde karşıt olan volatileve kullananvolatiledosya ve blok kapsamındaki sabit optimizasyonları ve blok kapsamındaki optimizasyonları geçersiz kılar register. const registerve registeraynı çıktılar üretecektir çünkü const blok-kapsamındaki C üzerinde hiçbir şey yapmaz, bu nedenle sadece registeroptimizasyonlar geçerlidir.

Clang'da registergöz ardı edilir, ancak constoptimizasyonlar hala gerçekleşir.

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.