---
title: 'Optimizasyon Düzeyleri'
source: 'https://academia.sh/tr/kurslar/c-sistem-programlama/optimizasyon-duzeyleri'
course: 'C ile Sistem Programlama'
language: tr
updated: '2026-09-26T03:02:44+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'as-if kuralının bir yazmayı ne zaman silmeye izin verdiğini bir model üzerinden gösterir'
    - 'volatile işaretli bir yazmanın neden silinmediğini açıklar'
    - 'kursun on beş değişikliğini sınıflarına göre bir tabloda toplar'
---

# Optimizasyon Düzeyleri

Eniyileyicinin okunmayan bir yazmayı sildiği model üzerinden as-if kuralı, volatile'ın verdiği garanti ve kursun on beş dersinin toplu dökümü.

Bir önceki ders, hata ayıklayıcının gördüğü değerin kaynaktaki yazımla her zaman
aynı olmadığını söyleyerek kapandı: bir değişken yazmaçta tutulmuş ya da
tamamen silinmiş olabilir. Bu ders o farkın nereden geldiğini ele alıyor.
Eniyileyici, gözlenebilir davranışı değiştirmeyen bir yazmayı kaldırabilir —
kaldırdığı yazma hiçbir okuyucuya ulaşmaz. Kurs bunu tek bir soruyla ölçüyordu:
bu değişikliği kim görüyor? Eniyileme için yanıt, geri kalan on dört değişiklikten
farklı bir yoldan **gözlenmeyen**e varıyor: burada ne bir kopyalama var ne de bir
aracı. Yazma vardır, ama hiçbir okuma ona ulaşmadan üstüne başka bir yazma gelir.

## Okunmadan Ezilen Yazma

Bir akışı üç adımla düşünün: bir yere 1 yazılır, aynı yere 2 yazılır, sonra o
konum bir yerde okunur. Birinci yazmanın etkisi, ikinci yazma gelene kadar hiç
okunmadıysa, ikinci yazma geldiğinde birinci yazmanın konumdaki izi tamamen
kaybolmuştur. Programın davranışını gözleyen hiçbir taraf — ne bir dosyaya
yazılan çıktı, ne bir başka sürece giden bir değer, ne de bir kilitle korunan
paylaşılan durum — birinci yazmanın hiç var olup olmadığını ayırt edemez.
Program birinci yazmayı hiç yapmasa da gözlenen sonuç değişmez.

**PA10.** Bir eniyileyici modeli, ardışık iki yazma arasında hiçbir okuma
olmadığını tespit ettiğinde birincisini kaldırabilir; kaldırmasa da gözlenebilir
sonuç aynıdır.

Ölçüm, kursun çekirdeğiyle aynı kayıt biçimini kullanıyor:

```c
// gozlem.h — bir degisikligin kime ulastigini siniflayan kayit
#ifndef GOZLEM_H
#define GOZLEM_H

enum Sinif { KOPYA, ORTAK, AKTARIM, GOZLENMEYEN };

/* Bir degisikligi kaydeder: gordu, degisikligi yapmayan tarafin onu
   okuyup okuyamadigidir (1 ya da 0). */
void gozlem(const char *degisiklik, enum Sinif sinif, int gordu);

/* Sinif basina sayilari ve ulasan / ulasmayan toplamini basar. */
void gozlem_ozeti(void);

#endif
```

```c
// gozlem.c — sayilar yalniz bu birimde tutulur
#include <stdio.h>
#include "gozlem.h"

static const char *const adlar[] = { "kopya", "ortak", "aktarim", "gozlenmeyen" };
static int sayilar[4];
static int ulasan = 0;
static int ulasmayan = 0;

void gozlem(const char *degisiklik, enum Sinif sinif, int gordu) {
    int beklenen = (sinif == ORTAK || sinif == AKTARIM);
    sayilar[sinif]++;
    if (gordu) {
        ulasan++;
    } else {
        ulasmayan++;
    }
    printf("%-34s %-8s %s%s\n", degisiklik, gordu ? "gordu" : "gormedi",
           adlar[sinif], gordu == beklenen ? "" : "  TUTARSIZ");
}

void gozlem_ozeti(void) {
    printf("siniflar: kopya %d, ortak %d, aktarim %d, gozlenmeyen %d\n",
           sayilar[KOPYA], sayilar[ORTAK], sayilar[AKTARIM], sayilar[GOZLENMEYEN]);
    printf("ulasan %d, ulasmayan %d\n", ulasan, ulasmayan);
}
```

Aşağıdaki kesit, kursun çekirdeğinden alınıyor ve bu dersin kendi kesitidir —
adları ve gövdesi kurs boyunca değişmez:

```c
// eniyileyici_olcumu.c — gorur.c'deki eniyileme kesiti, degistirilmeden
#include <stdio.h>
#include "gozlem.h"

struct Adim {
    char islem;
    int deger;
};
static void eniyileme(void) {
    struct Adim akis[] = { { 'y', 1 }, { 'y', 2 }, { 'o', 0 } };
    int okuyan = 0;
    int son_yazma = -1;
    for (int i = 0; i < 3; i++) {
        if (akis[i].islem == 'y') {
            son_yazma = i;
        } else if (son_yazma == 0) {
            okuyan++;
        }
    }
    gozlem("okunmadan ezilen yazma", GOZLENMEYEN, okuyan > 0);
}

int main(void) {
    eniyileme();
    gozlem_ozeti();
    return 0;
}
```

```text
okunmadan ezilen yazma             gormedi  gozlenmeyen
siniflar: kopya 0, ortak 0, aktarim 0, gozlenmeyen 1
ulasan 0, ulasmayan 1
```

`akis` dizisi üç adımı taşıyor: `y` bir yazma, `o` bir okuma. Döngü, her okuma
adımında en son hangi yazmanın etkili olduğunu (`son_yazma`) yokluyor. Okuma
geldiğinde `son_yazma` hâlâ **sıfırıncı** yazmayı gösteriyorsa (`son_yazma == 0`),
o okuma birinci yazmanın değerini görmüş sayılır ve `okuyan` artıyor. Bu
modelde `akis` sırasıyla `y=1`, `y=2`, `o` içeriyor: ikinci adım birinciyi
`son_yazma`yı 1'e taşıyarak ezmiş oluyor; üçüncü adımdaki okuma geldiğinde
`son_yazma` artık 0 değil, 1. Birinci yazmayı gören hiçbir okuma yok — `okuyan`
sıfırda kalıyor. `gozlem` çağrısı bunu `GOZLENMEYEN` sınıfıyla ve `gordu`
alanına `okuyan > 0` (yani 0, yanlış) vererek kaydediyor.

Bu, bir eniyileyicinin okunmayan bir yazmayı neden **silebileceğinin** modelidir:
birinci yazma hiç yapılmasa da `son_yazma` dizisi ve dolayısıyla `okuyan` sayısı
aynı kalır. Program iki yazma yerine tek yazma içerseydi — doğrudan 2 yazsaydı —
gözlenebilir sonuç (üçüncü adımın ne okuduğu) değişmezdi. Model bu yüzden
`okunmadan ezilen yazma`yı `gözlenmeyen` sınıfına koyuyor: değişiklik yapılmış,
ama hiçbir okuyucuya ulaşmamış.

## As-if Kuralı

Bir eniyileyicinin bir yazmayı silme hakkı keyfi değildir; tek bir koşula bağlıdır:
**as-if kuralı** ("sanki kuralı"). Bu kural, bir programın çalışma zamanı davranışı
**gözlenebilir davranış** kümesi üzerinden tanımlanır ve eniyileyici bu kümeyi
koruduğu sürece programın adım adım nasıl çalıştığını istediği gibi değiştirebilir
— sanki kaynaktaki sırayla çalışıyormuş gibi görünmesi yeterlidir, gerçekten öyle
çalışması gerekmez. Gözlenebilir davranış üç şeyle sınırlıdır: girdi/çıktı
işlemlerinin sırası ve içeriği, `volatile` işaretli nesnelere yapılan erişimler ve
programın sonlanma durumu. Yukarıdaki modelde birinci yazma bunların hiçbirine
girmiyor: bir dosyaya yazılmıyor, `volatile` değil, programın sonlanmasını
etkilemiyor. Bu yüzden silinmesi as-if kuralını ihlal etmez.

**PA11.** Bir yazma ancak gözlenebilir davranışın **hiçbir** parçasına
girmiyorsa okunmadan ezilebilir; girdiği an bu hak düşer.

As-if kuralı çekirdeğin diğer on dört ölçümüyle çelişmiyor, onları tamamlıyor.
`fork` sonrası çocuğun değiştirdiği değişken (kopya sınıfı) as-if kuralına konu
değildir — o, iki ayrı belleğin varlığıyla ilgilidir, tek bir sürecin içindeki
yazma sırasıyla değil. İşleyicinin kaldırdığı bayrak (aktarım sınıfı) ise tam
tersi yönden as-if kuralına giriyor: `volatile sig_atomic_t` işaretli olduğu için
eniyileyici o yazmaya asla dokunamaz — bir sonraki bölüm bunu ayrıntılandırıyor.

## Volatile'ın Verdiği Garanti

`volatile` anahtar sözcüğü bir değişkene uygulandığında, derleyiciye o değişkene
yapılan her okuma ve yazmanın gözlenebilir davranışın bir parçası sayılmasını
söyler. Bunun sonucu doğrudandır: `volatile` işaretli bir yazma, ardından hiçbir
okuma gelmese bile silinemez; `volatile` işaretli bir okuma, sonucu hiçbir yerde
kullanılmasa bile atlanamaz. Sinyaller dersindeki `bayrak` değişkeni tam olarak bu
yüzden `volatile sig_atomic_t` olarak tanımlanmıştı: bir işleyicinin kaldırdığı
bayrağı ana akış okumadan önce eniyileyici o yazmayı "kimse okumuyor" diye
silebilseydi, aktarım hiç gerçekleşmezdi.

Modelin diliyle söylenirse: `akis` dizisindeki konum `volatile` işaretli olsaydı,
birinci yazma okunmadan ezilse de silinemezdi, çünkü yazmanın kendisi gözlenebilir
davranışın parçası sayılırdı. Bu, kaydın sınıfını değiştirmez — ikinci yazma
geldiğinde birinci yazmanın değerini yine hiçbir okuma görmemiştir ve kayıt yine
`gözlenmeyen`dir. Değişen tek şey eniyileyicinin hakkıdır: yazma programda kalır,
yalnız okuyucuya ulaşmaz. Ders bunu ayrı bir kodla ölçmüyor; `volatile`'ın etkisi
eniyileyicinin ürettiği kodda görünür ve kaynak metindeki bir model o kodu
basamaz. Bu dersin `main` işlevi `eniyileme`'yi ve ardından `gozlem_ozeti`'yi
çağırıyor; çıktı, `gormedi` ile işaretlenmiş tek kaydın `gözlenmeyen` sınıfına
düştüğünü gösteriyor.

`volatile`'ın verdiği garanti dardır ve genişletilmemelidir. Tek başına iş
parçacıkları arasında sıralama sağlamaz, atomiklik sağlamaz, bellek bariyeri
kurmaz — POSIX İş Parçacıkları dersindeki kilit ve birleştirme (`join`) hâlâ
gereklidir. `volatile`'ın verdiği tek şey, o nesneye yapılan erişimlerin
eniyileyici tarafından silinmeyeceği ve sırasının korunacağı garantisidir; bu,
bir sinyal işleyicisi ile ana akış arasındaki tek paylaşım biçiminin neden
`volatile sig_atomic_t` olduğunu açıklar.

## Sınırlayıcı Ölçüm

Model, bir yazmanın silinip silinmeyeceğine tek bir kurala — gözlenebilir
davranışın korunup korunmadığına — bakarak karar veriyor. Gerçek bir eniyileyici
bu kararı çok daha geniş bir bilgiyle verir: bir değişkenin adresi alınmış mı,
başka bir çeviri biriminden görünür mü, bir işaretçi üzerinden takma adlanmış
olabilir mi. Bu ders eniyileme düzeyini bir bayrakla yazmıyor,
derleyici çıktısını, üretilen kodu ya da bir ölçümün süresini basmıyor — çünkü
bunların hiçbiri kaynak metindeki bir modelle gösterilemez; gerçek bir aracın
gerçek kararıdır. Model yalnız kuralın kendisini gösteriyor: hangi yazmaların
silinebileceğini, hangilerinin silinemeyeceğini. Bir yazmanın adresi başka bir
işlevce tutuluyorsa, o işlev geri çağrıldığında konumu okuyabilir; bu durumda
yazma artık gözlenebilir davranışın bir parçasıdır ve modeldeki gibi sessizce
silinemez. Modelin bunu göstermemesi bir eksiklik değil, sınırdır: kesit yalnız
tek bir akış içindeki ardışık yazmaları ele alıyor, çapraz işlev görünürlüğünü
değil.

## Özet

- `okunmadan ezilen yazma` (model): bir konuma art arda yapılan iki yazmadan
  birincisi hiç okunmadan ikincisi geliyorsa, birincinin izi kalmıyor.
- As-if kuralı, eniyileyicinin bir yazmayı ancak gözlenebilir davranışı
  değiştirmeyecekse silebileceğini söylüyor; gözlenebilir davranış girdi/çıktı,
  `volatile` erişimleri ve sonlanma durumuyla sınırlı.
- `volatile`, bir nesneye yapılan her erişimi gözlenebilir davranışın parçası
  sayar; bu yüzden `volatile` işaretli bir yazma hiç okunmasa bile silinmez.
- Sinyaller dersindeki `volatile sig_atomic_t` bu garantiyi kullanıyordu: bir
  işleyicinin kaldırdığı bayrak, ana akış onu henüz okumamış olsa da eniyileyici
  tarafından silinemez.
- Bu dersin ölçtüğü sınıf **gözlenmeyen**: yazma yapılıyor ama hiçbir okuyucuya
  ulaşmıyor — ne yazanın kendi tarafında kalıyor (kopya), ne bir aracıdan geçip
  bir kez görünüyor (aktarım); ezilip kayboluyor.
- Model gerçek bir eniyileyicinin kararını değil, kararın dayandığı kuralı
  gösteriyor; adres alma ve çapraz işlev görünürlüğü modelin kapsamı dışında.

## Kurs Kapanışı

Kurs on beş ders boyunca tek bir soruyu sordu: **bu değişikliği kim görüyor?**
Bu ders o soruyu son kez yanıtlıyor ve yanıt geri kalan on dördünden farklı bir
yoldan gözlenmeyene varıyor — yazma var, okuyucu yok, çünkü bir sonraki yazma
araya girmeden okuma hiç gelmedi. Aşağıdaki tablo on beş değişikliğin tümünü
topluyor:

| Ders | Ölçülen değişiklik | Kim görüyor | Sınırlayıcı ölçüm |
|---|---|---|---|
| Dosya Tanıtıcıları | `dup` ile çoğaltılan tanıtıcının paylaştığı konum | ortak | Tanıtıcı numarası neyin paylaşıldığını söylemez; paylaşım yalnız konum davranışıyla ölçülür |
| Süreç Yönetimi | `fork` sonrası çocuğun değiştirdiği değişken | kopya | Ölçüm zamanlamaya bağlı değildir; bir yarışı değil, iki kopyanın bağımsız olduğunu ölçer |
| Sinyaller | İşleyicinin kaldırdığı bayrak | aktarım | Engellenmişken tekrar gelen aynı sinyal açılışta yalnız bir kez teslim edilir |
| Süreçler Arası İletişim | Boruya yazılan değer | aktarım | Boru bir akıştır, ileti sınırı taşımaz; sınır ayrı bir uzunluk önekiyle kurulur |
| POSIX İş Parçacıkları | İş parçacığının kilit altında yazdığı sayaç | ortak | Yalnız son değer doğrulanır; ara durumlar ve yazma sırası ölçülmez |
| Bağlı Yapılar | Takma adla değişen düğüm | ortak | Bir işaretçinin paylaşımı kaynakta görünmez; iki başın aynı düğümü gösterip göstermediği eşitlikle ölçülür |
| Halka Arabellek ve Kuyruklar | Halkaya konan öge | aktarım | Okuma işlevinin imzası değerin yapıda kalıp kalmadığını söylemez; bu, art arda iki okumayla ölçülür |
| Karma Tabloları | Eklendikten sonra değişen anahtar | kopya | Ekleme işlevinin imzası anahtarın kopyalanıp kopyalanmadığını söylemez; anahtar işaretçiyle tutulsaydı sınıf ortak olurdu |
| Nesne Benzeri Tasarım | Bir kullanıcının yaptığı yatırma | ortak | Arayüzün biçimi (opak tip, işlev işaretçileri, düz işlevler) paylaşımı belirlemez; yalnız işaretçi eşitliği belirler |
| Kaynak Temizleme Deyimleri | Boşaltılmadan çıkılan tampon | gözlenmeyen | Gözlenmeyen, hiçbir yere ulaşmamak demektir; bu, değer basılmadan `== NULL` denetimleriyle doğrulanır |
| Derleme Sistemleri | Bağımlılığı yazılmamış başlık | kopya | Model yalnız yazılmış bağımlılığı görür; gerçekte hangi başlığın okunduğunu kendi başına bilmez |
| Kütüphane Üretimi | Statik bağlı kütüphane güncellemesi | kopya | Model yalnız hangi değere ulaşıldığını ölçer; arayüz değişirse işaretçiye dayalı güvence kaybolur ve bu durum koşturulmaz |
| Test Çerçeveleri | Yalıtılmış testin değişikliği | kopya | Süreç yalıtımı bellek değişikliğini keser, dosya sistemi değişikliğini kesmez |
| Hata Ayıklayıcı Kullanımı | İki durak arasındaki ara değer | gözlenmeyen | Kesme ve gözetleme noktası çalışan bir süreci gözler, çekirdek dökümü durmuş olanı okur; döküm üretilmez |
| Optimizasyon Düzeyleri | Okunmadan ezilen yazma | gözlenmeyen | Model yalnız tek akış içindeki ardışık yazmaları ele alır; adres alma kapsam dışı |

**5 kopya · 4 ortak · 3 aktarım · 3 gözlenmeyen.**

Bu dağılım, çekirdeğin on beş gözleminin dağılımıyla aynıdır — beklenmedik bir
uyuşma değil, çünkü çekirdek her ders için tam olarak bir gözlem taşıyor ve her
ders kendi kesitini o gözlemden alıyor. Yedi değişiklik öteki tarafa ulaştı, sekizi
ulaşmadı; ulaşanlar bir aracıdan (aktarım) ya da paylaşılan bir nesneden (ortak)
geçti, ulaşmayanlar ya yazanın kendi tarafında kaldı (kopya) ya da hiçbir yerde
durmadı (gözlenmeyen). Bu ayrım kursun başından beri aynı kaldı: bir değişikliğin
**yapılmış olması**, onun **görülmüş olmasını** garanti etmez.

Kurs boyunca aynı soru farklı düzeylerde tekrar sorulmuş oldu — iki sürecin belleği
arasında, bir işleyici ile ana akış arasında, iki iş parçacığının paylaştığı
bellekte, bir derleme biriminin başka birine bıraktığı izde ve son olarak bir
eniyileyicinin sildiği tek bir yazmada. Her düzeyde yanıt aynı dört sınıftan
birine düştü; sınıfların sayısı değişmedi, yalnız hangi düzeneğin hangi sınıfa
girdiği değişti.

Bir sonraki kurs (C++ Temelleri ve Nesne Tasarımı) sınıflar ve kaynak yönetimi
konusunu ele alıyor; kendi ölçü eksenini kendi ilk dersinde kuracak.
