Ders 06 / 12
Geri Bildirim Döngüleri
Dört geri bildirim döngüsünün uzunluğu ve kapsadığı hata sınıfı: 2, 30, 240 ve 4320 dakikalık kümülatif uzunluklarda 120 hatanın 42'sinin yazarken, 21'inin tümleştirmede, 25'inin hazırlıkta yakalanması ve 32'sinin hiçbirine düşmeyip üretime kaçması, sınıf başına ortalama gecikmenin 2,0 dakikadan 3810,0 dakikaya kadar açılması, veri biçimi sınıfını tümleştirme döngüsüne taşımanın 12 dakika ekleyip toplam gecikmeyi 144954'ten 128520 dakikaya indirmesine karşılık sınıfın 12 hatasının yalnız 5'ini erken yakalaması, zamanlama sınıfını taşımanın 20 dakikaya 10 hatadan 1'ini kazandırması, ve üç taşımanın birlikte geri dönüş oranını %53'ten %42'ye indirirken öncü süreyi 351,9'dan 420,2 dakikaya çıkarması.
İçindekiler
Önceki ders bütçe kuralının olayı olduktan sonra gördüğünü ve ölçülen etkinin bu yüzden küçük kaldığını saydı. Sinyalin ne kadar geç geldiği bu konunun her dersinde bir yerde çıktı: gözlem alanı bölünmüşken 7,0 adım, sınırda düşen bağlamda 61,0 adım, üretim doğrulamasında bulunan sapmada altı adım geriye dönüş. Ama gecikmenin kaynağı — döngünün kendisi — hiç doğrudan sayılmadı.
Geri bildirim döngüsü, bir hatanın doğduğu andan onu düzeltebilecek role ulaştığı ana kadar geçen yoldur. Bir akışta tek bir döngü yoktur; birkaç tane vardır, her birinin ayrı bir uzunluğu ve ayrı bir kapsamı vardır. Hata bulma gecikmesi M20/K05’te ve M21/K05’te ölçüldü; burada ölçülen o gecikme değil, döngünün kendisidir: kaç tane var, her biri ne kadar sürüyor, hangi hata sınıfını kapsıyor ve bir sınıfı daha erken bir döngüye taşımanın bedeli ne.
Döngülerin Kurulması
Örnek yine kurgu bölgesel ölçüm ağıdır; ağ da döngüler de kurgudur. KA32: dört döngü vardır — yazarken, tümleştirmede, hazırlıkta, üretimde; her birinin bir uzunluğu vardır ve uzunluklar kümülatiftir, çünkü sinyal yazan role ancak zincirin o halkasında döner. KA33: sekiz hata sınıfı vardır ve dönemde 120 hata doğar; sınıf başına sayılar sabittir. KA34: her döngünün kapsadığı sınıflar ve o sınıf için bir yakalama oranı vardır; üretim döngüsü her sınıfı yakalar, çünkü orada hatayı kullanan bulur. KA35: üreteç yazılır, tohum 20260806’dır; her hata için döngü başına bir zar önceden atılır, böylece taşıma koşumlarında hatanın şansı değişmez. KA36: 120 hata 60 değişikliğe sırayla dağıtılır; bir değişikliğin öncü süresi hazırlık kümülatifi artı üretimden önce yakalanan her hatasının döngü kümülatifidir. KA37: bir hata sınıfını daha erken bir döngüye taşımak o döngüye bir denetim ekler: döngünün uzunluğu artar, sonraki döngülerin kümülatifi de kayar ve sınıf o döngüde daha düşük bir oranla yakalanır.
Döngüler, sınıflar ve taşıma süreç içi bir modeldir; gerçek bir hat ya da hata kaydı yoktur.
// dongu/dongu.mjs — geri bildirim dongulerinin modeli: gercek bir hat ya da hata kaydi yok, // dakikalar veri yapisidir. Rastgelelik uretecle yazilir, tohum gorunur. export const N_DEG = 60, TOHUM = 20260806; export const DONGU = [["yazarken", 2], ["tumlestirmede", 28], ["hazirlikta", 210], ["uretimde", 4080]]; // ad ve kendinden onceki dongudeki artis // hata sinifi: donemde kac tane dogar export const SINIF = { sozdizimi: 24, tip: 18, "birim-mantigi": 22, tumlesim: 14, "veri-bicimi": 12, yapilandirma: 12, zamanlama: 10, kaynak: 8 }; // kapsam: dongu -> sinif -> yakalama orani. Uretim dongusu her sinifi yakalar. export const KAPSAM = { yazarken: { sozdizimi: 1.00, tip: 0.90, "birim-mantigi": 0.20 }, tumlestirmede: { tip: 1.00, "birim-mantigi": 0.85, tumlesim: 0.35 }, hazirlikta: { "birim-mantigi": 0.60, tumlesim: 0.85, "veri-bicimi": 0.55, yapilandirma: 0.35, zamanlama: 0.20, kaynak: 0.15 }, uretimde: Object.fromEntries(Object.keys(SINIF).map((s) => [s, 1.00])), }; export function uretec(tohum) { // dogrusal eslesmeli uretec let x = tohum >>> 0; return () => ((x = (x * 1664525 + 1013904223) >>> 0) / 2 ** 32); } // tasima: bir hata sinifini daha erken bir donguye tasir; o dongunun uzunlugu ek kadar buyur. export function kos(tasima = []) { const artis = DONGU.map(([, a]) => a); const kapsam = Object.fromEntries(DONGU.map(([ad]) => [ad, { ...KAPSAM[ad] }])); for (const { sinif, dongu, oran, ek } of tasima) { kapsam[dongu][sinif] = oran; artis[DONGU.findIndex(([ad]) => ad === dongu)] += ek; } const kum = artis.map((_, i) => artis.slice(0, i + 1).reduce((s, v) => s + v, 0)); const zar = uretec(TOHUM); const H = Object.entries(SINIF).flatMap(([sinif, n]) => Array.from({ length: n }, () => ({ sinif, zarlar: DONGU.map(() => zar()) }))); H.forEach((h, i) => { h.deg = i % N_DEG; }); // hatalar degisikliklere sirayla dagitilir for (const h of H) { // hata hangi dongude yakalanir h.dongu = null; for (let i = 0; i < DONGU.length; i++) { const o = kapsam[DONGU[i][0]][h.sinif] ?? 0; if (h.zarlar[i] < o) { h.dongu = i; h.gecikme = kum[i]; break; } } } const D = Array.from({ length: N_DEG }, (_, i) => { const hatalar = H.filter((h) => h.deg === i); const erken = hatalar.filter((h) => h.dongu < DONGU.length - 1); return { i, hatalar, kacan: hatalar.filter((h) => h.dongu === DONGU.length - 1).length, oncu: kum[DONGU.length - 2] + erken.reduce((s, h) => s + kum[h.dongu], 0) }; }); return { H, D, kum, artis, kapsam }; } export const ort = (a) => (a.length ? (a.reduce((s, v) => s + v, 0) / a.length).toFixed(1) : "-"); export function olc(tasima = []) { const { H, D, kum, artis, kapsam } = kos(tasima); const kacan = H.filter((h) => h.dongu === DONGU.length - 1); const onculer = D.map((d) => d.oncu); return { H, D, kum, artis, kapsam, toplamGecikme: H.reduce((s, h) => s + h.gecikme, 0), ortGecikme: ort(H.map((h) => h.gecikme)), kacan: kacan.length, onculSure: ort(onculer), dagitimSikligi: (1440 / (onculer.reduce((s, v) => s + v, 0) / D.length)).toFixed(2), geriDonusOrani: (100 * D.filter((d) => d.kacan > 0).length / N_DEG).toFixed(0) + "%", kurtarma: kum[DONGU.length - 1] }; }
// dongu/olc.mjs — kac dongu var, uzunluklari ne, hangi hata sinifini kapsiyor; tasimanin bedeli. import { DONGU, SINIF, KAPSAM, TOHUM, olc, ort } from "./dongu.mjs"; const yaz = (g, ...s) => console.log(s.map((v, i) => (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join("")); const T = olc(); const toplam = Object.values(SINIF).reduce((s, v) => s + v, 0); console.log(`${DONGU.length} geri bildirim dongusu, ${Object.keys(SINIF).length} hata sinifi, ` + `${toplam} hata, tohum ${TOHUM}`); const A = [-15, 10, 12, 9, 11, 12]; console.log("\n1. donguler: uzunluk ve kapsam"); yaz(A, "dongu", "uzunluk", "kumulatif", "sinif", "yakalanan", "yakalanan %"); DONGU.forEach(([ad], i) => { const g = T.H.filter((h) => h.dongu === i); yaz(A, ad, T.artis[i], T.kum[i], Object.keys(KAPSAM[ad]).length, g.length, (100 * g.length / toplam).toFixed(0) + "%"); }); const B = [-14, 7, 16, 14, 15]; console.log("\n2. hata sinifi hangi donguye dusuyor"); yaz(B, "sinif", "hata", "ilk kapsayan", "ort. gecikme", "uretime kacan"); for (const [s, n] of Object.entries(SINIF)) { const g = T.H.filter((h) => h.sinif === s); const ilk = DONGU.findIndex(([ad]) => (KAPSAM[ad][s] ?? 0) > 0); yaz(B, s, n, DONGU[ilk][0], ort(g.map((h) => h.gecikme)), g.filter((h) => h.dongu === DONGU.length - 1).length); } const K = { "taban": [], "veri-bicimi tumlestirmeye": [{ sinif: "veri-bicimi", dongu: "tumlestirmede", oran: 0.45, ek: 12 }], "yapilandirma tumlestirmeye": [{ sinif: "yapilandirma", dongu: "tumlestirmede", oran: 0.30, ek: 8 }], "zamanlama tumlestirmeye": [{ sinif: "zamanlama", dongu: "tumlestirmede", oran: 0.10, ek: 20 }], "ucu birden": [{ sinif: "veri-bicimi", dongu: "tumlestirmede", oran: 0.45, ek: 12 }, { sinif: "yapilandirma", dongu: "tumlestirmede", oran: 0.30, ek: 8 }, { sinif: "zamanlama", dongu: "tumlestirmede", oran: 0.10, ek: 20 }], }; const R = Object.fromEntries(Object.entries(K).map(([ad, t]) => [ad, olc(t)])); const C = [-27, 13, 16, 14, 15]; console.log("\n3. bir hata sinifini erken donguye tasimanin bedeli"); yaz(C, "kosum", "tumlestirme", "toplam gecikme", "ort. gecikme", "uretime kacan"); for (const [ad, r] of Object.entries(R)) yaz(C, ad, r.artis[1], r.toplamGecikme, r.ortGecikme, r.kacan); const E = [-24, 17, 18, 13]; console.log("\n4. tasinan sinifin kendisinde ne oldu (taban degerleri parantezde)"); yaz(E, "sinif (eklenen sure)", "erken yakalanan", "ort. gecikme", "hala kacan"); for (const [ad, t] of Object.entries(K).slice(1, 4)) { const s = t[0].sinif, r = R[ad], g = r.H.filter((h) => h.sinif === s); const b = T.H.filter((h) => h.sinif === s), son = DONGU.length - 1; yaz(E, `${s} (+${t[0].ek} dk)`, `${g.filter((h) => h.dongu === 1).length}/${g.length}`, `${ort(g.map((h) => h.gecikme))} (${ort(b.map((h) => h.gecikme))})`, `${g.filter((h) => h.dongu === son).length} (${b.filter((h) => h.dongu === son).length})`); } const F = [-27, 12, 12, 14, 12]; console.log("\n5. dort teslimat olcutu"); yaz(F, "kosum", "dagitim", "oncu sure", "geri donus", "kurtarma"); yaz(F, "", "(deg./gun)", "(dakika)", "(degisiklik)", "(dakika)"); for (const [ad, r] of Object.entries(R)) yaz(F, ad, r.dagitimSikligi, r.onculSure, r.geriDonusOrani, r.kurtarma);
4 geri bildirim dongusu, 8 hata sinifi, 120 hata, tohum 20260806
1. donguler: uzunluk ve kapsam
dongu uzunluk kumulatif sinif yakalanan yakalanan %
yazarken 2 2 3 42 35%
tumlestirmede 28 30 3 21 18%
hazirlikta 210 240 6 25 21%
uretimde 4080 4320 8 32 27%
2. hata sinifi hangi donguye dusuyor
sinif hata ilk kapsayan ort. gecikme uretime kacan
sozdizimi 24 yazarken 2.0 0
tip 18 yazarken 5.1 0
birim-mantigi 22 yazarken 241.5 1
tumlesim 14 tumlestirmede 792.9 2
veri-bicimi 12 hazirlikta 2280.0 6
yapilandirma 12 hazirlikta 3300.0 9
zamanlama 10 hazirlikta 3096.0 7
kaynak 8 hazirlikta 3810.0 7
3. bir hata sinifini erken donguye tasimanin bedeli
kosum tumlestirme toplam gecikme ort. gecikme uretime kacan
taban 28 144954 1208.0 32
veri-bicimi tumlestirmeye 40 128520 1071.0 28
yapilandirma tumlestirmeye 36 136578 1138.2 30
zamanlama tumlestirmeye 48 142224 1185.2 31
ucu birden 68 117414 978.5 25
4. tasinan sinifin kendisinde ne oldu (taban degerleri parantezde)
sinif (eklenen sure) erken yakalanan ort. gecikme hala kacan
veri-bicimi (+12 dk) 5/12 844.5 (2280.0) 2 (6)
yapilandirma (+8 dk) 4/12 2558.0 (3300.0) 7 (9)
zamanlama (+20 dk) 1/10 2687.0 (3096.0) 6 (7)
5. dort teslimat olcutu
kosum dagitim oncu sure geri donus kurtarma
(deg./gun) (dakika) (degisiklik) (dakika)
taban 4.09 351.9 53% 4320
veri-bicimi tumlestirmeye 3.87 372.4 47% 4332
yapilandirma tumlestirmeye 4.00 360.3 50% 4328
zamanlama tumlestirmeye 3.71 388.1 52% 4340
ucu birden 3.43 420.2 42% 4360
Sayılar ölçüm sınıfındadır; girdileri yukarıdaki varsayımlardır.
Dört Döngü, Dört Uzunluk
Birinci tablo döngüleri yan yana koyar. Uzunluklar 2, 28, 210 ve 4080 dakikadır; kümülatif olarak 2, 30, 240 ve 4320. İki uçtaki oran 2160’tır. Yakalama dağılımı ise düz değildir: 120 hatanın 42’si yazarken (%35), 21’i tümleştirmede (%18), 25’i hazırlıkta (%21) yakalanır ve 32’si, yani dörtte biri, ilk üç döngünün hiçbirine düşmez.
Kapsam sütunu nedeni söyler. Yazarken döngüsü üç sınıfı, tümleştirme üç sınıfı, hazırlık altı sınıfı kapsar; üretim döngüsü sekizini birden kapsar, çünkü orada eleyen bir oran yoktur. Bir hata sınıfı hiçbir erken döngünün kapsamında değilse, döngü uzunluklarının hiçbir önemi kalmaz.
Toplam gecikme 144954 dakikadır ve bunun 138240’ı — otuz iki çarpı 4320 — yalnız üretime kaçan hatalardan gelir. Hataların dörtte biri, gecikmenin %95’ini taşır.
Hangi Sınıf Nerede Bulunuyor
İkinci tablo aynı sayıyı sınıf sınıf açar ve ortalama gecikme 2,0 dakikadan 3810,0 dakikaya kadar uzanır. Sözdizimi ve tip hataları ilk iki döngüde biter (2,0 ve 5,1 dakika) ve hiçbiri üretime kaçmaz. Birim mantığı üç ayrı döngünün kapsamındadır, ortalaması 241,5 dakikadır ve 22 hatasının yalnız biri kaçar.
Kaçan 32 hatanın 29’u ilk kez hazırlıkta kapsanan dört sınıftan gelir: yapılandırma 9, zamanlama 7, kaynak 7, veri biçimi 6. Bu dört sınıfın hazırlıktaki yakalama oranları 0,35, 0,20, 0,15 ve 0,55’tir; yani hazırlık bu sınıflar için bir döngü değil, bir elektir. Bir hata sınıfı ne kadar geç kapsanıyorsa, kapsandığı yerdeki yakalama oranı da o kadar düşüktür — çünkü sınıf geç kapsanıyorsa erken ortamda görünmeyen bir şeye bağlıdır.
Taşımanın Bedeli ve Kaçırdığı
Üçüncü tablo üç taşımayı ölçer. Veri biçimi sınıfını tümleştirme döngüsüne taşımak o döngüye 12 dakika ekler; toplam gecikme 144954’ten 128520 dakikaya (%11 azalma), üretime kaçan 32’den 28’e iner. Dördüncü tablo bunun karşılığını sınıfın kendisinde gösterir: on iki hatanın yalnız beşi erken yakalanır, sınıfın ortalama gecikmesi 2280,0’dan 844,5 dakikaya iner ve iki hata hâlâ kaçar (tabanda altı).
Zamanlama sınıfı bu kararın sınırıdır. Tümleştirme döngüsüne taşımak 20 dakika ister — üç taşımanın en pahalısı — ve on hatanın birini kazanır; kaçan 7’den 6’ya iner, toplam gecikme yalnız 2730 dakika azalır. Toplu iş penceresi tümleştirme ortamında yoktur, dolayısıyla oran 0,10’dur. En pahalı taşıma en az kazandırandır ve nedeni oranda yazılıdır.
Beşinci tablo dört ölçütü verir. Üç taşımanın üçü de aynı işareti taşır: geri dönüş oranı iyileşir (%53’ten %47, %50 ve %52’ye), öteki üçü bozulur. Üçü birden uygulandığında tümleştirme döngüsü 28 dakikadan 68 dakikaya çıkar; kaçan hata 32’den 25’e, geri dönüş oranı %42’ye iner, ama dağıtım sıklığı 4,09’dan 3,43 değişiklik/güne, öncü süre 351,9’dan 420,2 dakikaya ve kurtarma süresi 4320’den 4360 dakikaya gider. Döngüyü uzatmak, o döngüden geçen her değişikliğin faturasıdır.
Farkın Saklandığı Yer
Bu derste fark döngü kapsamında saklıdır ve sayısı şudur: sekiz sınıfın dördü ilk iki döngünün hiçbirinde kapsanmaz, biri hiçbir erken döngüde 0,20’nin üstünde bir oranla kapsanmaz. Bildirilmiş kısım döngü uzunluklarıdır — 2, 30, 240, 4320 dakika; herkes okuyabilir. Bildirilmemiş kısım kapsamdır: hangi döngünün hangi sınıfı hangi oranla yakaladığı ancak koşumda görünür.
Sinyalin kime kaç adımda ulaştığı da buradan okunur: sözdizimi hatası yazan role 2,0 dakikada, kaynak hatası 3810,0 dakikada ulaşır. Aynı rol, aynı akış, aynı akıştaki aynı değişiklik — 1905 katlık fark yalnız hata sınıfından gelir.
Özet
- Dört döngünün uzunlukları kümülatif olarak 2, 30, 240 ve 4320 dakikadır; 120 hatanın 42’si yazarken, 21’i tümleştirmede, 25’i hazırlıkta yakalanır, 32’si hiçbirine düşmez.
- Kaçan 32 hatanın 29’u ilk kez hazırlıkta kapsanan dört sınıftandır (yapılandırma 9, zamanlama 7, kaynak 7, veri biçimi 6) ve o sınıfların hazırlıktaki yakalama oranları 0,15 ile 0,55 arasındadır.
- Sınıf başına ortalama gecikme 2,0 dakikadan 3810,0 dakikaya açılır; fark döngü uzunluğundan değil, sınıfın hangi döngüde kapsandığından gelir.
- Veri biçimini tümleştirmeye taşımak 12 dakikaya 12 hatanın 5’ini kazandırır ve toplam gecikmeyi %11 düşürür; zamanlamayı taşımak 20 dakikaya 10 hatanın 1’ini kazandırır.
- Üç taşıma birlikte kaçan hatayı 32’den 25’e ve geri dönüş oranını %53’ten %42’ye indirirken dağıtım sıklığını 4,09’dan 3,43’e, öncü süreyi 351,9’dan 420,2 dakikaya taşır.
Sonraki Adım
Döngüler kuruldu ve sinyalin kime kaç adımda ulaştığı sayıldı: gözlem alanında 7,0 adım, sınırda düşen bağlamda 61,0 adım, döngü kapsamında 2,0 ile 3810,0 dakika arası. Altı dersin altısı da aynı şeyi ölçtü — farkın nerede saklandığını.
Ama bütün bu ölçümler sessiz bir varsayımın üstünde durdu: aynı yazılımın her ortamda aynı yazılım olduğu. Bir hatanın hazırlıkta yakalanmayıp üretimde çıkması, yukarıdaki modelde bir oran olarak yazıldı — 0,35, 0,20, 0,15. O oranın neden bir olmadığı hiç sorulmadı. Geliştiricinin makinesinde çalışan ile üretimde koşan aynı şey değildir; aralarında bir fark vardır ve bu konu boyunca o farkın adı bile konmadı. Sonraki konu tam oradan başlar: ortamlar nedir, zincirin her halkasında hangi fark saklanır ve halkayı atlamanın bedeli nedir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.