Professional Documents
Culture Documents
Operating System Concepts 10th Edition 2018 Booksfree - Org 301 600
Operating System Concepts 10th Edition 2018 Booksfree - Org 301 600
• SCHED FIFO
• SCHED RR
SCHED FIFO , Bölüm 5.3.1'de özetlendiği gibi bir FIFO kuyruğu kullanarak ilk
gelen, ilk hizmet alır ilkesine göre iş parçacıklarını programlar . Ancak, eşit önceliğe
sahip iş parçacıkları arasında zaman dilimleme yoktur. Bu nedenle, FIFO kuyruğunun
önündeki en yüksek öncelikli gerçek zamanlı iş parçacığına, sonlandırılana veya
bloke olana kadar CPU verilecektir . SCHED RR , bir döngüsel deneme ilkesi kullanır.
Eşit öncelikli iş parçacıkları arasında zaman dilimleme sağlaması dışında SCHED
FIFO'ya benzer . POSIX , ek bir zamanlama sınıfı—SCHED OTHER— sağlar , ancak
uygulaması tanımlanmamıştır ve sisteme özeldir; farklı sistemlerde farklı davranabilir.
POSIX API , zamanlama ilkesini almak ve ayarlamak için aşağıdaki iki işlevi belirtir:
Her iki işlevin ilk parametresi, iş parçacığı için nitelikler kümesine yönelik bir
işaretçidir. İkinci parametre, (1) geçerli zamanlama ilkesine ( pthread attr getched
policy() için) ayarlanmış bir tamsayıya yönelik bir işaretçi veya (2) pthread attr setched
ilke() işlevi. Bir hata oluşursa her iki işlev de sıfır olmayan değerler döndürür.
Linux'ta süreç programlamanın ilginç bir geçmişi vardır. Sürüm 2.5'ten önce, Linux
çekirdeği, geleneksel UNIX zamanlama algoritmasının bir varyasyonunu çalıştırıyordu.
Ancak bu algoritma SMP sistemleri düşünülerek tasarlanmadığından, birden çok
işlemcili sistemleri yeterince desteklemiyordu. Ayrıca, çok sayıda çalıştırılabilir sürece
sahip sistemler için düşük performansa neden oldu. Çekirdeğin 2.5 Sürümü ile,
zamanlayıcı , sistemdeki görev sayısından daha azını dikkate alarak sabit zamanda
çalışan O(1) olarak bilinen bir zamanlama algoritmasını içerecek şekilde elden
geçirildi . O (1) zamanlayıcı da sağlanır
5.7 İşletim Sistemi Örnekleri 235
Machine Translated by Google
işlemci benzerliği ve işlemciler arasında yük dengeleme dahil olmak üzere SMP
sistemleri için artırılmış destek . Bununla birlikte, pratikte, O(1) zamanlayıcı SMP
sistemlerinde mükemmel performans sunmasına rağmen, birçok masaüstü bilgisayar
sisteminde yaygın olan etkileşimli işlemler için yetersiz yanıt sürelerine yol açtı. 2.6
çekirdeğinin geliştirilmesi sırasında, zamanlayıcı yeniden revize edildi; ve çekirdeğin
2.6.23 sürümünde, Tamamen Adil Zamanlayıcı (CFS) , varsayılan Linux zamanlama
algoritması oldu.
Linux sisteminde çizelgeleme, çizelgeleme sınıflarına dayalıdır . Her sınıfa belirli bir
öncelik atanır. Çekirdek, farklı zamanlama sınıfları kullanarak, sistemin ve süreçlerinin
ihtiyaçlarına göre farklı zamanlama algoritmalarını barındırabilir. Örneğin, bir Linux
sunucusu için zamanlama kriterleri, Linux çalıştıran bir mobil cihaz için olanlardan farklı
olabilir. Daha sonra hangi görevin çalıştırılacağına karar vermek için zamanlayıcı, en
yüksek öncelikli zamanlama sınıfına ait olan en yüksek öncelikli görevi seçer. Standart
Linux çekirdekleri iki zamanlama sınıfı uygular: (1) CFS zamanlama algoritmasını kullanan
bir varsayılan zamanlama sınıfı ve (2) bir gerçek zamanlı zamanlama sınıfı. Bu sınıfların
her birini burada tartışıyoruz. Yeni zamanlama sınıfları elbette eklenebilir.
CFS PERFORMANSI
Linux CFS zamanlayıcısı, bir sonraki görevin çalıştırılacağını seçmek için verimli bir
algoritma sağlar. Standart bir kuyruk veri yapısı kullanmak yerine, çalıştırılabilir her
görev kırmızı-siyah bir ağaca - anahtarı vruntime değerine dayanan dengeli bir ikili
arama ağacına - yerleştirilir. Bu ağaç aşağıda gösterilmiştir.
T0
en küçük vruntime
T1 T2
değerine sahip görev
T3 T4 T5 T6
T7 T8 T9
Bir görev çalıştırılabilir hale geldiğinde ağaca eklenir. Ağaçtaki bir görev
çalıştırılamazsa (örneğin, G/Ç beklerken engellenirse), kaldırılır. Genel olarak
konuşursak, daha az işlem süresi verilen görevler ( vruntime'ın daha küçük
değerleri) ağacın sol tarafındadır ve daha fazla işlem süresi verilen görevler sağ
taraftadır. İkili arama ağacının özelliklerine göre, en soldaki düğüm en küçük
anahtar değere sahiptir, bu da CFS zamanlayıcısı için en yüksek önceliğe sahip
görev olduğu anlamına gelir. Kırmızı-siyah ağaç dengeli olduğundan, en soldaki
düğümü keşfetmek için gezinmek O(log N) işlemlerini gerektirir (burada N ,
ağaçtaki düğüm sayısıdır). Bununla birlikte, verimlilik nedenleriyle, Linux
zamanlayıcı bu değeri en soldaki rb değişkeninde önbelleğe alır ve bu nedenle
bir sonraki hangi görevin çalıştırılacağını belirlemek yalnızca önbelleğe alınan
değerin alınmasını gerektirir.
sonuçta G/Ç'ye bağlı görev için CPU'ya bağlı görevden daha düşük olur ve G/Ç'ye bağlı
göreve CPU'ya bağlı görevden daha yüksek öncelik verir . Bu noktada, G/Ç'ye bağlı
görev çalışmaya uygun hale geldiğinde (örneğin, görevin beklediği G/Ç kullanılabilir
hale geldiğinde) CPU'ya bağlı görev yürütülüyorsa, G/Ç'ye bağlı görev öncelikli
olacaktır . CPU'ya bağlı görev .
Linux ayrıca Bölüm 5.6.6'da açıklandığı gibi POSIX standardını kullanarak gerçek
zamanlı zamanlama uygular . SCHED FIFO veya SCHED RR gerçek zamanlı ilkesi
kullanılarak zamanlanan herhangi bir görev , normal (gerçek zamanlı olmayan)
görevlerden daha yüksek bir öncelikte çalışır. Linux, biri gerçek zamanlı görevler için
diğeri normal görevler için olmak üzere iki ayrı öncelik aralığı kullanır. Gerçek zamanlı
görevlere 0 ila 99 aralığında statik öncelikler atanır ve normal görevlere 100 ila 139 arasında öncelikler atanır.
Bu iki aralık, sayısal olarak daha düşük değerlerin daha yüksek göreli öncelikleri
gösterdiği bir küresel öncelik şemasına eşlenir. Normal görevlere öncelik verilir
Machine Translated by Google
öncelik
-20 haritanın değeri 100'e ve +19 haritanın nice değerinin 139'a denk geldiği nice
değerlerine dayalıdır. Bu şema Şekil 5.26'da gösterilmektedir.
CFS zamanlayıcı, aynı zamanda NUMA'nın farkında olduğu ve iş parçacıklarının
geçişini en aza indiren, işleme çekirdekleri arasındaki yükü eşitleyen karmaşık bir
teknik kullanarak yük dengelemeyi de destekler . CFS , her iş parçacığının yükünü, iş
parçacığının önceliği ile ortalama CPU kullanım oranının bir birleşimi olarak tanımlar.
Bu nedenle, yüksek önceliğe sahip, ancak çoğunlukla G/Ç'ye bağlı olan ve az CPU
kullanımı gerektiren bir iş parçacığı, yüksek CPU kullanımına sahip düşük öncelikli bir
iş parçacığının yüküne benzer şekilde, genellikle düşük bir yüke sahiptir . Bu metriği
kullanarak, bir kuyruğun yükü, kuyruktaki tüm iş parçacıklarının yüklerinin toplamıdır
ve dengeleme, basitçe tüm sıraların yaklaşık olarak aynı yüke sahip olmasını sağlamaktır.
Bununla birlikte, Bölüm 5.5.4'te vurgulandığı gibi, bir iş parçacığının taşınması,
önbellek içeriklerinin geçersiz kılınması veya NUMA sistemlerinde daha uzun bellek
erişim sürelerine maruz kalması nedeniyle bellek erişim cezasına neden olabilir. Bu
sorunu çözmek için Linux, hiyerarşik bir zamanlama etki alanı sistemi tanımlar.
Bir zamanlama alanı , birbirine karşı dengelenebilen bir dizi CPU çekirdeğidir. Bu fikir
Şekil 5.27'de gösterilmektedir. Her bir zamanlama alanındaki çekirdekler, sistemin
kaynaklarını nasıl paylaştıklarına göre gruplandırılır.
Örneğin, Şekil 5.27'de gösterilen her çekirdeğin kendi seviye 1 (L1) önbelleği
olmasına rağmen, çekirdek çiftleri seviye 2 (L2) önbelleğini paylaşır ve bu nedenle
ayrı domain0 ve domain1 olarak düzenlenir. Benzer şekilde, bu iki alan bir seviye 3 (L3)
önbelleğini paylaşabilir ve bu nedenle işlemci düzeyinde bir alan ( NUMA düğümü
olarak da bilinir) halinde düzenlenir . Bir NUMA sisteminde bunu bir adım daha ileri götürerek,
çekirdek2
çekirdek0
L2 L2
çekirdek3
çekirdek1
L3
Şekil 5.27 Linux CFS zamanlayıcı ile NUMA uyumlu yük dengeleme.
Machine Translated by Google
sistem düzeyinde daha büyük bir etki alanı, ayrı işlemci düzeyinde NUMA düğümlerini
birleştirir.
CFS'nin arkasındaki genel strateji , hiyerarşinin en alt seviyesinden başlayarak, etki
alanları içindeki yükleri dengelemektir. Örnek olarak Şekil 5.27'yi kullanarak, başlangıçta
bir iş parçacığı yalnızca aynı etki alanındaki (yani, etki alanı0 veya etki alanı1 içindeki )
çekirdekler arasında göç eder. Bir sonraki düzeyde yük dengeleme, etki alanı0 ve etki
alanı1 arasında gerçekleşir . CFS , bir iş parçacığı yerel belleğinden daha uzağa
taşınacaksa, iş parçacıklarını ayrı NUMA düğümleri arasında taşıma konusunda isteksizdir
ve bu tür geçiş yalnızca ciddi yük dengesizlikleri altında gerçekleşir. Genel bir kural
olarak, genel sistem meşgulse, CFS , NUMA sistemlerinin bellek gecikme cezalarından
kaçınmak için her bir çekirdeğe yerel etki alanının ötesinde yük dengelemesi yapmaz .
Dağıtıcı, iş parçacığı yürütme sırasını belirlemek için 32 düzeyli bir öncelik şeması
kullanır. Öncelikler iki sınıfa ayrılır. Değişken sınıf , 1'den 15'e kadar önceliklere sahip iş
parçacıklarını içerir ve gerçek zamanlı sınıf , 16'dan 31'e kadar olan önceliğe sahip iş
parçacıklarını içerir. (Ayrıca, bellek yönetimi için kullanılan, 0 önceliğinde çalışan bir iş
parçacığı da vardır.) Gönderici bir Her bir zamanlama önceliği için kuyruk oluşturur ve
çalışmaya hazır bir iş parçacığı bulana kadar kuyruklar kümesini en yüksekten en
düşüğe doğru hareket ettirir. Hazır iş parçacığı bulunamazsa, gönderici boş iş
parçacığı adı verilen özel bir iş parçacığı yürütür.
Windows çekirdeğinin sayısal öncelikleri ile Windows API'si arasında bir ilişki vardır.
Windows API , bir işlemin ait olabileceği aşağıdaki altı öncelik sınıfını tanımlar:
Süreçler tipik olarak NORMAL ÖNCELİK SINIFI'nın üyeleridir. Sürecin ebeveyni, IDLE
PRIORITY CLASS'ın bir üyesi olmadığı veya süreç oluşturulurken başka bir sınıf
belirtilmediği sürece , bir süreç bu sınıfa aittir . Ek olarak, bir işlemin öncelik sınıfı şu
şekilde değiştirilebilir:
Machine Translated by Google
• BOŞTA
• EN DÜŞÜK
• NORMALİN ALTINDA
• NORMAL
• NORMALİN ÜZERİNDE
• EN YÜKSEK
• ZAMAN KRİTİK
Her iş parçacığının önceliği, hem ait olduğu öncelik sınıfına hem de o sınıf içindeki
göreli önceliğine bağlıdır. Bu ilişki Şekil 5.28'de gösterilmektedir. Öncelik sınıflarının
değerleri üst satırda görünür. Sol sütun, göreli önceliklerin değerlerini içerir. Örneğin,
NORMAL ÖNCELİK SINIFINDAN YUKARIDAKİ bir iş parçacığının göreli önceliği NORMAL
ise , o iş parçacığının sayısal önceliği 10'dur.
Ayrıca, her iş parçacığının, iş parçacığının ait olduğu sınıf için öncelik aralığında bir
değeri temsil eden bir temel önceliği vardır. Varsayılan olarak, temel öncelik, o sınıf için
NORMAL göreli önceliğin değeridir. Her bir öncelik sınıfı için temel öncelikler aşağıdaki
gibidir:
gerçek normalin
yüksek normal
zamanlı üstünde normalin altında
boşta öncelik
en yüksek 26 15 12 10 8 6
normalin üstünde 25 14 11 9 7 5
normal 24 13 10 8 6 4
normalin altında 23 12 9 7 5 3
en düşük 22 11 8 6 4 2
Boşta 16 1 1 1 1 1
Bir iş parçacığının ilk önceliği, genellikle iş parçacığının ait olduğu işlemin temel
önceliğidir, ancak Windows API'sindeki SetThreadPriority() işlevi bir iş parçacığının
temel önceliğini değiştirmek için de kullanılabilir.
Bir iş parçacığının zaman kuantumu bittiğinde, o iş parçacığı kesintiye uğrar.
İş parçacığı değişken öncelikli sınıftaysa, önceliği düşürülür. Ancak öncelik hiçbir
zaman temel önceliğin altına düşürülmez. Önceliği düşürmek, hesaplamaya bağlı iş
parçacıklarının CPU tüketimini sınırlama eğilimindedir . Bir bekleme işleminden
değişken öncelikli bir iş parçacığı serbest bırakıldığında, sevk programı önceliği
artırır. Destek miktarı, iş parçacığının ne beklediğine bağlıdır.
Örneğin, klavye G/ Ç'sini bekleyen bir iş parçacığı büyük bir artış elde ederken, disk
işlemi için bekleyen bir iş parçacığı orta düzeyde bir artış elde eder.
Bu strateji, fare ve pencereleri kullanan etkileşimli iş parçacıklarına iyi yanıt süreleri
verme eğilimindedir. Ayrıca, G/Ç'ye bağlı iş parçacıklarının, G/Ç aygıtlarını meşgul
etmesini sağlarken, hesaplamaya bağlı iş parçacıklarının arka planda yedek CPU
döngüleri kullanmasına izin verir . Bu strateji, UNIX dahil olmak üzere çeşitli işletim
sistemleri tarafından kullanılır . Ayrıca, kullanıcının şu anda etkileşimde olduğu pencere,
yanıt süresini iyileştirmek için bir öncelik artışı alır.
Bir kullanıcı etkileşimli bir program çalıştırdığında, sistemin özellikle iyi performans
sağlaması gerekir. Bu nedenle Windows'un NORMAL ÖNCELİK SINIFI'ndaki işlemler
için özel bir zamanlama kuralı vardır . Windows , ekranda seçili olan ön plan süreci ile
seçili olmayan arka plan süreci arasında ayrım yapar . Bir işlem ön plana geçtiğinde,
Windows zamanlama kuantumunu bir faktör kadar artırır - tipik olarak 3 oranında. Bu
artış, bir zaman paylaşımlı önalım gerçekleşmeden önce ön plan işleminin çalışması
için üç kat daha uzun süre verir.
dayalı iş parçacığı planlamasını kullanır. Her iş parçacığı altı sınıftan birine aittir:
4. Sistem (SYS)
5. Adil paylaşım (FSS)
Bir süreç için varsayılan zamanlama sınıfı zaman paylaşımıdır. Zaman paylaşımlı
sınıf için zamanlama ilkesi, dinamik olarak öncelikleri değiştirir ve çok düzeyli bir geri
bildirim kuyruğu kullanarak farklı uzunluklarda zaman dilimleri atar. Varsayılan olarak,
öncelikler ve zaman dilimleri arasında ters bir ilişki vardır. daha yüksek
Machine Translated by Google
zaman
kuantumunun
0 200 0 50
5 200 0 50
10 160 0 51
15 160 5 51
20 120 10 52
25 120 15 52
30 80 20 53
35 80 25 54
40 40 30 55
45 40 35 56
50 40 40 58
55 40 45 58
59 20 49 59
Şekil 5.29 Zaman paylaşımlı ve etkileşimli iş parçacıkları için Solaris gönderme tablosu.
öncelik, zaman dilimi ne kadar küçükse; ve öncelik ne kadar düşükse, zaman dilimi de o kadar
büyük olur. Etkileşimli süreçler tipik olarak daha yüksek bir önceliğe sahiptir; CPU'ya bağlı
işlemler, daha düşük bir öncelik. Bu zamanlama ilkesi, etkileşimli işlemler için iyi yanıt süresi ve
CPU'ya bağlı işlemler için iyi verim sağlar. Etkileşimli sınıf, zaman paylaşımlı sınıfla aynı
zamanlama politikasını kullanır, ancak KDE veya GNOME pencere yöneticileri tarafından
oluşturulanlar gibi pencereleme uygulamalarına daha iyi performans için daha yüksek bir
öncelik verir.
Şekil 5.29, zaman paylaşımı ve etkileşimli iş parçacıklarının zamanlanması için basitleştirilmiş
sevk tablosunu gösterir. Bu iki zamanlama sınıfı, 60 öncelik seviyesi içerir, ancak kısaca, sadece
bir avuç görüntülüyoruz. (Solaris sisteminde veya sanal makinede tam gönderim tablosunu
görmek için dispadmin -c TS -g'yi çalıştırın . ) Şekil 5.29'da gösterilen gönderim tablosu
aşağıdaki alanları içerir:
• Zaman kuantumu. İlişkili öncelik için zaman kuantumu. Bu, öncelikler ve zaman niceliği
arasındaki ters ilişkiyi gösterir: en düşük öncelik (öncelik 0) en yüksek zaman kuantumuna
(200 milisaniye) sahiptir ve en yüksek öncelik (öncelik 59) en düşük zaman kuantumuna
(20 milisaniye) sahiptir.
• Zaman kuantumunun süresi doldu. Tüm zaman kuantumunu bloke etmeden kullanan bir iş
parçacığının yeni önceliği. Bu tür iş parçacıkları CPU yoğun olarak kabul edilir. Tabloda
gösterildiği gibi, bu iş parçacıklarının öncelikleri azaltılmıştır.
Machine Translated by Google
Belirli bir sistem için bir CPU zamanlama algoritmasını nasıl seçeriz? Bölüm 5.3'te
gördüğümüz gibi, her biri kendi parametrelerine sahip birçok çizelgeleme algoritması
vardır. Sonuç olarak, bir algoritma seçmek zor olabilir.
İlk problem, bir algoritma seçiminde kullanılacak kriterleri tanımlamaktır. Bölüm
5.2'de gördüğümüz gibi, kriterler genellikle CPU kullanımı, yanıt süresi veya verim
açısından tanımlanır. Bir algoritma seçmek için önce bu elemanların göreceli önemini
tanımlamamız gerekir. Kriterlerimiz aşağıdakiler gibi çeşitli önlemleri içerebilir:
• Maksimum yanıt süresinin 300 milisaniye olduğu kısıtlaması altında CPU kullanımını
maksimize etme
5.8 Algoritma Değerlendirmesi 245
Machine Translated by Google
küresel zamanlama
öncelik sırası
169
en yüksek ilk
konuları kesmek
160
159
100
99
60
59
adil paylaşım (FSS) konuları
• Geri dönüş süresinin (ortalama olarak) toplam yürütme süresiyle doğrusal orantılı
olduğu şekilde verimi en üst düzeye çıkarmak
P1 10
P2 29
P3 3
P4 7
P5 12
P1 P2 P3 P4 P5
0 10 39 42 49 61
P3 P4 P1 P5 P2
03 10 20 32 61
P1 P2 P3 P4 P5 P2 P5 P2
0 10 20 23 30 40 50 52 61
Bilgisayar sistemi, bir sunucu ağı olarak tanımlanır. Her sunucunun bir bekleme
süreci kuyruğu vardır. CPU , cihaz kuyruklarıyla G/Ç sistemi gibi hazır kuyruğu olan
bir sunucudur . Varış oranlarını ve hizmet oranlarını bilerek, kullanımı, ortalama
kuyruk uzunluğunu, ortalama bekleme süresini vb. hesaplayabiliriz.
Bu çalışma alanına kuyruklama-ağ analizi denir .
Örnek olarak, n ortalama uzun vadeli kuyruk uzunluğu (hizmet verilen süreç
hariç), W kuyrukta ortalama bekleme süresi olsun ve λ kuyruktaki yeni süreçler için
ortalama varış oranı (örn. saniyede üç işlem). Bir sürecin beklediği W süresi
boyunca , λ × W yeni süreçlerin kuyruğa gelmesini bekliyoruz. Sistem kararlı
durumdaysa, kuyruktan çıkan işlemlerin sayısı gelen işlemlerin sayısına eşit olmalıdır.
Böylece,
n = λ × W.
5.8.3 Simülasyonlar
FCFS için
simülasyon performans
istatistikleri
FCFS
•••
CPU 10
G/Ç 213
gerçek CPU 12 SJF için
süreç G/Ç 112 simülasyon performans
yürütme CPU 2 istatistikleri
G/Ç 147
SJF
işlemci 173
•••
iz bandı
RR için
simülasyon performans
istatistikleri (q = 14)
RR (q = 14)
daha fazla bilgisayar zamanı alır. Ek olarak, izleme dosyaları büyük miktarda depolama
alanı gerektirebilir. Son olarak, simülatörün tasarımı, kodlaması ve hata ayıklaması
önemli bir görev olabilir.
5.8.4 Uygulama
5.9 Özet
• CPU çizelgeleme, hazır kuyruktan bir bekleyen işlemin seçilmesi ve CPU'nun buna tahsis
edilmesi görevidir. CPU , dağıtıcı tarafından seçilen sürece tahsis edilir.
• İlk gelen, ilk hizmet alır (FCFS) zamanlaması en basit zamanlama algoritmasıdır, ancak
kısa süreçlerin çok uzun süreçler için beklemesine neden olabilir.
• Round-robin (RR) zamanlama, CPU'yu bir zaman kuantumu için her işleme tahsis eder .
Süreç, zaman kuantumu sona ermeden önce CPU'dan vazgeçmezse, süreç öncelenir ve
bir zaman kuantumu için başka bir süreç çalışacak şekilde programlanır.
• Öncelik zamanlaması, her işleme bir öncelik atar ve CPU , en yüksek önceliğe sahip sürece
tahsis edilir. Aynı önceliğe sahip işlemler, FCFS sırasına göre veya RR planlaması
kullanılarak programlanabilir. • Çok düzeyli kuyruk zamanlama, işlemleri önceliğe göre
düzenlenmiş birkaç ayrı kuyruğa böler ve zamanlayıcı, süreçleri en yüksek öncelikli kuyrukta
yürütür. Her kuyrukta farklı zamanlama algoritmaları kullanılabilir.
• Çok düzeyli geri bildirim kuyrukları, bir işlemin farklı kuyruklar arasında geçiş yapabilmesi
dışında çok düzeyli kuyruklara benzer. • Çok çekirdekli işlemciler , aynı fiziksel çip üzerine
bir veya daha fazla CPU yerleştirir ve her CPU'nun birden fazla donanım iş parçacığı olabilir.
İşletim sistemi açısından bakıldığında, her bir donanım iş parçacığı mantıksal bir CPU
gibi görünür.
• Çok çekirdekli sistemlerde yük dengeleme, CPU çekirdekleri arasındaki yükleri eşitler,
ancak çekirdekler arasında yükleri dengelemek için geçiş yapmak önbellek içeriğini
geçersiz kılabilir ve bu nedenle bellek erişim sürelerini artırabilir. • Yumuşak gerçek
zamanlı zamanlama, gerçek zamanlı görevlere gerçek zamanlı olmayan görevlere göre
öncelik verir. Zor gerçek zamanlı zamanlama, gerçek zamanlı görevler için zamanlama
garantileri sağlar,
• En erken son teslim tarihi (EDF) zamanlaması, öncelikleri aşağıdakilere göre atar:
son tarih. Son teslim tarihi ne kadar erken olursa, öncelik o kadar yüksek olur; daha sonra
son tarih, öncelik o kadar düşük.
• Orantılı paylaşım planlaması , tüm uygulamalar arasında T payı tahsis eder. Eğer
bir uygulamaya N zaman payı tahsis edilir, N T'ye sahip olması sağlanır .
toplam işlemci süresi
• Solaris, global bir sistemle eşlenen altı benzersiz zamanlama sınıfını tanımlar.
öncelik. CPU yoğun iş parçacıklarına genellikle daha düşük öncelikler atanır
(ve daha uzun zaman kuantumları) ve G/Ç'ye bağlı iş parçacıkları genellikle atanır
daha yüksek öncelikler (daha kısa zaman kuantumlarıyla.)
Alıştırmalar
5.1 Bir CPU zamanlama algoritması, işleyişinin yürütülmesi için bir sıra belirler.
zamanlanmış süreçler. Bir işlemde programlanacak n işlem verildiğinde veya
kaç farklı çizelgeleme mümkündür? terimlerle bir formül verin
n.
5.3 Farzedelim ki, aşağıdaki süreçler zaman zaman yürütülmek üzere geliyor:
belirtilen. Her işlem listelenen süre boyunca çalışacaktır. Soruları cevaplarken,
önleyici olmayan zamanlama kullanın ve tüm kararları temel alın.
o anda sahip olduğunuz bilgilere göre karar verilmelidir.
P1 0.0 8
P2 0.4 4
P3 1.0 1
CPU ilk kez boşta bırakılırsa ortalama geri dönüş süresi olacaktır
1 birim ve ardından SJF zamanlaması kullanılır. Bu süreçleri unutmayın
P1 ve P2 bu bekleme süresi boyunca bekliyorlar, dolayısıyla bekleme süreleri
artırabilir. Bu algoritma gelecek bilgisi olarak bilinebilir.
zamanlama.
5.4 CPU patlamasının uzunluğuyla birlikte aşağıdaki süreç dizisini göz önünde bulundurun.
milisaniye cinsinden verilen süre:
Proseslerin P1, P2, P3, P4, P5, P1, P2, P3, P4, P5,
hepsi 0 zamanında.
c. Bu çizelgeleme algoritmalarının her biri için her bir sürecin bekleme süresi nedir?
P1 40 30 20 0
P2 30 35 25 25
P3 5 10 25 30
P4 15 60
P5 10 100
P6 10 105
Her sürece sayısal bir öncelik atanır ve daha yüksek bir sayı, daha yüksek bir göreli
önceliği belirtir. Aşağıda listelenen işlemlere ek olarak,
sistemin ayrıca boşta bir görevi vardır (bu, hiçbir CPU kaynağı tüketmez ve
Pidle olarak tanımlanır ). Bu görevin önceliği 0'dır ve sistemde çalıştırılacak başka bir
işlem olmadığında zamanlanır. uzunluğu
Alıştırmalar 253
Machine Translated by Google
zaman kuantumu 10 birimdir. Bir işlem, daha yüksek öncelikli bir işlem tarafından
öncelenirse, önceden alınan işlem kuyruğun sonuna yerleştirilir.
a. Bir Gantt şeması kullanarak süreçlerin zamanlama sırasını gösterin. b. Her bir
süreç için geri dönüş süresi nedir? c. Her işlem için bekleme süresi nedir?
5.6 Çok seviyeli bir kuyruk sisteminin farklı seviyelerinde farklı zaman-kuantum boyutlarına
sahip olmanın ne avantajı vardır?
ve FCFS d. RR ve SJF
5.8 Bir CPU zamanlama algoritmasının yakın geçmişte en az işlemci zamanını kullanan
süreçleri desteklediğini varsayalım . Bu algoritma neden G/Ç'ye bağlı programları
tercih edecek ve yine de CPU'ya bağlı programları kalıcı olarak aç bırakmayacak?
5.10 Geleneksel UNIX zamanlayıcı, öncelik numaraları ve öncelikler arasında ters bir ilişki
kurar: sayı ne kadar yüksekse, öncelik o kadar düşük olur. Zamanlayıcı, aşağıdaki
işlevi kullanarak işlem önceliklerini saniyede bir kez yeniden hesaplar:
UNIX FreeBSD 5.2'de kullanılan zamanlama ilkeleri [McKusick et al. (2015)]; Linux
CFS zamanlayıcısı, https://www.ibm.com/developerworks/library/l-completely-
fair-scheduler/ adresinde daha ayrıntılı olarak açıklanmıştır.
Solaris zamanlaması [Mauro ve McDougall (2007)] tarafından açıklanmıştır. [Rus
novich et al. (2017)], Windows dahili bileşenlerinde zamanlamayı tartışır. [Butenhof
(1997)] ve [Lewis ve Berg (1998)], Pthreads sistemlerinde zamanlamayı açıklar.
Çok çekirdekli zamanlama [McNairy ve Bhatia (2005)], [Kongetira et al. (2005)] ve
[Siddha et al. (2007)].
bibliyografya
[McKusick et al. (2015)] MK McKusick, GV Neville-Neil ve RNM Wat son, The Design and
Implementation of the FreeBSD UNIX İşletim Sistemi –İkinci Baskı, Pearson (2015).
[Siddha et al. (2007)] S. Siddha, V. Pallipadi ve A. Mallick, “Process Schedul ing Challenges
in the Era of Multi-Core Processors”, Intel Technology Journal, Cilt 11, Sayı 4 (2007).
Egzersizler EX-12
Machine Translated by Google
Bölüm 5 Alıştırmalar
5.12 Aşağıdaki çizelgeleme kriteri çiftlerinin belirli durumlarda nasıl çatıştığını tartışın.
ayarlar.
5.13 CPU zamanını tahsis etmek için kullanılan piyango biletleri süreçleri atayarak
piyango çizelgeleme çalışmalarını uygulamak için bir teknik . Bir zamanlama
kararı verilmesi gerektiğinde, rastgele bir piyango bileti seçilir ve bu bileti tutan
süreç CPU'yu alır. BTV işletim sistemi, her piyango kazananının 20 milisaniye CPU
zamanı (20 milisaniye × 50 = 1 saniye) aldığı bir piyangoyu saniyede 50 kez tutarak
piyango planlamasını uygular . BTV zamanlayıcısının, daha yüksek öncelikli iş
parçacıklarının düşük öncelikli iş parçacıklarına göre CPU'dan daha fazla ilgi
görmesini nasıl sağlayabileceğini açıklayın.
5.14 Çoğu zamanlama algoritması , bir işlemci üzerinde çalışmaya uygun süreçleri
listeleyen bir çalıştırma kuyruğunu korur. Çok çekirdekli sistemlerde iki genel
seçenek vardır: (1) her işlem çekirdeğinin kendi çalıştırma kuyruğu vardır veya
(2) tek bir çalıştırma sırası tüm işlem çekirdekleri tarafından paylaşılır. Bu
yaklaşımların her birinin avantajları ve dezavantajları nelerdir?
5.15 Bir sonraki CPU patlamasının uzunluğunu tahmin etmek için kullanılan üstel
ortalama formülü düşünün . Algoritma tarafından kullanılan parametrelere
aşağıdaki değerleri atamanın sonuçları nelerdir?
a. α = 0 ve τ0 = 100 milisaniye
b. α = 0.99 ve τ0 = 10 milisaniye
5.16 Tekrarlı sıralı zamanlayıcının bir varyasyonu, gerileyen sıralı sıralı zamanlayıcıdır. Bu
zamanlayıcı, her işleme bir zaman kuantumu ve bir öncelik atar. Bir zaman
kuantumunun başlangıç değeri 50 milisaniyedir. Bununla birlikte, bir işlem
CPU'ya tahsis edildiğinde ve tüm zaman kuantumunu kullandığında ( G/Ç için
bloke etmez ), zaman kuantumuna 10 milisaniye eklenir ve öncelik düzeyi
yükseltilir. (Bir işlemin zaman kuantumu maksimum 100 milisaniyeye yükseltilebilir.)
Bir işlem tüm zaman kuantumunu kullanmadan önce bloke ettiğinde, zaman
kuantumu 5 milisaniye azalır, ancak önceliği aynı kalır. Gerileyen döngüsel
zamanlayıcı ne tür bir işlemi (CPU'ya bağlı veya G/Ç'ye bağlı) tercih eder?
Açıklamak.
EX-13
Machine Translated by Google
5.17 CPU patlamasının uzunluğuyla birlikte aşağıdaki süreç dizisini göz önünde bulundurun.
milisaniye cinsinden verilir:
Proseslerin P1, P2, P3, P4, P5, P1, P2, P3, P4, P5,
hepsi 0 zamanında.
c. Bu çizelgeleme algoritmalarının her biri için her bir sürecin bekleme süresi nedir?
P1 8 15 0
P2 3 20 0
P3 4 20 20
P4 4 20 25
P5 5 545
P6 5 15 55
Her sürece sayısal bir öncelik atanır ve daha yüksek bir sayı, daha yüksek bir göreli
önceliği belirtir. Zamanlayıcı, en yüksek öncelikli işlemi yürütecektir. Aynı önceliğe
sahip işlemler için, bir döngüsel deneme
zamanlayıcı, 10 birimlik bir zaman kuantumu ile kullanılacaktır. bir süreç ise
daha yüksek öncelikli bir süreç tarafından önlenen, önceden alınan süreç
kuyruğun sonunda.
5.19 Nice komutu , Linux'ta bir işlemin nice değerini ayarlamak için kullanılır,
yanı sıra diğer UNIX sistemlerinde. Bazı sistemlerin neden izin verebileceğini açıklayın
herhangi bir kullanıcı bir işleme Nice değeri >= 0 atayacak, ancak yalnızca köke (veya
yönetici) kullanıcı < 0 güzel değerler atamak için .
Egzersizler EX-14
Machine Translated by Google
kısa iş
c. tekrar tekrar
d. Öncelik
5.21 Hazır kuyruğundaki girişlerin PCB'leri işaret ettiği bir RR zamanlama algoritması
türevi düşünün .
5.22 On G/Ç'ye bağlı görev ve bir CPU'ya bağlı görev çalıştıran bir sistem düşünün. G/
Ç'ye bağlı görevlerin her milisaniye CPU hesaplaması için bir G/Ç işlemi
yayınladığını ve her G/Ç işleminin tamamlanmasının 10 milisaniye sürdüğünü
varsayalım . Ayrıca bağlam değiştirme ek yükünün 0,1 milisaniye olduğunu ve
tüm işlemlerin uzun süreli görevler olduğunu varsayalım.
Aşağıdaki durumlarda bir döngüsel zamanlayıcı için CPU kullanımını tanımlayın:
düzeyli kuyruk zamanlaması uygulayan bir sistem düşünün. Bir bilgisayar kullanıcısı ,
kullanıcının işlemine ayrılan CPU süresini en üst düzeye çıkarmak için hangi
stratejiyi kullanabilir ?
5.24 Dinamik olarak değişen önceliklere dayalı bir önleyici öncelik zamanlama
algoritması düşünün. Daha büyük öncelik numaraları daha yüksek öncelik anlamına g
Bir işlem CPU'yu beklerken (hazır kuyruğunda, ancak çalışmıyor), önceliği α
oranında değişir. Çalışırken önceliği β oranında değişir. Tüm işlemlere hazır
kuyruğuna girdiklerinde 0 öncelik verilir. α ve β parametreleri birçok farklı
çizelgeleme algoritması verecek şekilde ayarlanabilir.
5.25 Aşağıdaki çizelgeleme algoritmalarının ikisinden birini nasıl ayırt ettiğini açıklayın.
kısa süreçler lehine veya aleyhine:
a. FCFS
b. RR
5.26 Paylaşılan bir hazır kuyruğun bir SMP ortamındaki performans sorunlarından neden
zarar görebileceğini açıklayın.
5.27 Öncelikten bağımsız olarak her kuyruğun yaklaşık olarak aynı sayıda iş parçacığına
sahip olmasını sağlayan bir yük dengeleme algoritması düşünün.
Bir çalıştırma kuyruğunda tüm yüksek öncelikli iş parçacıkları ve ikinci bir kuyrukta
tüm düşük öncelikli iş parçacıkları varsa, önceliğe dayalı bir zamanlama algoritması
bu durumu ne kadar etkili bir şekilde ele alır?
5.28 Bir SMP sisteminin özel, işlemci başına çalıştırma kuyruklarına sahip olduğunu varsayın .
Yeni bir süreç oluşturulduğunda, üst süreçle aynı kuyruğa veya ayrı bir kuyruğa
yerleştirilebilir.
a. Yeni süreci ebeveyni ile aynı kuyruğa yerleştirmenin faydaları nelerdir? b. Yeni
süreci farklı bir sürece yerleştirmenin faydaları nelerdir?
sıra?
YÜKSEK önceliği
c. Bir akraba ile AŞAĞIDAKİ NORMAL ÖNCELİK SINIFINDAKİ bir iş parçacığı
5.31 Hiçbir iş parçacığının GERÇEK ZAMAN ÖNCELİK SINIFINA ait olmadığını ve hiçbirine
ZAMAN KRİTİK bir öncelik atanamayacağını varsayarsak, Windows zamanlamasında
hangi öncelik sınıfı ve öncelik kombinasyonu mümkün olan en yüksek göreli önceliğe
karşılık gelir?
Egzersizler EX-16
5.33 A ve B adlı iki görevin bir Linux sisteminde çalıştığını varsayın. A ve B'nin nice
değerleri sırasıyla -5 ve +5'tir. CFS zamanlayıcısını bir kılavuz olarak kullanarak ,
aşağıdaki senaryoların her birinde verilen iki işlem arasında ilgili vruntime
değerlerinin nasıl değiştiğini açıklayın:
• Hem A hem de B CPU'ya bağlıdır.
5.35 p1 = 50 , t1 = 25 , p2 = 75 ve
t2 = 30.
Programlama Projeleri
Zamanlama Algoritmaları
Bu proje, birkaç farklı süreç çizelgeleme algoritmasının uygulanmasını içerir. Zamanlayıcıya
önceden tanımlanmış bir dizi görev atanacak ve görevleri seçilen zamanlama algoritmasına
göre planlayacaktır. Her göreve bir öncelik ve CPU patlaması atanır. Aşağıdaki zamanlama
algoritmaları uygulanacaktır:
• Görevleri CPU'dan talep ettikleri sıraya göre zamanlayan ilk gelen, ilk hizmet alır (FCFS) .
• Önce en kısa iş (SJF), görevlerin bir sonraki CPU patlamasının uzunluğuna göre
zamanlama.
• Görevleri öncelik sırasına göre zamanlayan ve eşit önceliğe sahip görevler için
döngüsel zamanlamayı kullanan, sıralı deneme ile öncelik.
Öncelikler 1 ile 10 arasında değişir; burada daha yüksek bir sayısal değer, daha yüksek
bir göreli önceliği gösterir. Round-robin zamanlama için, bir zaman kuantumunun
uzunluğu 10 milisaniyedir.
I. Uygulama
T1, 4, 20
T2, 2, 25
T3, 3, 25
T4, 3, 15
T5, 10, 10
Bu nedenle, görev T1'in önceliği 4 ve CPU patlaması 20 milisaniye vb. Tüm görevlerin aynı
anda geldiği varsayılır, bu nedenle zamanlayıcı algoritmalarınızın daha düşük öncelikli
süreçleri önleyen daha yüksek öncelikli süreçleri desteklemesi gerekmez. Ayrıca, görevlerin
belirli bir sıraya göre sıraya veya listeye yerleştirilmesi gerekmez.
İlk olarak Bölüm 5.1.2'de sunulduğu gibi, görev listesini düzenlemek için birkaç
farklı strateji vardır. Bir yaklaşım, tüm görevleri, görev seçimi stratejisinin zamanlamaya
bağlı olduğu tek bir sırasız listeye yerleştirmektir.
Machine Translated by Google
algoritma. Örneğin, SJF zamanlaması, bir sonraki en kısa CPU patlamasına sahip görevi
bulmak için listeyi arayacaktır . Alternatif olarak, zamanlama kriterlerine göre (yani
önceliğe göre) bir liste sıralanabilir. Diğer bir strateji, Şekil 5.7'de gösterildiği gibi,
her benzersiz öncelik için ayrı bir kuyruğa sahip olmayı içerir. Bu yaklaşımlar Kısım
5.3.6'da kısaca tartışılmaktadır. Ayrıca terimler listesini kullandığımızı ve birbirinin
yerine geçecek şekilde sıraya koyduğumuzu vurgulamakta fayda var .
Bununla birlikte, bir sıranın çok özel FIFO işlevi vardır, oysa bir listenin bu kadar katı
ekleme ve silme gereksinimleri yoktur. Bu projeyi tamamlarken genel bir listenin
işlevselliğini daha uygun bulmanız olasıdır.
fcfs yapmak
./fcfs program.txt
Daha fazla ayrıntı için kaynak kod indirme dosyasındaki BENİOKU dosyasına bakın.
Devam etmeden önce, sağlanan kaynak kodun yanı sıra Makefile'ı da tanıdığınızdan
emin olun.
Driver.java dosyası görev çizelgesinde okur, her görevi bir Java ArrayList'e ekler ve
program() yöntemini çağırarak işlem zamanlayıcısını çağırır . Aşağıdaki arayüz, beş
farklı zamanlama algoritmasının uygulayacağı genel bir zamanlama algoritmasını
tanımlar:
Linux ve macOS sistemlerinde, bir tamsayı değerini atomik olarak artırmak için sync
fetch ve add() işlevi kullanılabilir. Örnek olarak, aşağıdaki kod örneği, değeri
atomik olarak 1 artırır:
int değeri = 0;
senkronizasyon getir ve ekle(&value,1);
Üçüncü Bölüm
İşlem
senkronizasyon
Bir sistem tipik olarak, aynı anda veya paralel olarak çalışan birkaç (belki de yüzlerce
hatta binlerce) iş parçacığından oluşur. Konular genellikle kullanıcı verilerini paylaşır.
Bu arada, işletim sistemi, birden çok iş parçacığını desteklemek için çeşitli veri
yapılarını sürekli olarak günceller. Paylaşılan verilere erişim kontrol edilmediğinde,
muhtemelen bozuk veri değerlerine neden olan bir yarış durumu mevcuttur.
6BÖLÜM
senkronizasyon
Aletler
BÖLÜM HEDEFLERİ
257
Machine Translated by Google
Bunun nasıl olabileceğine dair bir örnek düşünelim. Bölüm 3'te, tümü
asenkron olarak çalışan ve muhtemelen veri paylaşan, birlikte çalışan sıralı
işlemlerden veya iş parçacıklarından oluşan bir sistem modeli geliştirdik. Bu modeli,
birçok işletim sistemi fonksiyonunun temsili bir paradigması olan üretici-tüketici
problemi ile gösterdik. Spesifik olarak, Bölüm 3.5'te, işlemlerin belleği paylaşmasını
sağlamak için sınırlı bir arabelleğin nasıl kullanılabileceğini açıkladık.
while (true) { /*
sonraki üretimde bir öğe üret */
Yukarıda gösterilen üretici ve tüketici rutinleri ayrı ayrı doğru olsa da, aynı anda
yürütüldüklerinde düzgün çalışmayabilirler. Örnek olarak, sayım değişkeninin
değerinin şu anda 5 olduğunu ve üretici ve tüketici süreçlerinin aynı anda "count+
+" ve "count--" ifadelerini yürüttüğünü varsayalım. Bu iki ifadenin yürütülmesini
takiben, değişken sayısı 4, 5 veya 6 olabilir! Yine de tek doğru sonuç, üretici ve
tüketici ayrı ayrı yürütürse doğru şekilde oluşturulan count == 5'tir.
Machine Translated by Google
register1 = sayma
register1 = register1 +
1 sayma = register1
burada register1 yerel CPU kayıtlarından biridir. Benzer şekilde, “say- -” ifadesi
aşağıdaki gibi uygulanır:
register2 =
register2 = register2
1 sayım = register2
burada yine register2 , yerel CPU kayıtlarından biridir. register1 ve register2 aynı
fiziksel kayıt olsa bile , bu kaydın içeriğinin kesme işleyicisi tarafından kaydedileceğini
ve geri yükleneceğini unutmayın (Bölüm 1.2.3).
"count++" ve "count--" nin eşzamanlı yürütülmesi, daha önce sunulan alt düzey
ifadelerin rastgele bir sırayla serpiştirildiği (ancak her bir üst düzey ifadedeki sıranın
korunduğu) sıralı bir yürütmeye eşdeğerdir. Böyle bir serpiştirme şudur:
Dört arabelleğin dolu olduğunu gösteren, aslında beş arabellek doluyken, yanlış
“sayım == 4” durumuna ulaştığımıza dikkat edin . T4 ve T5'teki ifadelerin sırasını tersine
çevirirsek, yanlış “sayım == 6” durumuna ulaşırız .
Bu yanlış duruma varırdık çünkü her iki işlemin de değişken sayısını aynı anda
manipüle etmesine izin verdik. Birkaç işlemin aynı anda aynı verilere eriştiği ve bunları
manipüle ettiği ve yürütmenin sonucunun erişimin gerçekleştiği belirli sıraya bağlı
olduğu böyle bir duruma yarış koşulu denir. Yukarıdaki yarış koşuluna karşı korunmak
için, aynı anda yalnızca bir işlemin değişken sayımı manipüle edebileceğinden emin
olmamız gerekir. Böyle bir garanti verebilmek için süreçlerin bir şekilde senkronize
edilmesini şart koşuyoruz.
bir diğer. Bu konunun önemi nedeniyle, bu bölümün büyük bir bölümünü, işbirliği
yapan süreçler arasındaki senkronizasyon ve koordinasyonun işlenmesine ayırdık.
while (doğru) {
giriş bölümü
kritik Bölüm
çıkış bölümü
kalan bölüm
3. Sınırlı bekleme. Bir işlem kritik bölümüne girmek için bir talepte bulunduktan
sonra ve bu talep kabul edilmeden önce diğer işlemlerin kritik bölümlerine
girmelerine izin verilen sayıda bir sınır veya sınır vardır.
Her işlemin sıfırdan farklı bir hızda yürütüldüğünü varsayıyoruz. Ancak, n prosesin
nispi hızıyla ilgili hiçbir varsayımda bulunamayız .
Belirli bir zamanda, işletim sisteminde birçok çekirdek modu işlemi etkin olabilir.
Sonuç olarak, bir işletim sistemini uygulayan kod (çekirdek kodu) birkaç olası yarış
koşuluna tabidir. Örnek olarak, sistemdeki tüm açık dosyaların bir listesini tutan bir
çekirdek veri yapısını düşünün. Bu liste, yeni bir dosya açıldığında veya
kapatıldığında (dosyanın listeye eklenmesi veya listeden çıkarılması) değiştirilmelidir.
İki işlem aynı anda dosyaları açacak olsaydı, bu listedeki ayrı güncellemeler bir
yarış durumuna neden olabilir.
Başka bir örnek Şekil 6.2'de gösterilmektedir. Bu durumda, iki süreç, P0 ve P1,
fork() sistem çağrısını kullanarak alt süreçler yaratıyor .
Bölüm 3.3.1'den fork() 'un yeni oluşturulan sürecin süreç tanımlayıcısını ana sürece
döndürdüğünü hatırlayın. Bu örnekte, bir sonraki kullanılabilir süreç tanımlayıcısının
değerini temsil eden sonraki kullanılabilir pid değişken çekirdek değişkeni üzerinde
bir yarış koşulu vardır . Karşılıklı dışlama sağlanmadıkça, aynı işlem tanımlayıcı
numarasının iki ayrı işleme atanması mümkündür.
Olası yarış koşullarına yatkın olan diğer çekirdek veri yapıları, bellek tahsisini
sürdürmek, süreç listelerini sürdürmek ve kesinti işlemek için yapıları içerir. İşletim
sisteminin bu tür yarış koşullarından arınmış olmasını sağlamak çekirdek
geliştiricilerine bağlıdır.
Paylaşılan bir değişken değiştirilirken kesintilerin oluşmasını önleyebilirsek,
kritik bölüm sorunu tek çekirdekli bir ortamda basitçe çözülebilirdi. Bu şekilde,
mevcut dizinin olduğundan emin olabiliriz.
P P1
0
next_available_pid = 2615
dönüş dönüş
2615 2615
Daha sonra, Peterson'ın çözümü olarak bilinen kritik bölüm problemine klasik yazılım tabanlı
bir çözüm göstereceğiz . Çünkü modern bilgisayar
mimariler, yükleme ve yükleme gibi temel makine dili talimatlarını gerçekleştirir.
mağaza, Peterson'ın çözümünün doğru çalışacağının garantisi yoktur.
Bu tür mimarilerde. Ancak, çözümü sunduğu için sunuyoruz.
Kritik bölüm problemini çözmenin iyi bir algoritmik açıklaması ve aşağıdakileri ele alan
yazılım tasarımında yer alan bazı karmaşıklıkları gösterir.
karşılıklı dışlama, ilerleme ve sınırlı bekleme gereksinimleri.
Peterson'ın çözümü, yürütmeyi değiştiren iki işlemle sınırlıdır
kritik bölümleri ve kalan bölümleri arasında. Prosesler P0 ve P1 olarak numaralandırılmıştır.
Kolaylık sağlamak için, Pi'yi sunarken , Pj'yi belirtmek için kullanırız .
diğer süreç; yani, j eşittir 1 - i.
Peterson'ın çözümü, iki işlemin iki veri öğesini paylaşmasını gerektirir:
int dönüş;
boole bayrağı[2];
Machine Translated by Google
while (true)
{ flag[i] = true;
dönüş = j; while
(bayrak[j] && dönüş == j)
;
/* kritik Bölüm */
bayrak[i] = yanlış;
/*kalan bölüm */
}
Değişken dönüş , kritik bölümüne girme sırasının kimde olduğunu gösterir. Yani,
eğer dönüş == i ise, Pi işleminin kritik bölümünde çalışmasına izin verilir. Bayrak
dizisi, bir işlemin kritik bölümüne girmeye hazır olup olmadığını belirtmek için kullanılır .
Örneğin, bayrak[i] doğruysa , Pi kritik bölümüne girmeye hazırdır. Bu veri yapılarının
açıklaması tamamlandıktan sonra, Şekil 6.3'te gösterilen algoritmayı tanımlamaya
hazırız.
Kritik bölüme girmek için, Pi süreci önce flag[i] 'yi doğru olarak ayarlar ve sonra
setler j değerine döner , böylece diğer süreç kritik bölüme girmek isterse, bunu
yapabileceğini iddia eder. Her iki işlem de aynı anda girmeye çalışırsa, dönüş kabaca
aynı anda hem i hem de j'ye ayarlanacaktır . Bu görevlerden yalnızca biri sürecek;
diğeri gerçekleşecek ancak hemen üzerine yazılacaktır. Sıranın nihai değeri , iki
süreçten hangisinin kritik bölümüne ilk önce girmesine izin verileceğini belirler.
Özellik 1'i kanıtlamak için, her Pi'nin kritik bölümüne, yalnızca flag[j] == false
veya == i'yi çevirdiğinde girdiğine dikkat edin. Ayrıca, her iki işlem de aynı anda
kritik bölümlerinde yürütülebiliyorsa, flag[0] == flag[1] == true olduğunu unutmayın.
Bu iki gözlem, P0 ve P1'in while deyimlerini yaklaşık olarak aynı anda başarıyla
yürütemeyeceklerini ima eder , çünkü dönüş değeri 0 veya 1 olabilir, ancak ikisi
birden olamaz. Bu nedenle, süreçlerden biri (örneğin, Pj) while ifadesini başarıyla
yürütmüş olmalı , oysa Pi en az bir ek ifadeyi ("turn == j") yürütmek zorundaydı .
Özellik 2 ve 3'ü kanıtlamak için, bir Pi işleminin kritik bölüme girmesinin, yalnızca
while döngüsünde durum flag[j] == true ve dönüş == j; bu döngü mümkün olan tek
döngüdür. Pj kritik bölüme girmeye hazır değilse, flag [j] == false ve Pi kritik bölümüne
girebilir. Pj , flag[j] 'yi true olarak ayarladıysa ve while deyiminde de çalışıyorsa, o zaman
ya == i'yi çevirin ya da == j'yi çevirin . Eğer dönüş == i ise, Pi kritik bölüme girecektir.
Eğer dönüş == j ise, Pj kritik bölüme girecektir. Ancak, Pj kritik bölümünden çıktığında,
flag[j] 'yi false olarak sıfırlayacak ve Pi'nin kritik bölümüne girmesine izin verecektir. Pj ,
flag[j] 'yi true olarak sıfırlarsa , ayrıca dönüşü i'ye ayarlaması gerekir .
Örnek olarak, iki iş parçacığı arasında paylaşılan aşağıdaki verileri göz önünde
bulundurun:
while (!bayrak)
;
x yazdır;
ve Thread 2 gerçekleştirir
x = 100;
bayrak = doğru;
Beklenen davranış, elbette, Thread 1'in x değişkeni için 100 değerini vermesidir.
Bununla birlikte, flag ve x değişkenleri arasında veri bağımlılığı olmadığından , bir
işlemcinin Thread 2 için talimatları yeniden sıralayabilmesi ve böylece flag x = 100
atanmadan önce true olarak atanması mümkündür. Bu durumda, Thread 1, x değişkeni
için 0 çıktısı verir . Daha az belirgin olan, işlemcinin ayrıca Thread 1 tarafından verilen
ifadeleri yeniden sıralayabilmesi ve flag değerini yüklemeden önce x değişkenini
yükleyebilmesidir. Bu gerçekleşirse, Thread 2 tarafından verilen talimatlar yeniden
sıralanmasa bile , Thread 1 x değişkeni için 0 çıktısı verir.
Machine Translated by Google
zaman
Bu, Peterson'ın çözümünü nasıl etkiler? Şekil 6.3'teki Peterson çözümünün giriş
bölümünde görünen ilk iki ifadenin atamaları yeniden sıralanırsa ne olacağını düşünün;
Şekil 6.4'te gösterildiği gibi her iki ipliğin de kritik bölümlerinde aynı anda aktif olması
mümkündür.
Aşağıdaki bölümlerde göreceğiniz gibi, karşılıklı dışlamayı korumanın tek yolu uygun
senkronizasyon araçlarını kullanmaktır. Bu araçlarla ilgili tartışmamız, donanımdaki ilkel
destekle başlar ve hem çekirdek geliştiricileri hem de uygulama programcıları için mevcut
olan soyut, yüksek seviyeli, yazılım tabanlı API'ler aracılığıyla ilerler.
Az önce kritik bölüm sorununa yazılım tabanlı bir çözüm tanımladık. ( Algoritma, karşılıklı
dışlamayı sağlamak için işletim sisteminden özel bir destek veya belirli donanım talimatları
içermediğinden, buna yazılım tabanlı bir çözüm diyoruz.) Bununla birlikte, tartışıldığı gibi,
yazılım tabanlı çözümlerin modern bilgisayar mimarilerinde çalışması garanti edilmez. . Bu
bölümde, kritik bölüm sorununu çözmek için destek sağlayan üç donanım talimatı
sunuyoruz. Bu ilkel işlemler, doğrudan senkronizasyon araçları olarak kullanılabilir veya
daha soyut senkronizasyon mekanizmalarının temelini oluşturmak için kullanılabilir.
bir sistemin, güvenilir olmayan veri durumlarına yol açabilecek bir politika olan talimatları
yeniden düzenleyebileceğini gördük. Bir bilgisayar mimarisinin, bir uygulama programına
hangi belleği garanti edeceğini nasıl belirlediği, bellek modeli olarak bilinir. Genel olarak,
bir bellek modeli iki kategoriden birine girer:
266
Bölüm 6 Senkronizasyon Araçları
while (!flag)
bellek engeli(); x
yazdır;
x = 100;
bellek bariyeri();
bayrak = doğru;
dönüş rv;
}
do
{ while (test et ve ayarla(&lock)); /*
hiçbir şey yapma */
/* kritik Bölüm */
kilit = yanlış;
Karşılaştırma ve takas() talimatı (CAS), tıpkı test ve set() talimatı gibi, iki kelime
üzerinde atomik olarak çalışır, ancak iki kelimenin içeriğinin değiştirilmesine
dayanan farklı bir mekanizma kullanır.
CAS komutu üç işlenen üzerinde çalışır ve Şekil 6.7'de tanımlanmıştır . İşlenen
değeri , yalnızca (*değer == beklenen) ifadesi doğruysa yeni değere ayarlanır . Ne
olursa olsun, CAS her zaman değişken değerinin orijinal değerini döndürür . Bu
talimatın önemli özelliği, atomik olarak yürütülmesidir. Bu nedenle, iki CAS komutu
aynı anda yürütülürse (her biri farklı bir çekirdekte), bunlar rastgele bir sırayla sırayla
yürütülecektir.
int karşılaştırma ve takas(int *değer, int beklenen, int yeni değer) { int temp = *değer;
dönüş sıcaklığı;
}
while (true)
{ while (karşılaştır ve değiştir(&lock, 0, 1) != 0 ); /
* hiçbir şey yapma */
/* kritik Bölüm */
kilit = 0;
/* kalan kısım */
}
while (true)
{ wait[i] = true; anahtar
= 1; while (bekliyor[i]
&& tuşu == 1)
anahtar = karşılaştır ve değiştir(&lock,0,1);
bekliyor[i] = yanlış;
/* kritik Bölüm */
j = (i + 1) %n; while
((j != i) && !bekliyor[j]) j = (j + 1) % n;
if (j == i) kilit =
0; başka
bekliyor[j] =
yanlış;
/* kalan kısım */
}
Intel x86 mimarilerinde, karşılaştırma ve takas() yönergesini uygulamak için derleme dili ifadesi
cmpxchg kullanılır . Atomik yürütmeyi zorlamak için , hedef işlenen güncellenirken veri yolunu
kilitlemek için kilit öneki kullanılır. Bu talimatın genel şekli şöyle görünür:
Bekleyen dizideki öğeler false olarak başlatılır ve kilit 0'a sıfırlanır. Karşılıklı dışlama
gereksiniminin karşılandığını kanıtlamak için, Pi işleminin kritik bölümüne ancak
wait[i] == false olduğunda girebileceğini not ederiz. veya anahtar == 0. Anahtarın
değeri, yalnızca karşılaştırma ve takas() yürütülürse 0 olabilir . Karşılaştırma ve
takas() 'ı yürüten ilk süreç key == 0 ; diğerleri beklemeli. wait[i] değişkeni , ancak
başka bir işlem kritik bölümünden çıkarsa yanlış olabilir ; karşılıklı dışlama gereksinimi
korunarak yalnızca bir bekleme[i] false olarak ayarlanır .
int sıcaklık;
do
{ sıcaklık = *v;
Kısım 6.4'te sunulan kritik bölüm sorununa yönelik donanım tabanlı çözümler
karmaşıktır ve uygulama programcıları tarafından genellikle erişilemez. Bunun
yerine, işletim sistemi tasarımcıları, kritik bölüm sorununu çözmek için daha üst
düzey yazılım araçları oluşturur. Bu araçların en basiti muteks kilididir. (Aslında
mutex terimi, karşılıklı dışlamanın kısaltmasıdır .) Kritik bölümleri korumak ve
böylece yarış koşullarını önlemek için mutex kilidini kullanıyoruz. Yani, bir işlem
kritik bir bölüme girmeden önce kilidi almalıdır; kritik bölümden çıktığında kilidi
serbest bırakır. Edinme () işlevi kilidi alır ve serbest bırakma() işlevi, Şekil 6.10'da
gösterildiği gibi kilidi serbest bırakır.
Bir muteks kilidi, değeri kilidin kullanılabilir olup olmadığını gösteren
kullanılabilir bir boole değişkenine sahiptir. Kilit mevcutsa, edinme() çağrısı başarılı
olur ve bu durumda kilidin kullanılamaz olduğu kabul edilir. Kullanılamayan bir kilidi
almaya çalışan bir işlem, kilit serbest bırakılıncaya kadar engellenir.
Machine Translated by Google
while (doğru) {
kilit almak
kritik Bölüm
kalan bölüm
elde() { while (!
mevcut)
; /* meşgul bekle */
mevcut = yanlış;
}
yayın() { mevcut
= doğru;
}
İÇERİĞİ KİLİTLE
Çok işlemcili sistemlerde, kilit kısa bir süre tutulacaksa, döndürme kilitleri genellikle tercih
edilen kilitleme mekanizması olarak tanımlanır. Ama tam olarak kısa bir süreyi oluşturan nedir?
Bir kilit üzerinde beklemenin iki bağlam anahtarı gerektirdiği göz önüne alındığında - iş
parçacığını bekleme durumuna taşımak için bir bağlam anahtarı ve kilit kullanılabilir hale
geldiğinde bekleyen iş parçacığını geri yüklemek için ikinci bir bağlam anahtarı - genel kural,
kilit açılacaksa bir döndürme kilidi kullanmaktır. iki bağlam anahtarından daha kısa bir süre
boyunca tutulabilir.
Bölüm 7'de mutex kilitlerinin klasik senkronizasyon problemlerini çözmek için nasıl
kullanılabileceğini inceleyeceğiz. Ayrıca, muteks kilitlerinin ve döndürme kilitlerinin çeşitli
işletim sistemlerinde ve Pthreads'te nasıl kullanıldığını tartışıyoruz.
6.6 Semaforlar
Mutex kilitleri, daha önce de belirttiğimiz gibi, genellikle senkronizasyon araçlarının en
basiti olarak kabul edilir. Bu bölümde, bir muteks kilidine benzer şekilde davranabilen
ancak aynı zamanda süreçlerin etkinliklerini senkronize etmeleri için daha karmaşık yollar
sağlayabilen daha sağlam bir aracı inceleyeceğiz.
Bir semafor S , başlatma dışında, yalnızca iki standart atomik işlemle erişilen bir
tamsayı değişkenidir: wait() ve sinyal().
Semaforlar Hollandalı bilgisayar bilimcisi Edsger Dijk stra tarafından tanıtıldı ve bu şekilde,
wait() işlemi orijinal olarak P (Hollandaca'dan ) olarak adlandırıldı.
Machine Translated by Google
wait(S)
{ while (S <= 0) ; //
meşgul bekle
S--;
}
sinyal(ler) {
S++;
}
Sayma semaforları, sınırlı sayıda örnekten oluşan belirli bir kaynağa erişimi kontrol
etmek için kullanılabilir. Semafor, mevcut kaynakların sayısına göre başlatılır. Bir kaynak
kullanmak isteyen her işlem, semafor üzerinde bir wait() işlemi gerçekleştirir (böylece
sayıyı azaltır). Bir işlem bir kaynağı serbest bıraktığında, bir sinyal() işlemi gerçekleştirir
(sayıyı artırarak). Semafor için sayı 0'a gittiğinde, tüm kaynaklar kullanılıyor. Bundan
sonra, bir kaynağı kullanmak isteyen işlemler, sayı 0'dan büyük olana kadar engellenir.
S1;
sinyal(senkronizasyon);
Machine Translated by Google
bekle(senkronizasyon);
S2;
Askıya alınmış, S semaforunu bekleyen bir işlem, başka bir işlem bir sinyal()
işlemi yürüttüğünde yeniden başlatılmalıdır . İşlem , işlemi bekleme durumundan
hazır duruma değiştiren bir wakeup() işlemi ile yeniden başlatılır. İşlem daha sonra
hazır kuyruğa alınır. ( CPU programlama algoritmasına bağlı olarak CPU, çalışan
süreçten yeni hazır sürece geçebilir veya geçmeyebilir.)
typedef struct
{ int değer;
yapı süreci *listesi; }
semafor;
Her semaforun bir tamsayı değeri ve bir süreç listesi listesi vardır. Bir işlemin bir
semafor üzerinde beklemesi gerektiğinde, işlemler listesine eklenir. Bir sinyal()
işlemi, bekleyen işlemler listesinden bir işlemi kaldırır ve bu işlemi uyandırır.
bekle(semafor *S) {
S->değer--;
if (S->değer < 0) { bu
işlemi S->listesine ekleyin;
uyumak();
}
}
Machine Translated by Google 6.6 Semaforlar 275
sinyal(semafor *S) {
S->değer++;
if (S->değer <= 0) {
S->listesinden bir P prosesini kaldırın ;
uyan);
}
}
nadiren ve daha sonra sadece kısa bir süre için. Kritik bölümleri uzun (dakikalar, hatta
saatler) olabilen veya neredeyse her zaman meşgul olabilen uygulama programlarında
tamamen farklı bir durum vardır. Bu gibi durumlarda, yoğun bekleme son derece
verimsizdir.
6.7 Monitörler
Semaforlar süreç senkronizasyonu için uygun ve etkili bir mekanizma sağlasalar da,
bunların yanlış kullanılması, tespit edilmesi zor olan zamanlama hatalarına neden
olabilir, çünkü bu hatalar yalnızca belirli yürütme dizileri gerçekleşirse gerçekleşir ve
bu diziler her zaman oluşmaz.
Üretici-tüketici sorununa çözümümüzde bir sayım kullanımında bu tür hataların
bir örneğini gördük (Bölüm 6.1). Bu örnekte, zamanlama sorunu çok nadiren
meydana geldi ve o zaman bile sayım değeri makul görünüyordu - yalnızca 1 ile. Yine
de, çözüm açıkça kabul edilebilir bir çözüm değil. Bu nedenle muteks kilitleri ve
semaforlar ilk etapta tanıtıldı.
sinyal(mutex);
...
kritik Bölüm
...
bekle(mutex);
bekle(mutex);
...
kritik Bölüm
...
bekle(mutex);
6.7 Monitörler 277
Machine Translated by Google
monitör adı {
fonksiyon P1 (...) {
...
}
fonksiyon P2 (...) {
...
}
.
.
.
fonksiyon Pn (...) {
...
}
koşul x, y;
x.bekle();
bu işlemi çağıran işlemin başka bir işlem çağırana kadar askıya alındığı anlamına
gelir.
x.sinyal();
giriş kuyruğu
paylaşılan veri
...
operasyonlar
başlatma kodu
x.signal () işlemi, tam olarak askıya alınmış bir işlemi sürdürür. Hiçbir işlem askıya alınmazsa,
signal() işleminin hiçbir etkisi olmaz; yani x'in durumu, işlem hiç yapılmamış gibidir (Şekil 6.13). Bu
işlemi , her zaman semaforun durumunu etkileyen semaforlarla ilişkili sinyal() işlemiyle karşılaştırın.
Şimdi, x.signal() işlemi bir P işlemi tarafından çağrıldığında , x koşuluyla ilişkili askıya alınmış
bir Q işlemi olduğunu varsayalım. Açıkça, askıya alınan Q işleminin yürütülmesine devam etmesine
izin verilirse, sinyalleme işlemi P'nin beklemesi gerekir. Aksi takdirde, monitör içinde hem P hem
de Q aynı anda etkin olacaktır. Bununla birlikte, kavramsal olarak her iki işlemin de yürütülmesine
devam edebileceğini unutmayın. İki olasılık mevcuttur:
2. Sinyal verin ve devam edin. Q ya P monitörden ayrılana kadar bekler ya da başka bir koşul için
bekler.
Her iki seçeneğin de benimsenmesi lehine makul argümanlar vardır. Bir yandan, P monitörde
zaten yürütülüyor olduğundan, sinyal ve devam yöntemi daha makul görünüyor. Öte yandan,
eğer P parçacığının devam etmesine izin verirsek, o zaman Q devam ettirildiğinde, Q'nun
beklediği mantıksal koşul artık geçerli olmayabilir. Bu iki seçenek arasında bir uzlaşma da
mevcuttur: P ipliği sinyal işlemini yürüttüğünde, hemen monitörden ayrılır. Bu nedenle, Q hemen
devam ettirilir.
giriş kuyruğu
paylaşılan veri
•••
operasyonlar
başlatma kodu
sinyal(mutex);
Bir monitör içinde karşılıklı dışlama sağlanır.
Artık koşul değişkenlerinin nasıl uygulandığını da tanımlayabiliriz.
Her x koşulu için , her ikisi de 0'a ayarlanmış bir x sem ikili semaforu ve bir tamsayı
değişkeni x sayısı tanıtıyoruz. x.wait() işlemi artık şu şekilde uygulanabilir:
x sayısı++;
if (sonraki sayı > 0)
sinyali(sonraki);
başka sinyal(mutex);
bekle(x sem); x
sayısı--;
if (x sayısı > 0)
{ sonraki sayı++;
sinyal(x sem);
bekle(sonraki);
sonraki sayı--;
}
ResourceAllocator'ı izleyin {
boole meşgul;
koşul x;
Şekil 6.14 Tek bir kaynağı tahsis etmek için bir monitör.
x.bekle(c);
rica etmek. Söz konusu kaynağa erişmesi gereken bir işlem aşağıdaki sırayı
izlemelidir:
R.acquire(t);
...
kaynağa erişin;
...
R.release();
• Bir işlem, önce kaynağa erişim izni almadan bir kaynağa erişebilir.
• Bir işleme, kaynağa erişim izni verildikten sonra bir kaynağı asla serbest
bırakmayabilir.
• Bir süreç, hiç talep etmediği bir kaynağı serbest bırakmaya çalışabilir. • Bir
Bu inceleme küçük, statik bir sistem için mümkün olsa da, büyük bir sistem veya
dinamik bir sistem için makul değildir. Bu erişim denetimi sorunu, yalnızca Bölüm
17'de açıklanan ek mekanizmaların kullanılmasıyla çözülebilir.
Machine Translated by Google
6.8 Canlılık
Kritik erişime erişimi koordine etmek için senkronizasyon araçlarını kullanmanın bir sonucu
bölümler, kritik bölümüne girmeye çalışan bir sürecin olasılığıdır.
süresiz olarak bekleyecektir. Hatırlayın, Bölüm 6.2'de aşağıdaki üç kriteri özetledik:
kritik-kesit probleminin çözümleri tatmin etmelidir. Süresiz bekleme ihlalleri
bunlardan ikisi - ilerleme ve sınırlı bekleme kriterleri.
Canlılık , bir sistemin sağlamak için karşılaması gereken bir dizi özelliği ifade eder.
süreçlerin yürütme yaşam döngüleri boyunca ilerleme kaydettiğini gösterir. Az önce
açıklanan koşullar altında süresiz olarak bekleyen bir süreç, bir örnektir.
"canlılık başarısızlığı."
Canlılık yetmezliğinin birçok farklı biçimi vardır; bununla birlikte, tümü genellikle
düşük performans ve yanıt verme ile karakterize edilir. çok basit
canlılık hatası örneği sonsuz bir döngüdür. Meşgul bir bekleme döngüsü şunları sunar:
bir canlılık hatası olasılığı , özellikle bir süreç keyfi olarak döngüye giriyorsa
uzun bir süre. gibi araçları kullanarak karşılıklı dışlama sağlama çabaları
muteks kilitleri ve semaforlar genellikle eşzamanlı programlamada bu tür hatalara yol
açabilir. Bu bölümde, canlılığa yol açabilecek iki durumu araştırıyoruz.
başarısızlıklar
6.8.1 Kilitlenme
Bir bekleme kuyruğuna sahip bir semaforun uygulanması,
iki veya daha fazla sürecin bir olay için süresiz olarak beklediği durum
bu sadece bekleme süreçlerinden biri tarafından kaynaklanabilir. Söz konusu olay
bir sinyal() işleminin yürütülmesidir. Böyle bir duruma gelindiğinde, bunlar
süreçlerin kilitlendiği söyleniyor .
Bunu göstermek için, P0 ve P1 olmak üzere iki süreçten oluşan bir sistem düşünün.
her biri S ve Q olmak üzere iki semafora erişir, 1 değerine ayarlanır:
P0 P1
bekle(ler); bekle(Q);
bekle(Q); bekle(ler);
. .
. .
. .
sinyal(ler); sinyal(Q);
sinyal(Q); sinyal(ler);
bu bölümde, kilitlenme sorunuyla başa çıkmak için çeşitli mekanizmaların yanı sıra
diğer canlılık arızaları biçimlerini açıklıyoruz.
Daha yüksek öncelikli bir sürecin, şu anda daha düşük öncelikli bir süreç veya daha
düşük öncelikli bir süreç zinciri tarafından erişilmekte olan çekirdek verilerini
okuması veya değiştirmesi gerektiğinde bir zamanlama zorluğu ortaya çıkar.
Çekirdek verileri tipik olarak bir kilitle korunduğundan, yüksek öncelikli işlemin
daha düşük öncelikli olanın kaynakla bitmesini beklemesi gerekecektir. Düşük
öncelikli süreç, daha yüksek önceliğe sahip başka bir süreç lehine önlenirse durum
daha karmaşık hale gelir.
Örnek olarak, öncelikleri L < M < H sırasını izleyen üç sürecimiz (L, M ve H)
olduğunu varsayalım. H sürecinin , şu anda L süreci tarafından erişilen bir S
semaforu gerektirdiğini varsayalım . Normal olarak, H süreci L'nin S kaynağını
kullanarak bitirmesini beklerdi . Bununla birlikte, şimdi M sürecinin çalıştırılabilir
hale geldiğini ve dolayısıyla L sürecini önlediğini varsayalım . Dolaylı olarak, daha
düşük önceliğe sahip bir süreç – M süreci – H sürecinin L' nin kaynaktan vazgeçmesi
için ne kadar beklemesi gerektiğini etkilemiştir . S.
Bu canlılık sorunu önceliğin tersine çevrilmesi olarak bilinir ve yalnızca ikiden
fazla önceliği olan sistemlerde ortaya çıkabilir. Tipik olarak, bir öncelik kalıtım
protokolü uygulanarak önceliğin tersine çevrilmesi önlenir . Bu protokole göre,
daha yüksek öncelikli bir işlemin ihtiyaç duyduğu kaynaklara erişen tüm işlemler,
söz konusu kaynaklarla bitene kadar daha yüksek önceliği devralır. Bitirdiklerinde
öncelikleri orijinal değerlerine döner.
Yukarıdaki örnekte, bir öncelik devralma protokolü, L işleminin H işleminin
önceliğini geçici olarak devralmasına izin verecek ve böylece M işleminin
yürütülmesini engellemesini önleyecektir. L işlemi , S kaynağını kullanmayı
bitirdiğinde , H'den devralınan önceliğinden vazgeçecek ve orijinal önceliğini üstlenecektir.
S kaynağı artık kullanılabilir olacağından, M değil, H süreci çalışırdı.
sonraki.
6.9 Değerlendirme
Önceliğin tersine çevrilmesi, bir zamanlama sıkıntısından daha fazlası olabilir. Gerçek zamanlı
sistemler gibi sıkı zaman kısıtlamaları olan sistemlerde, önceliğin tersine çevrilmesi, bir işlemin
bir görevi tamamlaması gerekenden daha uzun sürmesine neden olabilir. Bu olduğunda, diğer
arızalar kademeli olarak sistem arızasına neden olabilir.
1997'de deneyler yapmak için bir robot olan Sojourner gezginini Mars'a indiren bir NASA uzay
sondası olan Mars Pathfinder'ı düşünün . Sojourner çalışmaya başladıktan kısa bir süre sonra,
sık sık bilgisayar sıfırlamaları yaşamaya başladı.
Her sıfırlama, iletişimler de dahil olmak üzere tüm donanım ve yazılımı yeniden başlattı. Sorun
çözülmemiş olsaydı, Sojourner görevinde başarısız olacaktı.
Sorun, yüksek öncelikli bir görev olan "bc dist"in işini tamamlamasının beklenenden uzun
sürmesinden kaynaklanıyordu. Bu görev, daha düşük öncelikli “ASI/MET” görevi tarafından
tutulan ve daha sonra birden fazla orta öncelikli görev tarafından önlenen paylaşılan bir kaynağı
beklemeye zorlanıyordu. "bc dist" görevi paylaşılan kaynağı beklemeyi durdurur ve nihayetinde
"bc sched" görevi sorunu keşfeder ve sıfırlamayı gerçekleştirir. Sojourner, tipik bir öncelikli ters
çevirme durumundan muzdaripti.
Sojourner'daki işletim sistemi, tüm semaforlarda öncelikli kalıtımı etkinleştirmek için global
bir değişkene sahip olan VxWorks gerçek zamanlı işletim sistemiydi. Testten sonra, değişken
Sojourner'a (Mars'ta!) ayarlandı ve sorun çözüldü.
• Tartışmasız. Her iki seçenek de genellikle hızlı olsa da, CAS koruması
geleneksel senkronizasyondan biraz daha hızlı olacaktır.
6.10 Özet
• Süreçler paylaşılan verilere eşzamanlı erişime sahip olduğunda ve nihai sonuç,
eşzamanlı erişimlerin gerçekleştiği belirli sıraya bağlı olduğunda bir yarış
durumu oluşur. Yarış koşulları, paylaşılan verilerin değerlerinin bozulmasına
neden olabilir.
Alıştırmalar 287
• Kritik bölüm sorunu için donanım desteği, bellek engellerini içerir; karşılaştır ve
değiştir talimatı gibi donanım talimatları; ve atomik değişkenler.
• Bir muteks kilidi, bir işlemin kritik bir bölüme girmeden önce bir kilit almasını ve
kritik bölümden çıkarken kilidi serbest bırakmasını gerektirerek karşılıklı dışlama
sağlar.
• Monitör, yüksek düzeyde bir süreç senkronizasyonu sağlayan soyut bir veri
türüdür. Bir monitör, süreçlerin belirli koşulların gerçekleşmesini beklemesine ve
koşullar doğru olarak ayarlandığında birbirlerine sinyal vermesine izin veren
koşul değişkenlerini kullanır.
• Kritik bölüm problemini çözmenin yanı sıra süreçlerin aktivitesini senkronize etmek
için kullanılabilecek çeşitli araçlar, farklı çekişme seviyeleri altında
değerlendirilebilir. Bazı araçlar, belirli çekişme yükleri altında diğerlerinden
daha iyi çalışır.
Alıştırmalar
6.1 Bölüm 6.4'te, kesintileri sık sık devre dışı bırakmanın sistem saatini
etkileyebileceğini belirtmiştik. Bunun neden olabileceğini ve bu etkilerin nasıl
en aza indirilebileceğini açıklayın.
6.2 Meşgul beklemek deyiminin anlamı nedir ? Bir işletim sisteminde başka ne tür
beklemeler vardır? Meşgul beklemekten tamamen kaçınılabilir mi? Cevabını
açıkla.
6.3 Spinlock'ların neden tek işlemcili sistemler için uygun olmadığını, ancak çok
işlemcili sistemlerde sıklıkla kullanıldığını açıklayın.
6.5 n süreç arasında karşılıklı dışlamayı uygulamak için ikili bir semaforun nasıl
kullanılabileceğini gösterin .
6.6 Yarış koşulları birçok bilgisayar sisteminde mümkündür. İki işlevi olan bir
hesap bakiyesini koruyan bir bankacılık sistemi düşünün: yatırma(tutar) ve
çekme(tutar). Bu iki işlev , banka hesap bakiyesinden yatırılacak veya çekilecek
tutar iletilir. Bir karı kocanın bir banka hesabını paylaştığını varsayalım.
Eşzamanlı olarak, koca geri çekme() işlevini çağırır ve kadın depozito() işlevini
çağırır. Bir yarış koşulunun nasıl mümkün olduğunu ve yarış koşulunun
oluşmasını önlemek için neler yapılabileceğini açıklayın.
Karşılıklı dışlama sorunu ilk olarak [Dijk stra (1965)] tarafından klasik bir makalede
tartışıldı. Semafor kavramı [Dijkstra (1965)] tarafından önerildi. Monitör konsepti
[Brinch-Hansen (1973)] tarafından geliştirilmiştir. [Hoare (1974)] monitörün tam bir
tanımını verdi.
Mars Pathfinder sorunu hakkında daha fazla bilgi için bkz. http://research.microsoft.co
m/en-us/um/people/mbj/mars yol bulucu/yetkili hesap.html
Bellek engelleri ve önbellek hakkında kapsamlı bir tartışma [Mckenney (2010)]'de
sunulmuştur. [Herlihy ve Shavit (2012)], bellek modelleri ve karşılaştır ve değiştir
yönergeleri dahil olmak üzere çok işlemcili programlamayla ilgili çeşitli konular
hakkında ayrıntılar sunar. [Bahra (2013)] modern çok çekirdekli sistemlerde bloksuz
algoritmaları inceliyor.
bibliyografya
[Hoare (1974)] CAR Hoare, “Monitörler: Bir İşletim Sistemi Yapılandırma Kavramı”,
Communications of the ACM, Cilt 17, Sayı 10 (1974), sayfa 549–557.
EX-17
Bölüm 6 Alıştırmalar
6.7 Şekil 6.15'teki sözde kod, dizi tabanlı bir yığının temel push() ve pop()
işlemlerini gösterir. Bu algoritmanın eşzamanlı bir ortamda
kullanılabileceğini varsayarak aşağıdaki soruları yanıtlayın:
a. Hangi verilerin bir yarış durumu var?
6.8 Yarış koşulları birçok bilgisayar sisteminde mümkündür. Her bir ürün
için mevcut en yüksek teklifin muhafaza edilmesi gereken bir
çevrimiçi müzayede sistemi düşünün. Bir öğeye teklif vermek
isteyen bir kişi, teklif edilen tutarı mevcut en yüksek teklifle
karşılaştıran teklif(tutar) işlevini çağırır. Tutar mevcut en yüksek
teklifi aşarsa, en yüksek teklif yeni tutara ayarlanır. Bu, aşağıda gösterilmiştir:
geçersiz teklif(çift tutar) {
if (tutar > en yüksek Teklif) en
yüksek Teklif = miktar;
}
push(item) { if
(üst < SIZE) { stack[top]
= item; üst++;
}
başka
HATA
}
pop() { if
(!is boş()) { üst--; yığını
döndür[üst];
}
başka
HATA
}
is empty() { if
(üst == 0)
true döndür; aksi
takdirde false
döndürür;
}
Egzersizler EX-18
5 10 15 20 3025 35 40
0 1234 5 67
+ + + +
5 15 15 35 25 55 35 75
0 1234 5 67
+ +
5 15 15 50 25 55 35 130
0 1234 5 67
+
5 15 15 50 25 55 35 180
0 1234 5 67
Şekil 6.17 Alıştırma 6.14 için bir diziyi kısmi toplamlar dizisi olarak toplamak.
Bu, Şekil 6.16'da gösterildiği gibi dizideki öğeleri bir dizi kısmi toplam
olarak toplama etkisine sahiptir. Kod yürütüldükten sonra dizideki tüm
öğelerin toplamı son dizi konumunda saklanır.
Yukarıdaki kod örneğinde herhangi bir yarış koşulu var mı? Eğer öyleyse, nerede
meydana geldiklerini belirleyin ve bir örnekle açıklayın. Değilse, bu algoritmanın
neden yarış koşullarından bağımsız olduğunu gösterin.
EX-19
} Düğüm;
do
{ eski düğüm = üst;
yeni düğüm->sonraki = eski düğüm;
}
while (karşılaştır ve değiştir(üst, eski düğüm, yeni düğüm) != eski düğüm);
}
değer t pop() {
Düğüm *eski düğüm;
Düğüm *yeni düğüm;
do
{ eski düğüm = üst; if
(eski düğüm == NULL) NULL
döndürür;
yeni düğüm = eski düğüm->sonraki;
}
while (karşılaştır ve değiştir(üst, eski düğüm, yeni düğüm) != eski düğüm);
6.11 Bir döndürme kilidi uygulamak için karşılaştırma ve takas() kullanımına yönelik bir
yaklaşım aşağıdaki gibidir:
Egzersizler EX-20
while (true) { if
(*lock == 0) {
/* kilit mevcut görünüyor */
}
}
}
6.12 Bazı semafor uygulamaları , bir semaforun geçerli değerini döndüren bir getValue()
işlevi sağlar. Bu işlev, örneğin, wait() işlevini çağırmadan önce çağrılabilir,
böylece bir işlem yalnızca semaforun değeri > 0 ise wait()' i çağırır ve böylece
semaforu beklerken engellemeyi önler. Örneğin:
if (getValue(&sem) > 0)
wait(&sem);
6.13 İki proses için kritik bölüm problemine bilinen ilk doğru yazılım çözümü Dekker
tarafından geliştirilmiştir. İki süreç, P0 ve P1, aşağıdaki değişkenleri paylaşır:
6.14 n 1 dönüş beklemede alt sınırı olan n proses için kritik bölüm problemine bilinen
ilk doğru yazılım çözümü Eisenberg ve McGuire tarafından sunuldu. İşlemler
aşağıdaki değişkenleri paylaşır:
EX-21
while (true)
{ flag[i] = true;
while (bayrak[j]) {
if (dönüş == j) {
bayrak[i] = yanlış;
while (dönüş == j) ; /
* hiçbir şey yapma */
flag[i] = true;
}
}
/* kritik Bölüm */
dönüş = j;
bayrak[i] = yanlış;
/* kalan kısım */
}
Egzersizler EX-22
while (j != i) { if (flag[j] !
= boşta) { j = dönüş; başka
j = (j + 1) %n;
}
flag[i] = cs'de; j = 0;
/* kritik Bölüm */
j = (dönüş + 1) % n;
dönüş = j;
bayrak[i] = boşta;
/* kalan kısım */
}
EX-23
6.20 Bir bağlam anahtarının T zamanını aldığını varsayalım . Bir döndürme kilidini tutmak
için bir üst sınır (T cinsinden) önerin . Döndürme kilidi daha uzun süre tutulursa,
bir muteks kilidi (bekleyen iş parçacıklarının uyku moduna geçirildiği yer) daha iyi
bir alternatiftir.
6.21 Çok iş parçacıklı bir web sunucusu, hizmet verdiği isteklerin sayısını ( isabet olarak
bilinir) takip etmek ister. Değişken vuruşlarda bir yarış koşulunu önlemek için
aşağıdaki iki stratejiyi göz önünde bulundurun . İlk strateji, isabetleri güncellerken
temel bir muteks kilidi kullanmaktır :
int isabetleri;
muteks kilit vuruş kilidi;
lock.acquire()'a basın;
hit++; lock.release()'e
basın;
atomik t vuruşları;
atomic inc(&hits);
6.22 Şekil 6.20'de gösterilen tahsis ve serbest bırakma işlemleri için kod örneğini düşünün.
önlemek için?
6.23 Sunucular, açık bağlantıların sayısını sınırlayacak şekilde tasarlanabilir. Örneğin, bir
sunucu herhangi bir zamanda yalnızca N soket bağlantısına sahip olmak isteyebilir.
N bağlantı yapılır yapılmaz, sunucu mevcut bir bağlantı kurulana kadar başka bir
gelen bağlantıyı kabul etmeyecektir.
Machine Translated by Google
Egzersizler EX-24
/* fork() uygulaması bu işlevi çağırıyor */ int allocate process() { int yeni pid;
piyasaya sürülmüş. Eşzamanlı bağlantıların sayısını sınırlamak için bir sunucu tarafından
semaforların nasıl kullanılabileceğini gösterin.
6.24 Bölüm 6.7'de, kritik bölüm problemini çözmek için semaforların yanlış kullanımı
olarak aşağıdaki çizimi kullanıyoruz:
bekle(mutex);
...
kritik Bölüm
...
bekle(mutex);
6.26 Monitörlerle ilişkili sinyal() işleminin semaforlar için tanımlanan karşılık gelen
işlemden nasıl farklı olduğunu açıklayın.
6.27 Signal() ifadesinin bir monitör işlevinde yalnızca son ifade olarak görünebileceğini
varsayalım . Bu durumda Bölüm 6.7'de açıklanan uygulamanın nasıl
basitleştirilebileceğini önerin.
EX-25
Machine Translated by Google
6.28 Her biri benzersiz bir öncelik numarasına sahip olan P1, P2, ..., Pn süreçlerinden
oluşan bir sistem düşünün . Tahsis sırasına karar vermek için öncelik
numaralarını kullanarak bu işlemlere üç özdeş yazıcı tahsis eden bir monitör
yazın.
6.29 Bir dosya, her biri benzersiz bir numaraya sahip olan farklı işlemler arasında
paylaşılacaktır. Dosyaya, aşağıdaki kısıtlamaya tabi olarak birkaç işlem
tarafından aynı anda erişilebilir: Dosyaya erişmekte olan tüm işlemlerle ilişkili
tüm benzersiz sayıların toplamı n'den küçük olmalıdır. Dosyaya erişimi
koordine etmek için bir monitör yazın.
6.30 Bir monitör içindeki bir koşul üzerinde bir sinyal gerçekleştirildiğinde,
sinyalleşme süreci ya yürütmeye devam edebilir ya da kontrolü sinyal verilen
sürece aktarabilir. Önceki alıştırmanın çözümü, sinyallemenin
gerçekleştirilebileceği bu iki farklı yolla nasıl farklı olabilir?
6.31 Çağıran programın belirli sayıda zaman birimi (tik) boyunca kendisini
geciktirmesini sağlayan bir alarm saati uygulayan bir monitör için bir
algoritma tasarlayın . Monitörünüzde düzenli aralıklarla tik() işlevini çağıran
gerçek bir donanım saatinin varlığını varsayabilirsiniz .
6.32 Gerçek zamanlı bir sistemde öncelikli ters çevirme sorununun ele alınabileceği
yolları tartışın. Çözümlerin orantılı bir paylaşım planlayıcısı bağlamında
uygulanıp uygulanamayacağını da tartışın.
Machine Translated by Google
Programlama Sorunları
6.33 Tek bir kaynak türünden sınırlı sayıda kaynağın yönetilmesi gerektiğini
varsayın. Süreçler bu kaynaklardan birkaçını isteyebilir ve bittiğinde geri
verir. Örnek olarak, birçok ticari yazılım paketi , aynı anda çalışabilecek
uygulamaların sayısını gösteren belirli sayıda lisans sağlar. Uygulama
başlatıldığında lisans sayısı düşürülür. Uygulama sonlandırıldığında lisans
sayısı artırılır. Tüm lisanslar kullanımdaysa, uygulamayı başlatma istekleri
reddedilir. Böyle bir talep, yalnızca mevcut bir lisans sahibinin başvuruyu
feshetmesi ve bir lisans iade edilmesi durumunda kabul edilecektir.
Bir işlem bir dizi kaynak elde etmek istediğinde, count() işlevini azaltmayı
çağırır:
0 döndür;
}
}
Bir işlem bir dizi kaynak döndürmek istediğinde, artırma sayısı() işlevini
çağırır:
0 döndür;
}
6.34 Bir önceki alıştırmada bulunan count() işlevi, yeterli kaynak mevcutsa 0, aksi
takdirde -1 döndürür. Bu, bir dizi kaynak elde etmek isteyen bir süreç için
garip programlamaya yol açar:
sayıyı azalt(say);
7 BÖLÜM
senkronizasyon
Örnekler
Bölüm 6'da kritik bölüm problemini sunduk ve birden fazla eşzamanlı süreç
veri paylaştığında yarış koşullarının nasıl oluşabileceğine odaklandık. Yarış
koşullarının oluşmasını engelleyerek kritik bölüm sorununu ele alan birkaç
aracı incelemeye devam ettik. Bu araçlar, düşük seviyeli donanım çözümlerinden
(bellek bariyerleri ve karşılaştır ve değiştir işlemi gibi) giderek daha yüksek
seviyeli araçlara (mutex kilitlerinden semaforlara ve monitörlere) kadar
uzanıyordu. Ayrıca kilitlenmeler gibi canlılık tehlikeleri de dahil olmak üzere
yarış koşullarından bağımsız uygulamalar tasarlamanın çeşitli zorluklarını tartıştık.
Bu bölümde, Bölüm 6'da sunulan araçları birkaç klasik senkronizasyon
problemine uyguluyoruz. Ayrıca Linux, UNIX ve Windows işletim sistemleri
tarafından kullanılan senkronizasyon mekanizmalarını araştırıyoruz ve hem Java
hem de POSIX sistemleri için API ayrıntılarını açıklıyoruz.
BÖLÜM HEDEFLERİ
290
Bölüm 7 Senkronizasyon Örnekleri
while (doğru) {
...
/* sonraki üretimde bir ürün üret */
...
bekle(boş);
bekle(mutex);
...
/* üretilen sonrakini tampona ekle */
...
sinyal(mutex);
sinyal(dolu);
}
int n;
semafor muteks = 1;
semafor boş = n; semafor
dolu = 0
Üretici sürecinin kodu Şekil 7.1'de, tüketici sürecinin kodu ise Şekil 7.2'de
gösterilmiştir. Üretici ve tüketici arasındaki simetriye dikkat edin. Bu kodu üreticinin
tüketici için dolu tampon ürettiği veya tüketicinin üretici için boş tampon ürettiği
şeklinde yorumlayabiliriz.
while (true)
{ wait(dolu);
bekle(mutex);
...
/* bir öğeyi tampondan sonraki tüketilene kadar kaldır */
...
sinyal(mutex);
sinyal(boş);
...
/* sonraki tüketilen öğeyi tüket */
...
}
birincisine okuyucu , ikincisine yazar olarak atıfta bulunarak bu iki tür süreç arasında
Açıktır ki, iki okuyucu aynı anda paylaşılan verilere erişirse, herhangi bir olumsuz etki
ortaya çıkmayacaktır. Ancak, bir yazar ve başka bir süreç (bir okuyucu veya bir yazar)
veritabanına aynı anda erişirse, kaos ortaya çıkabilir.
while (true)
{ wait(rw mutex);
...
/* yazma yapılır */
...
sinyal(rw muteks);
}
while (true)
{ wait(mutex);
sayıyı oku++; if
(sayıyı oku == 1) wait(rw
mutex); sinyal(mutex);
...
/* okuma yapılır */
...
bekle(mutex);
okuma sayısı--;
if (sayıyı oku == 0)
sinyali(rw muteks);
sinyal(mutex);
}
293
7.1 Klasik Senkronizasyon Sorunları
süreç sadece paylaşılan verileri okumak istiyor, okuma modunda okuyucu-yazıcı kilidini talep
ediyor. Paylaşılan verileri değiştirmek isteyen bir işlem, yazma modunda kilidi talep
etmelidir. Birden çok işlemin okuma modunda aynı anda bir okuyucu-yazar kilidi almasına
izin verilir, ancak yazarlar için özel erişim gerektiğinden yalnızca bir işlem yazma için kilidi
alabilir.
Okuyucu-yazıcı kilitleri en çok aşağıdaki durumlarda kullanışlıdır:
PİLAV
while (true)
{ wait(chopstick[i]);
bekle(çubuk[(i+1) % 5]);
...
/* bir süre yemek ye */
...
sinyal(çubuk[i]);
sinyal(çubuk[(i+1) % 5]);
...
/* bir süre düşün */
...
}
filozoflardan birinin açlıktan öleceğini. Kilitlenmeyen bir çözüm, açlık olasılığını mutlaka
ortadan kaldırmaz.
Ardından, yemek filozofları sorununa kilitlenmeyen bir çözüm sunarak monitör kavramlarını
gösteriyoruz. Bu çözüm, bir filozofun yemek çubuklarını ancak her ikisi de mevcut olduğunda
alabileceği kısıtlamasını dayatır. Bu çözümü kodlamak için bir filozof bulabileceğimiz üç
durumu ayırt etmemiz gerekir. Bu amaçla, aşağıdaki veri yapısını tanıtıyoruz:
Filozof i durumu[i] = YEMEK değişkenini ancak iki komşusu yemek yemiyorsa ayarlayabilirim :
(durum[(i+4) % 5] != YEMEK) ve (durum[(i+1) % 5] ! = YEMEK).
koşul öz[5];
Bu, filozof i'nin aç olduğu, ancak ihtiyaç duyduğu yemek çubuklarını alamadığı zaman kendini
geciktirmesine izin verir.
Artık yemek felsefecileri sorununa çözümümüzü anlatabilecek durumdayız. Çubukların
dağılımı , tanımı Şekil 7.7'de gösterilen DiningPhilosophers monitörü tarafından kontrol edilir .
YemekPhilosophers.pickup(i);
...
yemek
...
YemekPhilosophers.putdown(i);
DiningPhilosophers'ı izleyin {
geçersiz başlatma(int i)
{ durum[i] = AÇ; test(i); if
(durum[i] != YEMEK)
self[i].wait();
void putdown(int i) {
durum[i] = DÜŞÜNMEK; test((i
+ 4) % 5); test((i + 1) % 5);
void testi(int i) {
if ((durum[(i + 4) % 5] != YEMEK) && (durum[i] == AÇ) &&
(durum[(i + 1) % 5] != YEMEK)) { durum[i] = YEMEK
YİYOR; self[i].signal();
}
}
}
}
sinyalsiz işaretli
Sürüm 2.6'dan önce Linux, önleyici olmayan bir çekirdekti; bu, çekirdek modunda
çalışan bir işlemin önceden engellenemeyeceği anlamına geliyordu - daha yüksek
öncelikli bir işlem çalıştırılabilir hale gelse bile. Ancak şimdi, Linux çekirdeği tamamen
önleyicidir, bu nedenle çekirdekte çalışırken bir görev önceden alınabilir.
Linux, çekirdekte senkronizasyon için birkaç farklı mekanizma sağlar. Çoğu
bilgisayar mimarisi, basit matematik işlemlerinin atomik sürümleri için talimatlar
sağladığından, Linux çekirdeği içindeki en basit senkronizasyon tekniği, opak veri
türü atomik t kullanılarak temsil edilen bir atomik tamsayıdır . Adından da anlaşılacağı
gibi, atomik tamsayıların kullanıldığı tüm matematik işlemleri kesintisiz olarak
gerçekleştirilir. Örneklemek için, bir atomik tamsayı sayacından ve bir tamsayı
değerinden oluşan bir program düşünün .
Mutex kilitleri, çekirdek içindeki kritik bölümleri korumak için Linux'ta mevcuttur.
Burada, bir görev kritik bir bölüme girmeden önce mutex lock() işlevini ve kritik
bölümden çıktıktan sonra mutex unlock() işlevini çağırmalıdır. Mutex kilidi
kullanılamıyorsa, mutex lock() işlevini çağıran bir görev uyku durumuna alınır ve kilidin
sahibi mutex unlock() işlevini çağırdığında uyandırılır .
Linux ayrıca çekirdeğe kilitlemek için döndürme kilitleri ve semaforlar (ve bu iki
kilidin okuyucu-yazıcı versiyonları) sağlar. SMP makinelerinde , temel kilitleme
mekanizması bir döndürme kilididir ve çekirdek, döndürme kilidi yalnızca kısa süreler
için tutulacak şekilde tasarlanmıştır. Yalnızca tek bir işlem çekirdeğine sahip gömülü
sistemler gibi tek işlemcili makinelerde, döndürme kilitleri kullanım için uygun değildir
ve çekirdek önceliğini etkinleştirme ve devre dışı bırakma ile değiştirilir. Diğer bir
deyişle, tek bir işlem çekirdeğine sahip sistemlerde, bir spinlock tutmak yerine, çekirdek,
çekirdek önceliğini devre dışı bırakır; ve döndürme kilidini serbest bırakmak yerine,
çekirdeğin önceden alınmasını sağlar. Bu aşağıda özetlenmiştir:
7.3 POSIX Senkronizasyonu 299
Machine Translated by Google
#include <pthread.h>
Mutex, pthread mutex lock() ve pthread mutex unlock() işlevleriyle elde edilir ve
serbest bırakılır . pthread mutex lock() çağrıldığında muteks kilidi kullanılamıyorsa ,
çağıran iş parçacığı, sahibi pthread mutex unlock()'ı çağırana kadar engellenir.
Aşağıdaki kod, muteks kilitleri ile kritik bir bölümü korumayı gösterir:
/* kritik Bölüm */
Tüm muteks işlevleri, doğru işlemle 0 değerini döndürür; bir hata oluşursa, bu
işlevler sıfırdan farklı bir hata kodu döndürür.
sem open() işlevi , sempahor adlı bir POSIX oluşturmak ve açmak için kullanılır :
/* kritik Bölüm */
/* kritik Bölüm */
Muteks kilitleri gibi, tüm semafor işlevleri başarılı olduğunda 0, bir hata durumu
oluştuğunda sıfır dışında döner.
pthread cond wait() işlevi, bir koşul değişkenini beklemek için kullanılır .
Aşağıdaki kod, bir iş parçacığının bir Pthread koşul değişkeni kullanarak a == b
koşulunun gerçekleşmesini nasıl bekleyebileceğini gösterir:
Koşul değişkeniyle ilişkili muteks kilidi , koşullu yan tümcedeki verileri olası bir
yarış koşulundan korumak için kullanıldığından, pthread cond wait() işlevi
çağrılmadan önce kilitlenmelidir . Bu kilit elde edildiğinde, iplik durumu kontrol
edebilir. Koşul doğru değilse, iş parçacığı daha sonra muteks kilidini ve koşul
değişkenini parametre olarak geçirerek pthread cond wait()' i çağırır. pthread
cond wait() işlevinin çağrılması muteks kilidini serbest bırakır, böylece başka bir
iş parçacığının paylaşılan verilere erişmesine ve muhtemelen koşul yan tümcesinin
doğru olarak değerlendirilmesi için değerini güncellemesine izin verir. (Program
hatalarına karşı koruma sağlamak için koşul cümlesini bir döngü içine yerleştirmek
önemlidir, böylece koşul sinyal verildikten sonra yeniden kontrol edilir.)
Machine Translated by Google
Java'daki her nesne onunla tek bir kilit ilişkilendirilmiştir. Bir yöntemin eşitleneceği
bildirildiğinde , yöntemin çağrılması, nesnenin kilidine sahip olmayı gerektirir.
BoundedBuffer sınıfındaki insert() ve remove() yöntemlerinde olduğu gibi, yöntem
tanımına synchronized anahtar sözcüğünü yerleştirerek bir eşitlenmiş yöntem bildiririz.
kilidin sahibi olmak için bu kümeden keyfi olarak bir iş parçacığı seçer. (“Keyfi
olarak” dediğimizde, spesifikasyonun bu kümedeki iş parçacıklarının belirli bir sırada
düzenlenmesini gerektirmediğini kastediyoruz. Bununla birlikte, pratikte çoğu sanal
makine, giriş kümesindeki iş parçacıklarını bir FIFO ilkesine göre sipariş eder.) Şekil
7.10, giriş kümesinin nasıl çalıştığını gösterir.
Bir kilide sahip olmanın yanı sıra, her nesne aynı zamanda bir dizi iş parçacığından
oluşan bir bekleme kümesiyle de ilişkilendirilmiştir. Bu bekleme seti başlangıçta
boştur. Bir iş parçacığı senkronize bir yönteme girdiğinde, nesnenin kilidine sahip
olur. Ancak, bu iş parçacığı belirli bir koşul nedeniyle devam edemediğini belirleyebilir.
kilit almak
nesne
kilidi
sahip
giriş seti
BLOK SENKRONİZASYONU
Bir kilidin alınması ile serbest bırakılması arasındaki süre , kilidin kapsamı
olarak tanımlanır . Paylaşılan verileri manipüle eden kodunun yalnızca
küçük bir yüzdesine sahip senkronize bir yöntem, çok büyük bir kapsam
verebilir. Böyle bir durumda, tüm yöntemi senkronize etmektense, yalnızca
paylaşılan verileri işleyen kod bloğunu senkronize etmek daha iyi olabilir.
Böyle bir tasarım, daha küçük bir kilit kapsamı ile sonuçlanır. Bu nedenle,
senkronize yöntemlerin bildirilmesine ek olarak, Java ayrıca aşağıda
gösterildiği gibi blok senkronizasyonuna da izin verir. Yalnızca kritik bölüm
koduna erişim, bu nesne için nesne kilidinin sahipliğini gerektirir . public
void someMethod() {
/* kritik olmayan bölüm */
synchronized(this) { /* kritik
bölüm */
}
/* kalan kısım */
}
Şekil 7.12, bir kilit için giriş ve bekleme setlerini göstermektedir. ( wait() bir InterruptedException
oluşturabilse de, kodun netliği ve basitliği için onu yok saymayı seçtiğimizi unutmayın.)
arabellek[içinde] = öğe;
in = (+1 olarak) % TAMPON BOYUTU;
say++;
bildir();
}
bildir();
T artık diğer ipliklerle kilit için rekabet etmeye uygundur. T kilidin kontrolünü tekrar
ele geçirdiğinde, count değerini tekrar kontrol edebileceği wait() çağrısından
döner . (Yine, rastgele bir iş parçacığı seçimi Java belirtimine göre yapılır; pratikte,
çoğu Java sanal makinesi, bir FIFO ilkesine göre bekleme kümesinde iş parçacığı
sipariş eder.)
Machine Translated by Google
sahip
• notify() çağrısı , üreticiyi nesne için bekleme kümesinden kaldırır, üreticiyi giriş
kümesine taşır ve üreticinin durumunu çalıştırılabilir olarak ayarlar.
Tuş kilidi(); { /
* kritik
bölümü deneyin */
} nihayet
{ key.unlock();
}
7.4.3 Semaforlar
Java API ayrıca Bölüm 6.6'da açıklandığı gibi bir sayma semaforu sağlar.
Semaforun yapıcısı şu şekilde görünür:
Semafor(int değeri);
değer, semaforun başlangıç değerini belirtir (negatif bir değere izin verilir).
Edinen iş parçacığı kesintiye uğrarsa, gain ( ) yöntemi bir InterruptedException
oluşturur. Aşağıdaki örnek, karşılıklı dışlama için bir semafor kullanmayı
göstermektedir:
Machine Translated by Google
{ sem.acquire()'ı
deneyin ; /* kritik Bölüm */
Semaforun serbest bırakılmasını sağlamak için nihayet yan tümcesine release() çağrısını
yerleştirdiğimize dikkat edin .
Java API'sinde ele aldığımız son yardımcı program , koşul değişkenidir. ReentrantLock ,
Java'nın eşitlenmiş ifadesine benzer olduğu gibi , koşul değişkenleri de wait() ve notify()
yöntemlerine benzer işlevsellik sağlar.
Bu nedenle, karşılıklı dışlama sağlamak için bir koşul değişkeni, bir yeniden giriş kilidi ile
ilişkilendirilmelidir.
Önce bir ReentrantLock oluşturarak ve ilişkili ReentrantLock için koşul değişkenini
temsil eden bir Condition nesnesi döndüren newCondition() yöntemini çağırarak bir
koşul değişkeni yaratırız. Bu, aşağıdaki ifadelerde gösterilmektedir:
Koşul değişkeni elde edildikten sonra, Bölüm 6.7'de açıklanan wait() ve sinyal()
komutlarıyla aynı şekilde işlev gören wait( ) ve signal() yöntemlerini çağırabiliriz.
kilit.kilit();
{ /** *
/**
* Bir süre biraz çalış... */
/**
* Şimdi bir sonraki iş parçacığına sinyal verin.
*/
dönüş = (dönüş + 1) % 5;
condVars[dönüş].signal();
}
}
Ayrıca sıradaki iş parçacığına sinyal vermek için bir ReentrantLock ve beş koşul
değişkeni (iş parçacığının beklediği koşulları temsil eden) oluşturmamız gerekir. Bu
aşağıda gösterilmiştir:
Kilit kilidi = yeni ReentrantLock();
Koşul[] koşulVars = yeni Koşul[5];
Çok çekirdekli sistemlerin ortaya çıkmasıyla birlikte, birden çok işlem çekirdeğinden
yararlanan eşzamanlı uygulamalar geliştirmek için artan baskı geldi. Bununla birlikte,
eşzamanlı uygulamalar, yarış koşulları ve kilitlenme gibi canlılık tehlikeleri açısından
artan bir risk sunar. Geleneksel olarak, muteks kilitleri, semaforlar ve monitörler gibi
teknikler bu sorunları çözmek için kullanılmıştır, ancak işlem çekirdeklerinin sayısı
arttıkça, yarış koşullarından ve kilitlenmeden arınmış çok iş parçacıklı uygulamalar
tasarlamak giderek zorlaşır. Bu bölümde, iş parçacığı güvenli eşzamanlı
uygulamaların tasarımını destekleyen hem programlama dillerinde hem de
donanımda sağlanan çeşitli özellikleri keşfediyoruz.
Bilgisayar biliminde oldukça sık olarak, bir çalışma alanındaki fikirler diğer
alanlardaki sorunları çözmek için kullanılabilir. Örneğin, veritabanı teorisinde
ortaya çıkan işlemsel bellek kavramı , ancak süreç senkronizasyonu için bir strateji
sağlar. Bir bellek işlemi , atomik olan bir bellek okuma-yazma işlemleri dizisidir. Bir
işlemdeki tüm işlemler tamamlanırsa, bellek işlemi tamamlanır. Aksi takdirde,
işlemler durdurulmalı ve geri alınmalıdır. İşlemsel belleğin faydaları, bir
programlama diline eklenen özellikler aracılığıyla elde edilebilir.
elde etmek();
serbest bırakmak();
S'deki işlemler bir işlem olarak yürütülür. Bu, update() işlevini aşağıdaki gibi yeniden
yazmamızı sağlar : void update() {
atom { /*
paylaşılan verileri değiştir */
}
}
7.5.2 Açık MP
Kritik bölüm derleyici yönergesinin kullanımına bir örnek olarak, önce paylaşılan
değişken sayacının update() işlevinde aşağıdaki gibi değiştirilebileceğini
varsayalım :
geçersiz güncelleme(int değeri)
{
sayaç += değer;
}
update() işlevi paralel bir bölgenin parçası olabilir veya buradan çağrılabilirse,
değişken sayacında bir yarış durumu mümkündür .
Bu yarışı düzeltmek için kritik bölüm derleyici yönergesi kullanılabilir
durum ve aşağıdaki gibi kodlanmıştır:
sayaç += değer;
}
}
Kritik bölüm derleyici yönergesi, bir ikili semafor veya muteks kilidi gibi davranır ve
kritik bölümde bir seferde yalnızca bir iş parçacığının etkin olmasını sağlar. Bir iş
parçacığı, o bölümde başka bir iş parçacığı etkinken (yani bölümün sahibiyken)
kritik bir bölüme girmeye çalışırsa , çağıran iş parçacığı, sahibi iş parçacığı çıkana
kadar engellenir. Birden fazla kritik bölüm kullanılması gerekiyorsa, her kritik
bölüme ayrı bir ad atanabilir ve bir kural, aynı adı taşıyan kritik bir bölümde aynı
anda birden fazla iş parçacığının etkin olamayacağını belirtebilir.
iyi bilinen programlama dilleri, zorunlu (veya prosedürel) diller olarak bilinir. Durum
tabanlı algoritmaları uygulamak için zorunlu diller kullanılır. Bu dillerde, algoritmanın
akışı, doğru çalışması için çok önemlidir ve durum, değişkenler ve diğer veri
yapılarıyla temsil edilir. Elbette program durumu değişkendir, çünkü değişkenlere
zaman içinde farklı değerler atanabilir.
7.6 Özet
• Windows, süreci uygulamak için gönderici nesnelerinin yanı sıra olayları kullanır
senkronizasyon araçları.
• Linux, yarış koşullarına karşı koruma sağlamak için çeşitli yaklaşımlar kullanır,
atomik değişkenler, döndürme kilitleri ve muteks kilitleri dahil.
• Java, senkronizasyon için zengin bir kütüphaneye ve API'ye sahiptir. Kullanılabilir araçlar şunları içerir:
monitörler (dil düzeyinde sağlanır) ve reentrant
kilitler, semaforlar ve koşul değişkenleri (bunlar
API).
• Kritik bölüm problemini çözmeye yönelik alternatif yaklaşımlar şunları içerir:
işlem belleği, OpenMP ve işlevsel diller. İşlevsel diller, farklı bir programlama
sundukları için özellikle ilgi çekicidir.
prosedürel dillerden paradigma. Yordamsal dillerin aksine, işlevsel diller
durumlarını korumazlar ve bu nedenle genellikle bağışıktırlar.
yarış koşullarından ve kritik bölümlerden.
Alıştırmalar
bibliyografya 315
7.2 Windows, ince okuyucu-yazıcı kilitleri adı verilen hafif bir eşitleme aracı sağlar .
Okuyucu-yazar kilitlerinin çoğu uygulaması ya okuyucuları ya da yazarları
tercih ederken ya da belki bir FIFO politikası kullanarak bekleyen dizileri
sipariş ederken, ince okuyucu-yazar kilitleri ne okuyucuları ne de yazarları
destekler ve bekleyen diziler bir FIFO kuyruğunda sıralanmaz. Böyle bir
senkronizasyon aracı sağlamanın faydalarını açıklayın.
7.3 İkili bir semafor yerine bir muteks kilidinin kullanılabilmesi için, Şekil 7.1 ve
Şekil 7.2'de üretici ve tüketici süreçlerinde hangi değişikliklerin gerekli
olacağını açıklayın.
7.4 Yemek-filozofları probuyla kilitlenmenin nasıl mümkün olduğunu açıklayın
lem.
7.5 Windows gönderici nesneleri ile sinyalli ve sinyalsiz durumlar arasındaki farkı
açıklayın.
7.6 Val'in bir Linux sistemindeki atomik bir tam sayı olduğunu varsayın . Aşağıdaki
işlemler tamamlandıktan sonra val değeri nedir ?
atomik küme(&val,10);
atomik alt(8,&val); atom
inc(&val); atom inc(&val);
atomik toplama(6,&val);
atom alt(3,&val);
bibliyografya
[Goetz et al. (2006)] B. Goetz, T. Peirls, J. Bloch, J. Bowbeer, D. Holmes ve D. Lea, Java
Concurrency in Practice, Addison-Wesley (2006).
[Oaks (2014)] S. Oaks, Java Performance—The Definitive Guide, O'Reilly & Asso
alıntılar (2014).
Egzersizler EX-26
Bölüm 7 Alıştırmalar
7.7 Yarış koşullarının mümkün olduğu iki çekirdek veri yapısını tanımlayın. Bir yarış
durumunun nasıl oluşabileceğine dair bir açıklama eklediğinizden emin olun.
7.8 Linux çekirdeği, bir sürecin bir semafor elde etmeye çalışırken bir döndürme kilidi
tutamayacağına dair bir ilkeye sahiptir. Bu politikanın neden yürürlükte olduğunu açıklayın.
7.9 Tamponların (kısımların) monitörün içinde gömülü olduğu bir sınırlı arabellek
monitörü için bir algoritma tasarlayın.
7.10 Bir monitördeki katı karşılıklı dışlama, sınırlı arabelleği yapar
Alıştırma 7.14'ün monitörü esas olarak küçük porsiyonlar için uygundur.
7.11 Okur-yazar sorununda adillik ve işlem hacmi arasındaki dengeyi tartışın. Okur-yazar
sorununu açlığa neden olmadan çözmek için bir yöntem önerin.
7.12 Java ReentrantLock'taki lock() yöntemine yapılan çağrının neden istisna işleme için
try yan tümcesine yerleştirilmediğini , ancak unlock() yöntemine yapılan çağrının
neden bir nihayet yan tümcesine yerleştirildiğini açıklayın.
Programlama Sorunları
7.14 Alıştırma 3.20 , her sürece benzersiz bir süreç tanımlayıcısı tahsis eden bir PID yöneticisi
tasarlamanızı gerektiriyordu . Alıştırma 4.28, süreç tanımlayıcılarını talep eden ve
serbest bırakan bir dizi iş parçacığı yaratan bir program yazarak çözümünüzü Alıştırma
3.20'ye göre değiştirmenizi gerektiriyordu. Mutex kilitlerini kullanarak, süreç
tanımlayıcılarının kullanılabilirliğini temsil etmek için kullanılan veri yapısının yarış
koşullarından güvenli olmasını sağlayarak çözümünüzü Alıştırma 4.28'e göre değiştirin.
7.15 Alıştırma 4.27'de Fibonacci dizisini oluşturmak için bir program yazdınız. Program,
hesaplanan değerleri yazdırmadan önce ana iş parçacığının alt iş parçacığının
yürütmesini bitirmesini beklemesini gerektiriyordu.
Ana iş parçacığının, alt iş parçacığı tarafından hesaplandığı anda Fibonacci sayılarına
erişmesine izin verirsek - alt iş parçacığının sona ermesini beklemek yerine - bu
alıştırmanın çözümünde ne gibi değişiklikler gerekli olur? Değiştirilmiş çözümünüzü
uygulayın.
7.16 C programı stack-ptr.c (kaynak kodu indirme dosyasında mevcuttur), bağlantılı bir liste
kullanan bir yığın uygulamasını içerir. Kullanımının bir örneği aşağıdaki gibidir:
7.17 Alıştırma 4.24, Monte Carlo tekniğini kullanarak π'yi tahmin eden çok iş parçacıklı bir
program tasarlamanızı istedi. Bu alıştırmada, sonucu global bir değişkende saklayarak
rastgele noktalar oluşturan tek bir iş parçacığı oluşturmanız istendi. Bu iş parçacığı
çıktıktan sonra, ana iş parçacığı π değerini tahmin eden hesaplamayı gerçekleştirdi.
Bu programı, her biri rastgele noktalar oluşturan ve noktaların daire içine girip
girmediğini belirleyen birkaç iş parçacığı oluşturacak şekilde değiştirin. Her iş
parçacığı, daire içine giren tüm noktaların genel sayısını güncellemek zorunda kalacak.
7.18 Alıştırma 4.25 , Monte Carlo tekniğini kullanarak π tahmin eden OpenMP kullanarak bir
program tasarlamanızı istedi . Olası yarış koşullarını arayan o programa yönelik
çözümünüzü inceleyin. Bir yarış durumu belirlerseniz, Bölüm 7.5.2'de özetlenen
stratejiyi kullanarak buna karşı koruyun.
7.19 Bir bariyer , bir dizi iş parçacığının aktivitesini senkronize etmek için bir araçtır.
Bir iplik bir engel noktasına ulaştığında, diğer tüm iplikler geçene kadar ilerleyemez.
Machine Translated by Google
Konular da bu noktaya geldi. Son iplik engel noktasına ulaştığında, tüm iplikler
serbest bırakılır ve eşzamanlı olarak devam edebilir.
uygulamak.
Bariyerin N olarak başlatıldığını varsayalım - iş parçacığı sayısı
bariyer noktasında beklemesi gereken:
init(N);
Her iplik daha sonra bariyer noktasına ulaşana kadar bir miktar iş yapar:
/* bir süreliğine biraz çalış */
bariyer noktası();
• int init(int n)— Engeli belirtilen boyutta başlatır. • int bariyer noktası(void)
Programlama Projeleri
I. POSIX
Müşteri
Kaynak kodu indirmesinde , thread havuzunun kısmi bir uygulaması olarak threadpool.c C kaynak
dosyasını sağlıyoruz . İstemci kullanıcıları tarafından çağrılan işlevlerin yanı sıra iş parçacığı
havuzunun iç kısımlarını destekleyen birkaç ek işlevi uygulamanız gerekecektir. Uygulama
aşağıdaki faaliyetleri içerecektir:
2. pool send() işlevi kısmen uygulanır ve şu anda yürütülecek işlevi ve verilerini bir görev
yapısına yerleştirir. Görev yapısı, havuzdaki bir iş parçacığı tarafından tamamlanacak işi
temsil eder . havuz gönderme() , enqueue() işlevini çağırarak bu görevleri kuyruğa ekler
ve işçi iş parçacıkları, işi kuyruktan almak için dequeue () 'yi çağırır . Kuyruk, statik olarak
(diziler kullanılarak) veya dinamik olarak (bağlantılı bir liste kullanılarak) uygulanabilir.
pool init() işlevi, görevin havuza başarıyla gönderilip gönderilmediğini belirtmek için
kullanılan bir int dönüş değerine sahiptir (0 başarıyı, 1 başarısızlığı belirtir) . Kuyruk
diziler kullanılarak uygulanırsa, iş gönderme girişimi varsa ve kuyruk doluysa pool init() 1
değerini döndürür. Kuyruk bağlantılı bir liste olarak uygulanırsa, bir bellek ayırma hatası
oluşmadığı sürece pool init() her zaman 0 döndürmelidir.
3. işçi() işlevi , havuzdaki her bir iş parçacığı tarafından yürütülür, burada her iş parçacığı
kullanılabilir çalışmayı bekleyecektir. İş kullanılabilir hale geldiğinde, iş parçacığı onu
kuyruktan kaldırır ve belirtilen işlevi çalıştırmak için execute() öğesini çağırır.
4. Kuyruğa erişirken veya sırayı değiştirirken yarış koşullarından kaçınmak için bir
muteks kilidi gereklidir. (Bölüm 7.3.1, Pthreads muteks kilitleriyle ilgili ayrıntıları
sağlar.)
5. Havuz kapatma() işlevi, her çalışan iş parçacığını iptal edecek ve ardından her iş
parçacığının pthread birleştirme()' yi çağırarak sonlandırılmasını bekleyecektir .
POSIX iş parçacığı iptaliyle ilgili ayrıntılar için Bölüm 4.6.3'e bakın . (Semafor
işlemi sem wait() , bir semaforda bekleyen bir iş parçacığının iptal edilmesini
sağlayan bir iptal noktasıdır.)
II. Java
Bu projenin Java sürümü, Bölüm 7.4'te açıklandığı gibi Java senkronizasyon araçları
kullanılarak tamamlanabilir. Senkronizasyon, (a) synchronized/wait()/notify() (Bölüm
7.4.1) kullanan monitörlere veya (b) semaforlara ve yeniden giriş kilitlerine (Bölüm 7.4.2
ve Bölüm 7.4.3) bağlı olabilir. Java iş parçacıkları Bölüm 4.4.3'te açıklanmıştır.
kullanılabilir hale gelir. ( add() yöntemi, çalışmayı bekleyen boşta bir iş parçacığını
uyandırmak için bir Çalıştırılabilir görevi kuyruğa yerleştirdiğinde, notify() veya semafor
işlemlerini kullanarak bildirim uygulayabilir .)
Bu projeyle ilgili ek ayrıntılar için kaynak kodu indirmesine bakın. Özellikle, BENİOKU dosyası
Java kaynak dosyalarını ve ayrıca Java iş parçacığı kesintisi hakkında daha fazla ayrıntıyı açıklar.
Öğrenciler ve TA
Pthreads'i (Bölüm 4.4.1) kullanarak, her öğrencinin ayrı bir iş parçacığı olarak çalışacağı n
öğrenci oluşturarak başlayın. TA , ayrı bir iş parçacığı olarak da çalışacaktır.
Öğrenci konuları, belirli bir süre için programlama ve TA'dan yardım isteme arasında değişecektir .
TA mevcutsa , yardım alacaklardır. Aksi takdirde, ya koridorda bir sandalyeye oturacaklar ya da hiç
sandalye yoksa, programlamaya devam edecekler ve daha sonra yardım isteyeceklerdir. Bir
öğrenci gelir ve TA'nın uyuduğunu fark ederse, semafor kullanarak TA'ya haber vermelidir. TA bir
öğrenciye yardım etmeyi bitirdiğinde , öğretim görevlisi koridorda yardım bekleyen öğrencilerin
olup olmadığını kontrol etmelidir. Eğer öyleyse, TA sırayla bu öğrencilerin her birine yardım
etmelidir. Öğrenci yoksa, TA uykuya dönebilir.
Öğrenci programlamasının simülasyonunun yanı sıra bir öğrenciye yardım sağlayan TA'nın
simülasyonu için belki de en iyi seçenek , uygun iş parçacıklarının rastgele bir süre boyunca
uyumasını sağlamaktır.
POSIX muteks kilitlerinin ve semaforlarının kapsamı Bölüm 7.3'te verilmiştir.
Ayrıntılar için o bölüme bakın.
Machine Translated by Google
Her iki uygulama da her biri 0 sayısı ile tanımlanan beş filozofun oluşturulmasını
gerektirecektir. . 4. Her filozof ayrı bir iş parçacığı olarak çalışacaktır. Felsefeciler
düşünmek ve yemek arasında gidip gelirler. Her iki aktiviteyi de simüle etmek için, her
bir iş parçacığının bir ile üç saniye arasında rastgele bir süre boyunca uyumasını sağlayın.
I. POSIX
burada filozof sayısı yemek yemek isteyen filozof sayısını tanımlar. Bir filozof
yemeyi bitirdiğinde,
II. Java
Tampon
Dahili olarak, arabellek sabit boyutlu bir tür arabellek öğesi dizisinden oluşacaktır (bir typedef
kullanılarak tanımlanacaktır ). Arabellek öğesi nesneleri dizisi dairesel bir kuyruk olarak işlenecektir.
Arabellek öğesinin tanımı, arabelleğin boyutuyla birlikte aşağıdaki gibi bir başlık dosyasında
saklanabilir:
/* arabellek.h */
typedef int arabellek öğesi;
#define TAMPON BOYUTU 5
Tampon , sırasıyla üretici ve tüketici iş parçacıkları tarafından çağrılan item () ekleme ve item()
kaldırma olmak üzere iki fonksiyonla manipüle edilecektir . Bu işlevleri özetleyen bir iskelet Şekil
7.14'te görülmektedir.
item() ekleme ve item() kaldırma işlevleri , Şekil 7.1 ve Şekil 7.2'de özetlenen algoritmaları
kullanarak üretici ve tüketiciyi senkronize edecektir. Tampon ayrıca, boş ve dolu semaforlarla
birlikte karşılıklı dışlama nesne muteksini başlatan bir başlatma işlevi gerektirecektir .
iş parçacığı sayısı
3. Tüketici iş parçacığı sayısı
#include "buffer.h"
/* arabellek */
arabellek öğesi arabellek[BUFFER SIZE];
Üretici iş parçacığı, rastgele bir süre uyuma ve arabelleğe rastgele bir tamsayı ekleme
arasında geçiş yapacak. Rastgele sayılar, 0 ile RAND MAX arasında rasgele tamsayılar
üreten Rand() işlevi kullanılarak üretilecektir . Tüketici ayrıca rastgele bir süre uyuyacak ve
uyandıktan sonra arabellekteki bir öğeyi çıkarmaya çalışacaktır.
#include "buffer.h"
while (true) { /*
rastgele bir süre uyku */ sleep(...); /* rastgele bir sayı
üret */ item = rand(); if (öğe ekle(öğe)) fprintf("hata
durumunu bildir"); else printf("üretici %d n üretti",item);
while (true) { /*
rastgele bir süre uyku */ sleep(...); if (öğeyi
kaldır(&item)) fprintf("hata durumunu bildir");
başka
printf("tüketici %d n tüketti",item);
}
Daha önce belirtildiği gibi, bu sorunu Pthreads veya Windows API kullanarak
çözebilirsiniz. Aşağıdaki bölümlerde, bu seçeneklerin her biri hakkında daha fazla
bilgi veriyoruz.
Windows Konuları
Mutex kilitleri, Bölüm 7.2.1'de açıklandığı gibi bir tür dağıtıcı nesnesidir. Aşağıda,
CreateMutex() işlevi kullanılarak bir muteks kilidinin nasıl oluşturulacağı
gösterilmektedir:
#include <windows.h>
KOL Mutex;
Mutex = CreateMutex(BOŞ, YANLIŞ, BOŞ);
İlk parametre, muteks kilidi için bir güvenlik özniteliğine başvurur. Bu özniteliği
NULL olarak ayarlayarak , işlemin herhangi bir alt öğesinin kilidin tutamağını
devralmak için bu muteks kilidini oluşturmasını engelleriz. İkinci parametre, muteks
kilidinin yaratıcısının kilidin ilk sahibi olup olmadığını gösterir. YANLIŞ değeri
iletmek, mutex'i oluşturan iş parçacığının ilk sahip olmadığını gösterir.
(Muteks kilitlerinin nasıl elde edildiğini yakında göreceğiz.) Üçüncü parametre,
mutekse isim vermemizi sağlar. Ancak, bir NULL değeri sağladığımız için mutekse
isim vermeyiz. Başarılı olursa, CreateMutex() muteks kilidine bir HANDLE döndürür ;
aksi halde NULL döndürür.
Bölüm 7.2.1'de, gönderici nesnelerini sinyalli veya sinyalsiz olarak tanımladık .
Sahiplik için bir sinyal gönderici nesnesi (bir muteks kilidi gibi) mevcuttur.
Edinildiğinde, sinyalsiz duruma geçer. Serbest bırakıldığında sinyalli duruma döner.
WaitForSingleObject(Mutex, INFINITE);
INFINITE parametre değeri , kilidin kullanılabilir hale gelmesi için sonsuz bir süre
bekleyeceğimizi belirtir. Kilit belirli bir süre içinde kullanılabilir hale gelmezse,
çağıran iş parçacığının zaman aşımına uğramasına izin verecek başka değerler
kullanılabilir. Kilit sinyal durumundaysa, WaitForSingleObject() hemen döner ve kilit
sinyalsiz hale gelir. ReleaseMutex()' i çağırarak bir kilit serbest bırakılır (sinyal edilen
duruma geçer )— örneğin, aşağıdaki gibi:
ReleaseMutex(Mutex);
Windows Semaforları
#include <windows.h>
KULP Sem;
Sem = CreateSemaphore(NULL, 1, 5, NULL);
Machine Translated by Google
İlk ve son parametreler, muteks kilitleri için tanımladığımıza benzer şekilde, bir
güvenlik özniteliği ve semafor için bir isim tanımlar. İkinci ve üçüncü parametreler,
semaforun başlangıç değerini ve maksimum değerini gösterir. Bu örnekte,
semaforun başlangıç değeri 1 ve maksimum değeri 5'tir. Başarılı olursa,
CreateSemaphore() muteks kilidine bir HANDLE döndürür ; aksi halde NULL döndürür.
WaitForSingleObject(Sem, SONSUZ);
ReleaseSemaphore(Sem, 1, NULL);
8 BÖLÜM
kilitlenmeler
BÖLÜM HEDEFLERİ
• Kilitlenmeyi karakterize eden dört gerekli koşulu tanımlayın. • Bir kaynak tahsisi
grafiğinde bir kilitlenme durumu tanımlayın. • Kilitlenmeleri önlemek için dört farklı
yaklaşımlarını değerlendirin.
317
Machine Translated by Google
Mutex kilitleri ve semaforlar gibi Bölüm 6'da tartışılan çeşitli senkronizasyon araçları
da sistem kaynaklarıdır; ve çağdaş bilgisayar sistemlerinde en yaygın kilitlenme
kaynaklarıdır. Ancak, tanımlama burada bir sorun değildir. Bir kilit tipik olarak belirli bir
veri yapısıyla ilişkilendirilir; yani, bir kilit bir kuyruğa erişimi korumak için, diğeri
bağlantılı bir listeye erişimi korumak için kullanılabilir ve benzerleri. Bu nedenle, bir
kilidin her örneğine tipik olarak kendi kaynak sınıfı atanır.
Normal çalışma modunda, bir iş parçacığı bir kaynağı yalnızca aşağıdaki sırayla
kullanabilir:
tablo ayrıca tahsis edildiği iş parçacığını da kaydeder. Bir iş parçacığı, şu anda başka bir iş
parçacığına tahsis edilmiş bir kaynak isterse, bu kaynağı bekleyen bir iş parçacığı
kuyruğuna eklenebilir.
Bir dizi iş parçacığı, kümedeki her iş parçacığı, yalnızca kümedeki başka bir iş
parçacığının neden olabileceği bir olayı beklerken kilitlenmiş durumda. Burada esas olarak
ilgilendiğimiz olaylar, kaynak edinimi ve serbest bırakılmasıdır.
Kaynaklar tipik olarak mantıksaldır (örneğin, muteks kilitleri, semaforlar ve dosyalar); ancak,
Bölüm 3'te tartışılan bir ağ arabiriminden veya IPC (işlemler arası iletişim) olanaklarından
okuma da dahil olmak üzere diğer olay türleri kilitlenmelere neden olabilir .
Bir çıkmaz durumu göstermek için, Bölüm 7.1.3'teki yemek-filozofları sorununa geri
dönüyoruz. Bu durumda, kaynaklar yemek çubukları ile temsil edilir. Bütün filozoflar aynı
anda acıkırsa ve her filozof solundaki yemek çubuğunu tutarsa, artık kullanılabilir yemek
çubuğu yoktur. Daha sonra her filozof, sağ çubuğunun kullanılabilir olmasını beklerken
engellenir.
Ardından, birinci iş parçacığı ve ikinci iş parçacığı olmak üzere iki iş parçacığı oluşturulur
ve bu iş parçacıklarının her ikisinin de her iki muteks kilidine erişimi vardır. bir iplik ve iki iplik
Şekil 8.1'de gösterildiği gibi sırasıyla do work one() ve do work work () fonksiyonlarında
çalıştırın .
Bu örnekte, iplik bir muteks kilitlerini (1) birinci muteks, (2) ikinci muteks sırasına göre
elde etmeye çalışır . Aynı zamanda, (1) ikinci muteks, (2) birinci muteks sırasına göre muteks
kilitlerini elde etmek için iki girişimde bulunun. Bir iş parçacığı birinci muteks alırken, ikinci
iş parçacığı ikinci muteks alırsa kilitlenme mümkündür .
320
Bölüm 8 Kilitlenmeler
Machine Translated by Google
* Biraz iş yapın */
pthread mutex
unlock(&second mutex); pthread mutex kilidini(&ilk
mutex);
* Biraz iş yap */
Canlı kilit, bloke etmeden bir muteks kilidi elde etmeye çalışan Pthreads pthread mutex
trylock() işleviyle gösterilebilir. Şekil 8.2'deki kod örneği, Şekil 8.1'deki örneği şimdi pthread
mutex trylock() kullanacak şekilde yeniden yazar. Bu durum, birinci iş parçacığı ilk muteks,
ardından ikinci iş parçacığı ikinci muteks ediniyorsa , canlı kilitlenmeye yol açabilir .
Her iş parçacığı daha sonra başarısız olan, ilgili kilitlerini serbest bırakan ve aynı eylemleri süresiz
olarak tekrarlayan pthread mutex trylock()'u çağırır.
Livelock, tipik olarak, iş parçacıkları aynı anda başarısız işlemleri yeniden denediğinde ortaya
çıkar. Bu nedenle, her bir iş parçacığının başarısız işlemi rastgele zamanlarda yeniden denemesini
sağlayarak genellikle önlenebilir. Bu, bir ağ çakışması meydana geldiğinde Ethernet ağları
tarafından alınan yaklaşımdır. Bir çarpışma meydana geldikten hemen sonra bir paketi yeniden
iletmeye çalışmak yerine, bir çarpışmaya karışan bir ana bilgisayar, tekrar iletmeyi denemeden
önce rastgele bir süre geri çekilecektir.
Canlı kilitlenme, kilitlenmeden daha az yaygındır, ancak yine de eşzamanlı uygulamaların
tasarlanmasında zorlu bir konudur ve kilitlenme gibi, yalnızca belirli zamanlama koşullarında ortaya
çıkabilir.
Önceki bölümde, muteks kilitleri kullanan çok iş parçacıklı programlamada kilitlenmenin nasıl
oluşabileceğini gösterdik. Şimdi kilitlenmeyi karakterize eden koşullara daha yakından bakıyoruz.
Aşağıdaki dört koşul bir sistemde aynı anda geçerliyse bir kilitlenme durumu ortaya çıkabilir:
1. Karşılıklı dışlama. En az bir kaynak paylaşılamaz modda tutulmalıdır; yani, bir seferde yalnızca
bir iş parçacığı kaynağı kullanabilir. Başka bir iş parçacığı bu kaynağı talep ederse, istekte
bulunan iş parçacığı, kaynak serbest bırakılıncaya kadar ertelenmelidir.
3. Önlem yok. Kaynaklar engellenemez; yani, bir kaynak yalnızca onu tutan iş parçacığı
tarafından, o iş parçacığı görevini tamamladıktan sonra gönüllü olarak serbest bırakılabilir.
4. Dairesel bekleme. Bir dizi {T0, T1, ..., Tn} bekleyen iş parçacığı mevcut olmalıdır, öyle ki T0 ,
T1 tarafından tutulan bir kaynağı bekliyor , T1 , T2 tarafından tutulan bir kaynağı
bekliyor , ..., Tn 1 bekliyor Tn tarafından tutulan bir kaynak ve Tn , T0 tarafından tutulan bir
kaynağı bekliyor .
Bir kilitlenmenin oluşması için dört koşulun hepsinin geçerli olması gerektiğini vurguluyoruz.
Dairesel bekleme koşulu, bekle ve bekle koşulunu ifade eder, bu nedenle dört
322 Bölüm 8 Kilitlenmeler
Machine Translated by Google
int yapıldı = 0;
} else
pthread mutex unlock(&first mutex);
}
int yapıldı = 0;
} else
pthread mutex unlock(&ikinci mutex);
}
.
first_mutex
.
ikinci_mutex
thread_one thread_two
koşullar tamamen bağımsız değildir. Bununla birlikte, her koşulu ayrı ayrı ele
almanın yararlı olduğunu Bölüm 8.5'te göreceğiz.
Kilitlenmeler, sistem kaynak tahsisi grafiği adı verilen yönlendirilmiş bir grafik
açısından daha kesin olarak tanımlanabilir . Bu grafik, bir V köşe kümesinden ve bir E
kenar kümesinden oluşur. V köşe kümesi, iki farklı düğüm tipine bölünür: T = {T1,
T2, ..., Tn}, tüm düğümlerden oluşan küme. sistemdeki aktif iş parçacıkları ve R = {R1,
R2, ..., Rm}, sistemdeki tüm kaynak türlerinden oluşan küme.
• T, R ve E kümeleri :
R1 R3
T1 T2 T3
R2
R4
R1 R3
T1 T2 T3
R2
R4
kenar T3 R2 grafiğe (Şekil 8.5). Bu noktada sistemde iki minimum döngü vardır:
T1 R1 T2 R3 T3 R2 T1
T2 R3 T3 R2 T2
T1 R1 T3 R2 T1
T2
R1
T3
T1
R2
T4
Şekil 8.6 Bir döngüye sahip ancak kilitlenme olmayan kaynak tahsisi grafiği.
Machine Translated by Google
İlk çözüm, Linux ve Windows dahil olmak üzere çoğu işletim sistemi tarafından
kullanılan çözümdür. Daha sonra, genellikle ikinci çözümde özetlenen yaklaşımları
kullanarak kilitlenmeleri işleyen programlar yazmak çekirdek ve uygulama
geliştiricilerine kalmıştır. Veritabanları gibi bazı sistemler üçüncü çözümü benimser,
kilitlenmelerin oluşmasına izin verir ve ardından kurtarmayı yönetir.
Ardından, kilitlenmeleri ele almak için üç yöntemi kısaca detaylandıracağız.
Ardından, Bölüm 8.5 ila Bölüm 8.8'de ayrıntılı algoritmalar sunuyoruz. Devam
etmeden önce, bazı araştırmacıların, işletim sistemlerindeki tüm kaynak tahsisi
sorunları yelpazesi için temel yaklaşımlardan hiçbirinin tek başına uygun olmadığını
savunduklarını belirtmeliyiz. Bununla birlikte, temel yaklaşımlar birleştirilebilir, bu da
bir sistemdeki her kaynak sınıfı için en uygun yaklaşımı seçmemize izin verir.
kilitlenme (eğer gerçekten bir kilitlenme oluşmuşsa). Bu konuları Bölüm 8.7 ve Bölüm
8.8'de tartışıyoruz.
Kilitlenmeleri tespit edecek ve bu kilitlenmelerden kurtulacak algoritmaların
yokluğunda, sistemin kilitlenme durumunda olduğu ancak ne olduğunu tanımanın
hiçbir yolu olmadığı bir duruma varabiliriz. Bu durumda, tespit edilmeyen kilitlenme,
sistemin performansının bozulmasına neden olacaktır, çünkü kaynaklar çalışamayan iş
parçacıkları tarafından tutulmaktadır ve giderek daha fazla iş parçacığı, kaynaklar için
istekte bulundukça, kilitlenme durumuna girecektir. Sonunda sistem çalışmayı durduracak
ve manuel olarak yeniden başlatılması gerekecek.
Bu yöntem, kilitlenme sorununa uygulanabilir bir yaklaşım gibi görünmese de, daha
önce belirtildiği gibi çoğu işletim sisteminde kullanılmaktadır. Harcama önemli bir
husustur. Kilitlenme olasılığını göz ardı etmek diğer yaklaşımlardan daha ucuzdur.
Birçok sistemde kilitlenmeler nadiren (örneğin ayda bir) meydana geldiğinden, diğer
yöntemlerin ekstra masrafı buna değmeyebilir.
Ek olarak, canlı kilitlenme gibi diğer canlılık koşullarından kurtulmak için kullanılan
yöntemler, kilitlenmeden kurtulmak için kullanılabilir. Bazı durumlarda, bir sistem bir
canlılık hatasından muzdariptir ancak kilitlenme durumunda değildir.
Bu durumu, örneğin, en yüksek öncelikte çalışan gerçek zamanlı bir iş parçacığında
(veya önleyici olmayan bir zamanlayıcıda çalışan herhangi bir iş parçacığında) ve kontrolü
hiçbir zaman işletim sistemine geri döndürmediğinde görüyoruz. Sistem, bu tür koşullar
için manuel kurtarma yöntemlerine sahip olmalıdır ve bu teknikleri yalnızca kilitlenme
kurtarma için kullanabilir.
Bölüm 8.3.1'de belirttiğimiz gibi, bir kilitlenmenin oluşması için dört gerekli koşulun her
birinin geçerli olması gerekir. Bu koşullardan en az birinin gerçekleşmemesini sağlayarak
bir kilitlenme oluşmasını engelleyebiliriz . Bu yaklaşımı, gerekli dört koşulun her birini ayrı
ayrı inceleyerek detaylandırıyoruz.
Karşılıklı dışlama koşulu geçerli olmalıdır. Yani, en az bir kaynak paylaşılamaz olmalıdır.
Paylaşılabilir kaynaklar, birbirini dışlayan erişim gerektirmez ve bu nedenle bir kilitlenmeye
dahil olamaz. Salt okunur dosyalar, paylaşılabilir bir kaynağa iyi bir örnektir. Birkaç iş
parçacığı aynı anda salt okunur bir dosyayı açmaya çalışırsa, dosyaya aynı anda erişim
izni verilebilir. Bir iş parçacığının asla paylaşılabilir bir kaynak beklemesi gerekmez. Ancak
genel olarak, bazı kaynaklar doğası gereği paylaşılamaz olduğundan, karşılıklı dışlama
koşulunu reddederek kilitlenmeleri önleyemeyiz. Örneğin, bir muteks kilidi aynı anda
birkaç iş parçacığı tarafından paylaşılamaz.
Tut ve bekle koşulunun sistemde hiçbir zaman oluşmamasını sağlamak için, bir iş
parçacığı bir kaynak istediğinde, başka hiçbir kaynağı tutmadığını garanti etmeliyiz.
Kullanabileceğimiz bir protokol, her iş parçacığının yürütmeye başlamadan önce tüm
kaynaklarını istemesini ve tahsis edilmesini gerektirir. Bu, elbette,
328 Bölüm 8 Kilitlenmeler
Machine Translated by Google
Örneklemek için, R = {R1, R2, ..., Rm} kaynak türleri kümesi olsun. Her kaynak
türüne benzersiz bir tam sayı atarız, bu da
Machine Translated by Google
F(ilk muteks)=1
F(ikinci muteks)=5
Ayrıca, kilitler dinamik olarak alınabiliyorsa, bir kilit siparişi vermenin önceden
kilitlenme önlemeyi garanti etmediğini belirtmek önemlidir. Örneğin, iki hesap
arasında para transferi yapan bir fonksiyonumuz olduğunu varsayalım.
Bir yarış koşulunu önlemek için, her hesabın Şekil 8.7'de gösterildiği gibi bir get lock()
işlevinden elde edilen ilişkili bir muteks kilidi vardır.
Kilitlenme, iki iş parçacığı aynı anda işlem() işlevini çağırarak farklı hesapları aktarırsa
mümkündür. Yani, bir iş parçacığı çağırabilir
edin(kilit1);
edin(kilit2);
çekmek(den, miktar);
depozito(to, miktar);
serbest bırakma(kilit2);
serbest bırakma(kilit1);
}
Sistem her bir iş parçacığına (maksimum değerine kadar) kaynakları belirli bir
sırayla tahsis edebiliyorsa ve yine de bir kilitlenmeyi önleyebiliyorsa, durum
güvenlidir . Daha resmi olarak, bir sistem yalnızca güvenli bir sıra varsa güvenli
durumdadır . <T1, T2, ..., Tn> iş parçacığı dizisi , Ti'nin hala yapabileceği kaynak
tarafından
isteklerinin
karşılanabiliyorsa,
her biri için mevcut
mevcut
Ti ,tahsis
mevcutdurumu
kaynaklar
içinartı
güvenli
tutulan
bir kaynaklar
dizidir. tüm
Tj tarafından , j < i ile. Bu durumda, Ti'nin ihtiyaç duyduğu
mevcut
kaynaklar
değilse,hemen
Ti tüm
Tj'ler bitene kadar bekleyebilir . Bitirdiklerinde, Ti tüm özelliklerini elde edebilir.
Machine Translated by Google
güvensiz
kilitlenme
güvenli
gerekli kaynaklar, belirlenmiş görevi tamamlayın, tahsis edilen kaynakları iade edin ve sonlandırın. Ti sona
erdiğinde, Ti +1 gerekli kaynakları elde edebilir, vb. Böyle bir sıra yoksa, sistem durumunun güvensiz
olduğu söylenir.
Güvenli durum, kilitlenmiş bir durum değildir. Tersine, kilitlenme durumu güvenli olmayan bir
durumdur. Ancak, tüm güvensiz durumlar kilitlenme değildir (Şekil 8.8).
Güvenli olmayan bir durum kilitlenmeye neden olabilir . Durum güvenli olduğu sürece, işletim sistemi
güvenli olmayan (ve kilitlenmemiş) durumlardan kaçınabilir. Güvenli olmayan bir durumda, işletim sistemi,
iş parçacıklarının bir kilitlenme meydana gelecek şekilde kaynak istemesini engelleyemez. İş parçacıklarının
davranışı güvenli olmayan durumları kontrol eder.
Örneklemek için, on iki kaynağı ve üç iş parçacığı olan bir sistemi düşünün: T0, T1 ve T2. T0 iş
parçacığı on kaynak gerektirir, T1 iş parçacığı dörde ihtiyaç duyabilir ve T2 iş parçacığı en fazla dokuz
kaynağa ihtiyaç duyabilir. t0 zamanında , T0 iş parçacığının beş kaynak tuttuğunu, T1 iş parçacığının iki
kaynak tuttuğunu ve T2 iş parçacığının iki kaynak tuttuğunu varsayalım . (Dolayısıyla, üç ücretsiz kaynak
vardır.)
10 5
T0
4 2
T1
9 2
T2
t0 anında sistem güvenli durumdadır. <T1, T0, T2> dizisi güvenlik koşulunu karşılamaktadır. T1 iş
parçacığı , tüm kaynaklarını hemen tahsis edebilir ve daha sonra bunları iade edebilir (sistem daha sonra
beş kullanılabilir kaynağa sahip olacaktır); daha sonra T0 iş parçacığı tüm kaynaklarını alabilir ve geri
gönderebilir (bu durumda sistem on kullanılabilir kaynağa sahip olacaktır); ve son olarak, iş parçacığı T2
tüm kaynaklarını alabilir ve geri gönderebilir (bu durumda sistem on iki kaynağın tümüne sahip olacaktır).
Bir sistem güvenli durumdan güvenli olmayan bir duruma geçebilir. Diyelim ki, t1 zamanında , T2 iş
parçacığı istekte bulundu ve bir kaynak daha tahsis edildi. Sistem artık güvenli durumda değil. Bu noktada,
tüm kaynakları yalnızca T1 iş parçacığına tahsis edilebilir.
Onları döndürdüğünde, sistem yalnızca dört kullanılabilir kaynağa sahip olacaktır.
T0 iş parçacığına beş kaynak tahsis edildiğinden ancak en fazla on kaynak bulunduğundan, beş kaynak
daha talep edebilir. Bunu yaparsa, beklemesi gerekecek çünkü müsait değiller. Benzer şekilde, T2 iş
parçacığı altı ek kaynak talep edebilir ve beklemesi gerekebilir, bu da bir kilitlenmeye neden olur. Hatamız,
T2 iş parçacığından bir kaynak daha isteğini vermekti. T2'yi ikisinden birine kadar bekletmiş olsaydık
Machine Translated by Google
Bu şemada, bir iş parçacığı halihazırda mevcut olan bir kaynağı talep ederse, yine
de beklemesi gerekebilir. Bu nedenle, kaynak kullanımı, aksi takdirde olacağından daha
düşük olabilir.
Her kaynak türünün yalnızca bir örneğine sahip bir kaynak tahsisat sistemimiz varsa,
kilitlenmeden kaçınmak için Bölüm 8.3.2'de tanımlanan kaynak tahsisi grafiğinin bir
türevini kullanabiliriz. Daha önce açıklanan istek ve atama kenarlarına ek olarak, talep
kenarı adı verilen yeni bir kenar türü sunuyoruz . Bir talep kenarı Ti Rj , Ti parçacığının
gelecekte bir zamanda Rj kaynağı talep edebileceğini gösterir. Bu kenar, yönde bir
istek kenarına benzer, ancak grafikte kesikli bir çizgi ile temsil edilir. Ti parçacığı Rj
kaynağını istediğinde , talep kenarı Ti Rj bir istek kenarına dönüştürülür. Benzer
şekilde,
bir kaynak Rj Ti tarafından serbest bırakıldığında , atama kenarı Rj Ti yeniden bir
talep kenarına Ti Rj dönüştürülür .
Döngü yoksa, kaynağın tahsisi sistemi güvenli bir durumda bırakacaktır. Bir döngü
bulunursa, tahsis sistemi güvenli olmayan bir duruma sokar. Bu durumda, Ti parçacığı
isteklerinin yerine getirilmesini beklemek zorunda kalacaktır.
Bu algoritmayı göstermek için Şekil 8.9'daki kaynak tahsisi grafiğini ele alıyoruz.
T2'nin R2'yi istediğini varsayalım . R2 şu anda ücretsiz olsa da bu işlem grafikte bir
döngü oluşturacağından T2'ye tahsis edemiyoruz (Şekil 8.10). Belirtildiği gibi bir
döngü, sistemin güvenli olmayan bir durumda olduğunu gösterir. T1 R2'yi ve T2 R1'i
talep ederse , bir kilitlenme meydana gelir.
Kaynak tahsisi grafiği algoritması, her kaynak türünün birden çok örneğine sahip bir
kaynak tahsis sistemine uygulanamaz. bu
334 Bölüm 8 Kilitlenmeler
Machine Translated by Google
R1
T1 T2
R2
R1
T1 T2
R2
sayısını tanımlar. Allocation [i][j] k'ye eşitse , o zaman Ti iş parçacığına şu anda Rj kaynak
türünün k örneği tahsis edilir . • İhtiyaç. Bir n × m matrisi, her bir iş parçacığının
kalan kaynak ihtiyacını gösterir. Eğer Need[i][j] k'ye eşitse , Ti iş parçacığının görevini
tamamlamak için k tane daha Rj kaynak tipi örneğine ihtiyacı olabilir . İhtiyaç[i][j]' nin
Maks[i][j]'ye eşit olduğunu unutmayın.
Tahsis[i][j].
Bu veri yapıları zaman içinde hem boyut hem de değer olarak değişir.
Bankacının algoritmasının sunumunu basitleştirmek için daha sonra bazı notasyonlar
oluşturacağız. X ve Y , n uzunluğunda vektörler olsun . X Y olduğunu ancak ve ancak X[i]
Y[i] ise tüm i = 1, 2, ..., n için söylüyoruz
Y X. .Ayrıca
Örneğin,
Y X=
ve(1,7,3,2)
Y veYY<=X.
X ise (0,3,2,1) ise, o zaman
Allocation ve Need matrislerindeki her satırı vektör olarak ele alabilir ve Allocationi ve
Needi olarak adlandırabiliriz . Allocationi vektörü , şu anda Ti iş parçacığına tahsis edilen
kaynakları belirtir ; Needi vektörü , Ti iş parçacığının görevini tamamlamak için hala
isteyebileceği ek kaynakları belirtir .
Artık bir sistemin güvenli durumda olup olmadığını bulmak için algoritmayı sunabiliriz. Bu
algoritma şu şekilde açıklanabilir:
a. Bitir[i] == yanlış
b. İhtiyaç İş
Bu algoritma, bir durumun güvenli olup olmadığını belirlemek için bir m × n2 işlem sırası
gerektirebilir .
1. Eğer Requesti Needi ise 2. adıma gidin. Aksi takdirde, bir hata koşulu yükseltin, çünkü
iş parçacığı maksimum iddiasını aştı.
2. Eğer Requesti Uygun ise adım 3'e gidin. Aksi takdirde, Ti'nin beklemesi gerekir.
kaynaklar mevcut değildir.
Mevcut = Mevcut–Talep
Tahsis = Tahsis + Talep
Needi = Needi -Requesti
İhtiyaç
ABC
T0 743
T1 122
T2 600
T3 011
T4 431
Sistemin şu anda güvenli bir durumda olduğunu iddia ediyoruz. Nitekim, sıra
<T1, T3, T4, T2, T0> güvenlik kriterlerini karşılar. Diyelim ki şimdi bu iş parçacığı
T1 , ek bir A tipi kaynak örneği ve iki örnek talep eder.
kaynak türü C, bu nedenle İstek1 = (1,0,2). Bu isteğin gerçekleşip gerçekleşemeyeceğine karar vermek için
hemen verildiğinde, önce İstek1 Uygun olup olmadığını kontrol ederiz - yani
8.7 Kilitlenme Algılama 337
Machine Translated by Google
ABC ABC
T0 010 743 230
T1 302 020
T2 302 600
T3 211 011
T4 002 431
Bu yeni sistem durumunun güvenli olup olmadığını belirlememiz gerekiyor. Bunu yapmak için, biz
güvenlik algoritmamızı yürütün ve <T1, T3, T4, T0, T2> dizisini bulun
güvenlik gereksinimini karşılar. Bu nedenle, isteği hemen verebiliriz
iplik T1.
Bununla birlikte, sistem bu durumdayken, bir
kaynaklar mevcut olmadığı için T4 tarafından (3,3,0) talebi kabul edilemez.
Ayrıca, T0 tarafından (0,2,0) için bir istek ,
Ortaya çıkan durum güvenli olmadığı için kaynaklar mevcuttur.
Bunu, öğrencilerin uygulamayı gerçekleştirmeleri için bir programlama alıştırması olarak bırakıyoruz.
bankacı algoritması.
Bir sistem bir kilitlenme önleme veya bir kilitlenme önleme algoritması
kullanmıyorsa, bir kilitlenme durumu meydana gelebilir. Bu ortamda,
sistem şunları sağlayabilir:
Tüm kaynakların yalnızca tek bir örneği varsa, kaynak tahsisi grafiğinin bir
türevini kullanan bir kilitlenme algılama algoritması tanımlayabiliriz.
bir bekleme grafiği. Bu grafiği kaynak tahsisi grafiğinden şu şekilde elde ederiz:
kaynak düğümlerini kaldırmak ve uygun kenarları daraltmak.
Daha doğrusu, bir bekleme grafiğinde Ti'den Tj'ye bir kenar, ipliğin
Ti , Tj iş parçacığının Ti'nin ihtiyaç duyduğu bir kaynağı serbest bırakmasını bekliyor . Bir kenar Ti Tj
Machine Translated by Google
338
Bölüm 8 Kilitlenmeler
T5
R1 R3 R4
T5
T1 T2 T3
T1 T2 T3
T4
T4
R2 R5
(a) (b)
Şekil 8.11 (a) Kaynak tahsisi grafiği. (b) Karşılık gelen bekleme grafiği.
bir bekleme grafiğinde, ancak ve ancak karşılık gelen kaynak tahsis grafiği, bazı
Rq kaynakları için Ti Rq ve Rq Tj olmak üzere iki kenar içeriyorsa mevcuttur .
Şekil 8.11'de bir kaynak tahsisi grafiği ve buna karşılık gelen bekleme grafiği
sunuyoruz.
Daha önce olduğu gibi, sistemde yalnızca ve yalnızca bekleme grafiği bir
döngü içeriyorsa bir kilitlenme vardır. Kilitlenmeleri algılamak için sistemin grafiği
beklemeyi sürdürmesi ve grafikte bir döngü arayan bir algoritmayı periyodik olarak
başlatması gerekir. Bir grafikteki bir döngüyü algılamak için bir algoritma, O(n2)
işlemlerini gerektirir; burada n , grafikteki köşe sayısıdır.
Bölüm 2.10.4'te açıklanan BCC araç takımı, bir Linux sisteminde çalışan bir
kullanıcı işleminde Pthreads muteks kilitleriyle olası kilitlenmeleri algılayabilen bir
araç sağlar. BCC aracı kilitlenme algılayıcısı , pthread mutex lock() ve pthread
mutex unlock() işlevlerine yapılan çağrıları izleyen problar ekleyerek çalışır .
Belirtilen süreç herhangi bir işleve çağrı yaptığında, kilitlenme algılayıcısı bu
süreçte muteks kilitlerinin bir bekleme grafiği oluşturur ve grafikte bir döngü
algılarsa kilitlenme olasılığını bildirir.
Java, kilitlenme tespiti için açık destek sağlamasa da, bir kilitlenme olup olmadığını belirlemek
için çalışan bir programı analiz etmek için bir iş parçacığı dökümü kullanılabilir. İş parçacığı
dökümü, bir Java uygulamasındaki tüm iş parçacıklarının durumlarının anlık görüntüsünü
görüntüleyen kullanışlı bir hata ayıklama aracıdır. Java iş parçacığı dökümleri ayrıca, bloke
edilmiş bir iş parçacığının hangi kilitleri almayı beklediği de dahil olmak üzere kilitleme bilgilerini
gösterir. Bir iş parçacığı dökümü oluşturulduğunda, JVM döngüleri algılamak için bekleme
grafiğini arar ve algıladığı kilitlenmeleri bildirir. Çalışan bir uygulamanın iş parçacığı dökümünü
oluşturmak için komut satırından şunu girin:
Bu metnin kaynak kodu indirmesinde, Şekil 8.1'de gösterilen programın bir Java örneğini
sunuyoruz ve kilitlenmiş Java iş parçacıklarını bildiren bir iş parçacığı dökümünün nasıl
oluşturulacağını açıklıyoruz.
• Tahsis. Bir n × m matrisi, her bir iş parçacığına o anda tahsis edilen her türden
kaynak sayısını tanımlar.
a. Bitir[i] == yanlış
b. İstek İş
4. Bazı i, 0 i < n için Finish[i] == false ise, sistem kilitlenme durumundadır. Ayrıca,
Finish[i] == false ise, Ti parçacığı kilitlenir.
Rica etmek
ABC
T0 000
T1 202
T2 001
T3 100
T4 002
Kilitlenmeler sık sık meydana geliyorsa, algılama algoritması sık sık çalıştırılmalıdır.
Kilitlenen iş parçacıklarına ayrılan kaynaklar, kilitlenme bozulana kadar boşta
kalacaktır. Ek olarak, kilitlenme döngüsüne dahil olan iş parçacıklarının sayısı
artabilir.
Kilitlenmeler, yalnızca bazı iş parçacıkları hemen verilemeyen bir istekte
bulunduğunda meydana gelir. Bu istek, bir bekleyen iş parçacığı zincirini
tamamlayan son istek olabilir. Aşırı durumda, bir tahsisat talebinin hemen
verilemeyeceği her zaman kilitlenme tespit algoritmasını çağırabiliriz. Bu durumda,
yalnızca kilitlenen iş parçacığı kümesini değil, aynı zamanda kilitlenmeye "neden
olan" belirli iş parçacığını da tanımlayabiliriz. (Gerçekte, kilitlenen iş parçacıklarının
her biri, kaynak grafiğindeki döngüdeki bir bağlantıdır, bu nedenle hepsi birlikte
kilitlenmeye neden olur.) Birçok farklı kaynak türü varsa, bir istek kaynak grafiğinde
birçok döngü oluşturabilir. , her döngü en son istek tarafından tamamlanır ve
tanımlanabilir tek bir iş parçacığının "nedenidir".
Elbette, her kaynak isteği için kilitlenme algılama algoritmasını çağırmak,
hesaplama süresinde önemli bir ek yüke neden olacaktır. Daha ucuz bir alternatif,
algoritmayı tanımlı aralıklarla, örneğin saatte bir kez veya CPU kullanımı yüzde 40'ın
altına düştüğünde çalıştırmaktır.
(Bir kilitlenme sonunda sistem verimini felce uğratır ve CPU kullanımının düşmesine
neden olur.) Algılama algoritması zaman içinde rastgele noktalarda çağrılırsa,
kaynak grafiği birçok döngü içerebilir. Bu durumda, genellikle kilitlenen birçok iş
parçacığından hangisinin kilitlenmeye "neden olduğunu" söyleyemeyiz.
bir kilitlenmeyi kırmak için iki seçenek vardır. Biri, dairesel beklemeyi kırmak için bir veya
daha fazla iş parçacığını iptal etmektir. Diğeri, kilitlenen bir veya daha fazla iş parçacığından
bazı kaynakları önceden almaktır.
Bir işlemi veya iş parçacığını iptal ederek kilitlenmeleri ortadan kaldırmak için iki yöntemden
birini kullanırız. Her iki yöntemde de sistem, sonlandırılan işlemlere tahsis edilen tüm
kaynakları geri alır.
• Kilitlenen tüm süreçleri iptal edin. Bu yöntem açıkça kilitlenme döngüsünü kıracaktır,
ancak büyük bir maliyetle. Kilitli süreçler uzun süre hesaplanmış olabilir ve bu kısmi
hesaplamaların sonuçları atılmalı ve muhtemelen daha sonra yeniden hesaplanması
gerekecektir.
• Kilitlenme döngüsü ortadan kalkana kadar bir seferde bir işlemi iptal edin. Her işlem iptal
edildikten sonra, herhangi bir işlemin hala kilitlenip kilitlenmediğini belirlemek için bir
kilitlenme algılama algoritmasının çağrılması gerektiğinden, bu yöntem önemli
ölçüde ek yüke neden olur.
Bir işlemi iptal etmek kolay olmayabilir. İşlem bir dosyayı güncellemenin ortasındaysa,
sonlandırmak o dosyayı yanlış bir durumda bırakabilir. Benzer şekilde, işlem bir muteks kilidi
tutarken paylaşılan verileri güncellemenin ortasındaysa, paylaşılan verilerin bütünlüğü ile
ilgili hiçbir garanti verilemese de, sistem kilidin durumunu kullanılabilir olarak geri
yüklemelidir.
Kısmi sonlandırma yöntemi kullanılıyorsa, hangi kilitli işlemin (veya işlemlerin)
sonlandırılacağını belirlememiz gerekir. Bu belirleme, CPU zamanlama kararlarına benzer
bir ilke kararıdır. Soru temelde ekonomiktir; sonlandırılması minimum maliyete neden olacak
süreçleri iptal etmeliyiz. Ne yazık ki, minimum maliyet terimi kesin değildir. Aşağıdakiler
de dahil olmak üzere birçok faktör hangi sürecin seçildiğini etkileyebilir:
4. İşlemin tamamlanması için daha kaç kaynağa ihtiyacı var 5. Kaç işlemin
sonlandırılması gerekecek
2. Geri alma. Bir kaynağı bir süreçten önce alırsak, o süreçle ne yapılmalı?
Açıkçası, normal yürütmesine devam edemez; bazı gerekli kaynak eksik.
İşlemi güvenli bir duruma geri almalı ve bu durumdan yeniden başlatmalıyız.
8.9 Özet
• Bir dizi işlemde, kümedeki her işlem yalnızca kümedeki başka bir işlemin neden
olabileceği bir olayı beklediğinde kilitlenme oluşur. • Kilitlenme için dört
gerekli koşul vardır: (1) karşılıklı dışlama, (2) bekle ve bekle, (3) ön alma yok ve (4)
döngüsel bekle. Kilitlenme yalnızca dört koşulun tümü mevcut olduğunda
mümkündür.
• Kilitlenmeler, bir döngünün olduğu kaynak tahsisi grafikleriyle modellenebilir.
kilitlenmeyi gösterir.
Alıştırmalar
8.2 Bir sistemin güvenli olmayan bir durumda olduğunu varsayalım. İş parçacıklarının
bir kilitlenme girmeden yürütmelerini tamamlamalarının mümkün olduğunu gösterin.
durum.
8.4 Kilitlenmeleri önlemenin olası bir yöntemi, başka herhangi bir kaynaktan önce
talep edilmesi gereken tek, daha yüksek dereceli bir kaynağa sahip olmaktır.
Örneğin, birden çok iş parçacığı A ··· E eşitleme nesnelerine erişmeye
çalışırsa, kilitlenme mümkündür. (Bu tür senkronizasyon nesneleri muteksler,
semaforlar, koşul değişkenleri ve benzerlerini içerebilir.) Altıncı bir F nesnesi
ekleyerek kilitlenmeyi önleyebiliriz . Ne zaman bir iş parçacığı herhangi bir
A ··· E nesnesi için senkronizasyon kilidini almak isterse , önce F nesnesi için
kilidi alın . Bu çözüm, kapsama olarak bilinir : A ··· E nesnelerinin kilitleri, F
nesnesinin kilidinin içinde bulunur .
Bu şemayı Bölüm 8.5.4'teki dairesel bekleme şemasıyla karşılaştırın.
8.8 Aşağıdaki kaynak tahsisi politikasını göz önünde bulundurun. Kaynak isteklerine
ve kaynakların serbest bırakılmasına her zaman izin verilir. Kaynaklar müsait
olmadığı için bir kaynak talebi karşılanamıyorsa, kaynakları beklerken bloke
edilmiş herhangi bir iş parçacığını kontrol ederiz. Engellenen bir iş parçacığı
istenen kaynaklara sahipse, bu kaynaklar ondan alınır ve istekte bulunan iş
parçacığına verilir. Engellenen iş parçacığının beklediği kaynakların
vektörü, alınan kaynakları içerecek şekilde artırılır.
a. Kilitlenme meydana gelebilir mi? Cevabınız “evet” ise bir örnek veriniz.
Cevabınız “hayır” ise, hangi gerekli koşulun gerçekleşemeyeceğini belirtin.
Tahsis Maks
ABCD ABCD
T0 3014 5117
T1 2210 3211
T2 3121 3321
T3 0510 4612
T4 4212 6325
a. Mevcut = (0, 3, 0, 1) b.
Mevcut = (1, 0, 0, 2)
Machine Translated by Google
8.10 Bir sistemin güvenli durumda olup olmadığını belirleyen kilitlenme önleme
güvenlik algoritmasını kodladığınızı ve şimdi kilitlenme algılama algoritmasını
uygulamanız istendiğini varsayalım. Bunu, sadece güvenlik algoritması
kodunu kullanarak ve Maxi = Waitingi + Allocationi'yi yeniden tanımlayarak
yapabilir misinizkaynakları
, burada Waitingi
belirten, bir
i'nin hangi iş parçacığı
vektördür içinBölüm
ve Allocationi beklediği
8.6'da
tanımlandığı gibidir?
Cevabını açıkla.
8.11 Yalnızca tek iş parçacıklı bir kilitlenme olması mümkün müdür?
işlem? Cevabını açıkla.
bibliyografya
EX-27
Bölüm 8 Alıştırmalar
8.13 Bölüm 8.2'de Şekil 8.1'de gösterilen program örneğinden kilitlenmeyi gösteren
kaynak tahsisi grafiğini çizin.
8.14 Bölüm 6.8.1'de, P0 ve P1 süreçleri ile S ve Q semaforlarını içeren olası bir kilitlenme
senaryosunu tanımladık . Bu bölümde sunulan senaryo altında kilitlenmeyi
gösteren kaynak tahsis grafiğini çizin.
8.15 Çok iş parçacıklı bir uygulamanın senkronizasyon için yalnızca okuyucu-yazıcı kilitlerini
kullandığını varsayın. Kilitleme için gerekli dört koşulun uygulanması, birden fazla
okuyucu-yazıcı kilidi kullanılması durumunda yine de kilitlenme mümkün müdür?
8.16 Şekil 8.1'de gösterilen program örneği her zaman kilitlenmeye yol açmaz. CPU
zamanlayıcısının oynadığı rolü ve bu programda kilitlenmeye nasıl katkıda
bulunabileceğini açıklayın.
8.17 Bölüm 8.5.4'te tüm kilitlerin belirli bir sırayla alınmasını sağlayarak kilitlenmeyi
önlediğimiz bir durumu tanımlamıştık. Ancak, iki iş parçacığı aynı anda işlem()
işlevini çağırırsa, bu durumda kilitlenmenin mümkün olduğuna da işaret ediyoruz .
Kilitlenmeleri önlemek için transaction() işlevini düzeltin .
•
•
•
•
•
•
Egzersizler EX-28
8.18 Şekil 8.12'de gösterilen altı kaynak tahsisi grafiğinden hangisi, kilitlenme
durumunu gösterir? Kilitlenmeyen durumlar için aşağıdakileri sağlayın:
iş parçacığı ve kaynak döngüsü. Kilitlenme durumunun olmadığı durumlarda,
iş parçacıklarının yürütmeyi tamamlayabileceği sırayı gösterir.
b. Sistem verimi
(a) (b)
T1 T3
R2_
R1
• • R1 R2
_ R3
_
•••
T1 T2 T3
T2 _
(c) (d)
R1 R2
_ T1 T2
•• •• R1 R2
_
•• ••
T1 T2 3_
4_
T3
(e) (f )
T1 T2
T1 T2
R1 R2
_
R1 R2 R3
_
•• •• • •• ••
T3 T4
T3 T4
c. Bir iş parçacığı için Maks'ı artırın (iş parçacığı daha fazlasını istiyor veya istiyor
izin verilenden daha fazla kaynaklar).
d. Bir iş parçacığı için Maks'ı azaltın (iş parçacığı buna gerek olmadığına karar verir
bu kadar kaynak).
e. Konu sayısını artırın.
Tahsis Maks.
ABCD ABCD
T0 2106 6327
T1 3313 5415
T2 2312 6614
T3 1234 4345
T4 3030 7261
8.26 Tek bir kaynak türü için bankacının algoritmasını şuradan elde edebiliriz:
genel bankacının algoritması sadece boyutsallığı azaltarak
çeşitli dizilerin 1.
Tek kaynak tipini uygulayarak çoklu kaynak tipi bankacı şemasını
uygulayamayacağımızı bir örnekle gösterin.
her kaynak türüne ayrı ayrı şema.
8.27 Bir sistemin aşağıdaki anlık görüntüsünü göz önünde bulundurun:
Tahsis Maks.
ABCD ABCD
T0 1202 4316
T1 0112 2424
T2 1240 3651
T3 1201 2623
T4 1001 3112
a. Mevcut = (2, 2, 2, 3)
b. Mevcut = (4, 4, 1, 1)
c. Mevcut = (3, 0, 1, 4)
d. Mevcut = (1, 5, 2, 2)
EX-31
8.29 Kilitlenme algılama algoritmasında yapılan iyimser varsayım nedir? Bu varsayım nasıl
ihlal edilebilir?
8.30 Tek şeritli bir köprü, iki Vermont köyünü North Tun köprüsü ile Güney Tunbridge'i
birbirine bağlar. İki köydeki çiftçiler ürünlerini komşu kasabaya ulaştırmak için
bu köprüyü kullanıyor. Kuzeye giden ve güneye giden bir çiftçi aynı anda köprüye
binerse, köprü çıkmaza girebilir. (Vermont çiftçileri inatçıdır ve yedekleme
yapamazlar.) Semaforlar ve/veya muteks kilitleri kullanarak, kilitlenmeyi önleyen
sözde kodda bir algoritma tasarlayın. Başlangıçta, açlıktan endişe etmeyin (kuzeye
giden çiftçilerin güneye giden çiftçilerin köprüyü kullanmasını engellemesi veya
tam tersi durum).
8.31 Çözümünüzü, açlıktan arınmış olacak şekilde Alıştırma 8.30'a göre değiştirin.
Machine Translated by Google
Programlama Sorunları
8.33 Şekil 8.7'de, dinamik olarak kilitleri alan bir işlem() fonksiyonunu gösteriyoruz.
Metinde, bu fonksiyonun kilitlenmeyi önleyecek şekilde kilitleri elde etmek
için nasıl zorluklar sunduğunu açıklıyoruz. Bu metin için kaynak kodu
indirmesinde sağlanan işlem() Java uygulamasını kullanarak , kilitlerin sırayla
alınması için Sys tem.identityHashCode() yöntemini kullanarak değiştirin.
Programlama Projeleri
Bankacı Algoritması
Bu proje için, Bölüm 8.6.3'te tartışılan bankacı algoritmasını uygulayan bir program
yazacaksınız. Müşteriler bankadan kaynakları talep eder ve serbest bırakır. Bankacı,
yalnızca sistemden güvenli bir durumda çıkarsa bir talepte bulunacaktır. Sistemi
güvenli olmayan bir durumda bırakan bir istek reddedilecektir.
Bu projeyi açıklayan kod örnekleri C'de gösterilmiş olsa da, Java kullanarak da bir
çözüm geliştirebilirsiniz.
Bankacı
Bankacı , Bölüm 8.6.3'te ana hatlarıyla belirtildiği gibi, m kaynak türü için n
müşteriden gelen talepleri değerlendirecektir . Bankacı, aşağıdaki veri yapılarını
kullanarak kaynakları takip edecektir:
Kullanıcının etkileşimli olarak kaynaklar için bir istek girmesine, kaynakları serbest
bırakmasına veya bankacının algoritmasıyla kullanılan farklı veri yapılarının (mevcut,
maksimum, tahsis ve ihtiyaç) değerlerini çıkarmasına izin veren bir program
tasarlayın.
Komut satırında her türden kaynak sayısını ileterek programınızı çağırmalısınız.
Örneğin, birinci türden on, ikinci türden beş, üçüncü türden yedi ve dördüncü türden
sekiz örnekle dört kaynak türü olsaydı, programınızı aşağıdaki gibi çağırırdınız:
./a.out 10 5 7 8
6,4,7,3
4,2,3,2
2,5,3,3
6,3,3,2
5,6,7,5
burada girdi dosyasındaki her satır, her müşteri için her kaynak türünün maksimum
talebini temsil eder. Programınız maksimum diziyi bu değerlere başlatacaktır.
RQ 0 3 1 2 1
Programınız daha sonra, Bölüm 8.6.3.1'de belirtilen güvenlik algoritmasını kullanarak
talebin karşılanıp karşılanmayacağını veya reddedileceğini bildirir.
Machine Translated by Google
Dördüncü Bölüm
Hafıza
Yönetmek
Bir bilgisayar sisteminin temel amacı programları yürütmektir. Bu programlar,
eriştikleri verilerle birlikte yürütme sırasında en azından kısmen ana bellekte
olmalıdır.
Modern bilgisayar sistemleri, sistem yürütme sırasında birkaç işlemi bellekte
tutar. Çeşitli yaklaşımları yansıtan birçok bellek yönetimi şeması mevcuttur ve her
algoritmanın etkinliği duruma göre değişir. Bir sistem için bellek yönetimi
şemasının seçimi, özellikle sistemin donanım tasarımı olmak üzere birçok faktöre
bağlıdır. Çoğu algoritma, bir tür donanım desteği gerektirir.
Machine Translated by Google
Machine Translated by Google
9 BÖLÜM
Ana hafıza
Bölüm 5'te CPU'nun bir dizi işlem tarafından nasıl paylaşılabileceğini gösterdik.
CPU programlamanın bir sonucu olarak , hem CPU kullanımını hem de
bilgisayarın kullanıcılarına yanıt verme hızını iyileştirebiliriz . Ancak
performanstaki bu artışı gerçekleştirmek için birçok işlemi hafızada tutmalıyız,
yani hafızayı paylaşmalıyız.
Bu bölümde, belleği yönetmenin çeşitli yollarını tartışacağız. Bellek
yönetimi algoritmaları, ilkel bir çıplak makine yaklaşımından sayfalama
kullanan bir stratejiye kadar değişir. Her yaklaşımın kendine göre avantajları
ve dezavantajları vardır. Belirli bir sistem için bellek yönetimi yönteminin
seçimi, özellikle sistemin donanım tasarımı gibi birçok faktöre bağlıdır.
Göreceğimiz gibi, çoğu algoritma donanım desteği gerektirir, bu da birçok
sistemin donanım ve işletim sistemi bellek yönetimini yakından entegre
etmesine neden olur.
BÖLÜM HEDEFLERİ
1024000
işletim
sistemi
880000
işlem
işlem
300040
temel
işlem
256000
Şekil 9.1 Bir taban ve bir limit kaydı, mantıksal bir adres alanı tanımlar.
Öncelikle her işlemin ayrı bir bellek alanına sahip olduğundan emin olmamız gerekir.
İşlem başına ayrı bellek alanı, işlemleri birbirinden korur ve aynı anda yürütme için
belleğe yüklenen birden çok işlemin olması için esastır. Bellek alanlarını ayırmak için,
işlemin erişebileceği yasal adres aralığını belirleme ve işlemin yalnızca bu yasal adreslere
erişebilmesini sağlama yeteneğine ihtiyacımız var. Bu korumayı Şekil 9.1'de gösterildiği
gibi genellikle bir taban ve bir sınır olmak üzere iki kayıt kullanarak sağlayabiliriz.
Temel kayıt , en küçük yasal fiziksel bellek adresini tutar; limit kaydı , aralığın boyutunu
belirtir. Örneğin, temel kayıt 300040'a sahipse ve sınır kaydı 120900 ise, program yasal
olarak 300040 ila 420939 (dahil) arasındaki tüm adreslere erişebilir.
352
Bölüm 9 Ana Bellek
çoklu işlem sistemi, bir sonraki işlemin içeriğini ana bellekten kayıtlara yüklemeden
önce, bir işlemin durumunu kayıtlardan ana belleğe depolayarak bağlam
anahtarlarını yürütmelidir.
Çoğu sistem, bir kullanıcı işleminin fiziksel belleğin herhangi bir bölümünde
kalmasına izin verir. Bu nedenle, bilgisayarın adres alanı 00000'den başlasa da,
kullanıcı işleminin ilk adresinin 00000 olması gerekmez. Daha sonra işletim sisteminin
bir işlemi fiziksel belleğe gerçekte nasıl yerleştirdiğini göreceksiniz.
Çoğu durumda, bir kullanıcı programı yürütülmeden önce, bazıları isteğe bağlı
olabilen birkaç adımdan geçer (Şekil 9.3). Bu adımlar sırasında adresler farklı
şekillerde gösterilebilir. Kaynak programdaki adresler genellikle semboliktir
(değişken sayısı gibi). Bir derleyici tipik olarak bu sembolik adresleri yeniden
yerleştirilebilir adreslere bağlar ("bu modülün başlangıcından itibaren 14 bayt" gibi).
Bağlayıcı veya yükleyici (bkz. Bölüm 2.5), yeri değiştirilebilen adresleri mutlak
adreslere (74014 gibi) bağlar. Her bağlama, bir adres alanından diğerine bir
eşlemedir.
Klasik olarak, komutların ve verilerin bellek adreslerine bağlanması,
yol boyunca herhangi bir adımda yapılabilir:
kaynak
program
Derleme
derleyici
zamanı
nesne
dosyası
başka
nesne
dosyaları
bağlayıcı
yük
çalıştırılabilir zaman
dosya
yükleyici
dinamik olarak
bağlantılı
kitaplıklar
uygulamak
bellekteki
zaman
program
(çalışma zamanı)
Bu bölümün büyük bir kısmı, bu çeşitli bağlamaların bir bilgisayar sisteminde nasıl
etkin bir şekilde uygulanabileceğini göstermeye ve uygun donanım desteğini
tartışmaya ayrılmıştır.
CPU tarafından oluşturulan bir adrese genellikle mantıksal adres denir, oysa bellek
birimi tarafından görülen bir adres, yani, bir adrese yüklenen adres.
Machine Translated by Google
fiziksel
mantıksal adres adres
fiziksel
İşlemci MMU
hafıza
belleğin bellek adres kaydı —genel olarak fiziksel adres olarak adlandırılır.
Artık iki farklı adres tipimiz var: mantıksal adresler (0 ila maksimum aralığında)
ve fiziksel adresler ( bir temel değer R için R + 0 ila R + max aralığında ). Kullanıcı
programı yalnızca mantıksal adresler üretir ve işlemin 0'dan maksimuma kadar olan
bellek konumlarında çalıştığını düşünür. Ancak, bu mantıksal adresler kullanılmadan
önce fiziksel adreslerle eşlenmelidir. bu
Machine Translated by Google
Şekil 9.5 Bir yer değiştirme kaydı kullanarak dinamik yer değiştirme.
Ayrı bir fiziksel adres alanına bağlı mantıksal adres alanı kavramı, uygun bellek
yönetiminin merkezinde yer alır.
Ana bellek hem işletim sistemini hem de çeşitli kullanıcı işlemlerini barındırmalıdır. Bu
nedenle, ana belleği mümkün olan en verimli şekilde tahsis etmemiz gerekiyor. Bu
bölüm, erken bir yöntem olan bitişik bellek tahsisini açıklar.
Bellek genellikle iki bölüme ayrılır: biri işletim sistemi ve diğeri kullanıcı işlemleri
için. İşletim sistemini düşük bellek adreslerine veya yüksek bellek adreslerine
yerleştirebiliriz. Bu karar, kesme vektörünün konumu gibi birçok faktöre bağlıdır.
Ancak birçok işletim sistemi (Linux ve Windows dahil) işletim sistemini yüksek belleğe
yerleştirir ve bu nedenle sadece bu durumu tartışıyoruz.
Machine Translated by Google
357
9.2 Bitişik Bellek Tahsisi
CPU zamanlayıcı yürütme için bir süreç seçtiğinde, dağıtım programı içerik
anahtarının bir parçası olarak yer değiştirme ve limit kayıtlarını doğru değerlerle
yükler. Bir CPU tarafından üretilen her adres bu kayıtlara karşı kontrol edildiğinden,
hem işletim sistemini hem de diğer kullanıcıların programlarını ve verilerini bu
çalışan işlem tarafından değiştirilmekten koruyabiliriz.
Yer değiştirme-kayıt şeması, işletim sisteminin boyutunun dinamik olarak
değişmesine izin vermek için etkili bir yol sağlar. Bu esneklik birçok durumda arzu
edilir. Örneğin, işletim sistemi, aygıt sürücüleri için kod ve arabellek alanı içerir. Bir
aygıt sürücüsü şu anda kullanımda değilse, onu bellekte tutmanın pek bir anlamı
yoktur; bunun yerine, yalnızca gerektiğinde belleğe yüklenebilir. Aynı şekilde, aygıt
sürücüsüne artık ihtiyaç duyulmadığında kaldırılabilir ve belleği diğer ihtiyaçlar
için ayrılabilir.
limit yer
kaydı değiştirme kaydı
fiziksel
mantıksal adres evet adres
İşlemci < + hafıza
hayır
358
Bölüm 9 Ana Bellek
9.2.2 Bellek Tahsisi
Artık bellek ayırmaya geçmeye hazırız. Bellek ayırmanın en basit yöntemlerinden
biri, her bölümün tam olarak bir süreç içerebileceği bellekteki değişken
büyüklükteki bölümlere süreçler atamaktır. Bu değişken bölüm şemasında, işletim
sistemi, belleğin hangi bölümlerinin kullanılabilir olduğunu ve hangilerinin işgal
edildiğini gösteren bir tablo tutar. Başlangıçta, tüm bellek kullanıcı işlemleri için
kullanılabilir ve bir büyük kullanılabilir bellek bloğu, bir boşluk olarak kabul edilir.
Sonunda, göreceğiniz gibi, bellek çeşitli boyutlarda bir dizi delik içerir.
Gelen bir sürecin taleplerini karşılamak için yeterli bellek olmadığında ne olur?
Seçeneklerden biri, süreci reddetmek ve uygun bir hata mesajı sağlamaktır.
Alternatif olarak, bu tür işlemleri bir bekleme kuyruğuna yerleştirebiliriz. Bellek
daha sonra serbest bırakıldığında, işletim sistemi bekleyen bir işlemin bellek
taleplerini karşılayıp karşılamayacağını belirlemek için bekleme kuyruğunu kontrol
eder.
Genel olarak, belirtildiği gibi, mevcut bellek blokları, bellek boyunca dağılmış
çeşitli boyutlarda bir dizi delik içerir. Bir işlem geldiğinde ve belleğe ihtiyaç
duyduğunda, sistem bu işlem için yeterince büyük bir delik için kümeyi arar. Delik
çok büyükse, iki parçaya bölünür. Bir kısım gelen işleme tahsis edilir; diğeri delik
kümesine döndürülür. Bir işlem sona erdiğinde, bellek bloğunu serbest bırakır ve
bu blok daha sonra delikler grubuna geri yerleştirilir. Yeni delik diğer deliklere
bitişikse, bu bitişik delikler daha büyük bir delik oluşturmak üzere birleştirilir.
yüksek hafıza
işletim sistemi işletim sistemi işletim sistemi işletim sistemi
düşük
süreç 2 süreç 2 süreç 2 süreç 2
hafıza
• İlk uyum. Yeterince büyük olan ilk deliği tahsis edin. Arama, ya delik setinin
başlangıcında ya da bir önceki ilk-uyum aramasının bittiği yerde başlayabilir. Yeterince
büyük bir serbest delik bulur bulmaz aramayı bırakabiliriz.
• En iyi fi . Yeterince büyük olan en küçük deliği tahsis edin. Liste boyuta göre
sıralanmadıkça, tüm listeyi aramalıyız. Bu strateji, en küçük kalan deliği üretir.
• En kötü uyum. En büyük deliği tahsis edin. Yine, boyuta göre sıralanmadıkça tüm listeyi
aramalıyız. Bu strateji, en uygun yaklaşımdan daha küçük artık delikten daha faydalı
olabilecek en büyük artık deliği üretir.
Simülasyonlar, azalan süre ve depolama kullanımı açısından hem ilk uyum hem de en
iyi uyumun en kötü uyumdan daha iyi olduğunu göstermiştir. Ne ilk uyum ne de en iyi
uyum, depolama kullanımı açısından diğerinden açıkça daha iyi değildir, ancak ilk uyum
genellikle daha hızlıdır.
9.2.3 Parçalanma
Bellek tahsisi için hem ilk uyum hem de en uygun stratejiler, harici parçalanmadan
muzdariptir . İşlemler yüklenip bellekten çıkarıldığında, boş bellek alanı küçük parçalara
bölünür. Bir isteği karşılamak için yeterli toplam bellek alanı olduğunda ancak kullanılabilir
alanlar bitişik olmadığında harici parçalanma vardır: depolama çok sayıda küçük deliğe
bölünür. Bu parçalanma sorunu ciddi olabilir. En kötü durumda, her iki işlem arasında bir
boş (veya boşa harcanmış) bellek bloğumuz olabilir. Bunun yerine tüm bu küçük bellek
parçaları tek bir büyük boş blokta olsaydı, birkaç işlem daha çalıştırabilirdik.
Dış parçalanma sorununa bir çözüm sıkıştırmadır. Amaç, tüm boş belleği
tek bir büyük blokta bir araya getirmek için bellek içeriğini karıştırmaktır.
Ancak sıkıştırma her zaman mümkün değildir. Yer değiştirme statik ise ve
montaj veya yükleme sırasında yapılıyorsa sıkıştırma yapılamaz. Yalnızca yer
değiştirme dinamikse ve yürütme zamanında yapılırsa mümkündür. Adresler
dinamik olarak yeniden yerleştirildiyse, yer değiştirme yalnızca programı ve
verileri taşımayı ve ardından yeni temel adresi yansıtacak şekilde temel kaydı
değiştirmeyi gerektirir. Sıkıştırma mümkün olduğunda, maliyetini belirlememiz
gerekir. En basit sıkıştırma algoritması, tüm süreçleri belleğin bir ucuna
taşımaktır; tüm delikler diğer yönde hareket ederek büyük bir kullanılabilir
bellek deliği oluşturur. Bu şema pahalı olabilir.
Dış parçalanma sorununa bir başka olası çözüm, işlemlerin mantıksal
adres alanının bitişik olmamasına izin vermek, böylece bir işleme, bu tür
belleğin bulunduğu her yerde fiziksel bellek tahsis edilmesine izin vermektir.
Bu, bilgisayar sistemleri için en yaygın bellek yönetimi tekniği olan sayfalamada
kullanılan stratejidir . Aşağıdaki bölümde sayfalamayı açıklıyoruz.
Parçalanma, veri bloklarını yönetmeniz gereken her yerde meydana
gelebilecek bilgi işlemde genel bir sorundur. Konuyu depolama yönetimi
bölümlerinde daha ayrıntılı tartışıyoruz (Bölüm 11 ila Bölüm 15).
9.3 Çağrı
Buraya kadar tartışılan bellek yönetimi, bir işlemin fiziksel adres alanının bitişik
olmasını gerektirmiştir. Şimdi , bir işlemin fiziksel adres alanının bitişik
olmamasına izin veren bir bellek yönetimi şeması olan sayfalamayı tanıtıyoruz.
Sayfalama, bitişik bellek tahsisini rahatsız eden iki sorun olan harici parçalanmayı
ve buna bağlı sıkıştırma ihtiyacını önler. Sayısız avantaj sunduğu için, çeşitli
biçimlerde sayfalama, büyük sunuculardan mobil cihazlara kadar çoğu işletim
sisteminde kullanılır.
Sayfalama, işletim sistemi ve bilgisayar donanımı arasındaki işbirliği ile
gerçekleştirilir.
Sayfa numarası, işlem başına sayfa tablosunda bir dizin olarak kullanılır . Bu,
Şekil 9.8'de gösterilmektedir. Sayfa tablosu, fiziksel bellekteki her çerçevenin
temel adresini içerir ve ofset, başvurulan çerçevedeki konumdur.
Böylece çerçevenin temel adresi, fiziksel bellek adresini tanımlamak için sayfa
ofseti ile birleştirilir. Belleğin sayfalama modeli Şekil 9.9'da gösterilmektedir.
Aşağıda, MMU tarafından mantıksal bir metni çevirmek için atılan adımlar özetlenmektedir.
CPU tarafından fiziksel bir adrese oluşturulan adres:
m-n n
Machine Translated by Google
sayfa 0 0
0 1
Sayfa 1 1 sayfa 0
1 4
2 3
sayfa 2 2
3 7
4 Sayfa 1
mantıksal bellek
5
7 3. sayfa
fiziksel
hafıza
Somut (küçük de olsa) bir örnek olarak, Şekil 9.10'daki hafızayı ele alalım. Burada, mantıksal
adreste, n = 2 ve m = 4. 4 baytlık bir sayfa boyutu ve 32 baytlık bir fiziksel bellek (8 sayfa) kullanarak,
programcının bellek görünümünün fiziksel belleğe nasıl eşleştirilebileceğini gösteriyoruz.
Mantıksal adres 0, sayfa 0, ofset 0'dır. Sayfa tablosuna indeksleme, sayfa 0'ın çerçeve 5'te
olduğunu buluruz. Böylece, mantıksal adres 0, fiziksel adres 20 [= (5 × 4) + 0] ile eşlenir. Mantıksal
adres 3 (sayfa 0, ofset 3), fiziksel adres 23'e [= (5 × 4) + 3] eşlenir. Mantıksal adres 4, sayfa 1, ofset
0'dır; sayfa tablosuna göre, sayfa 1 çerçeve 6'ya eşlenir. Böylece mantıksal adres 4, fiziksel adres
24 [= (6 × 4) + 0] ile eşlenir. Mantıksal adres 13, fiziksel adres 9 ile eşleşir.
Sayfalamanın kendisinin bir dinamik yer değiştirme biçimi olduğunu fark etmiş olabilirsiniz.
Her mantıksal adres, disk belleği donanımı tarafından bazı fiziksel adreslere bağlıdır. Sayfalamayı
kullanmak, her bellek çerçevesi için bir tane olmak üzere, bir taban (veya yer değiştirme) kayıtları
tablosu kullanmaya benzer.
Bir sayfalama şeması kullandığımızda, harici parçalanma olmaz: herhangi bir boş çerçeve,
ihtiyacı olan bir işleme tahsis edilebilir. Ancak, bazı iç parçalanmalarımız olabilir. Çerçevelerin
birimler olarak tahsis edildiğine dikkat edin. Bir işlemin bellek gereksinimleri sayfa sınır dizileriyle
çakışmazsa, ayrılan son çerçeve tamamen dolu olmayabilir. Örneğin, sayfa boyutu 2.048 bayt
ise, 72.766 baytlık bir işlem için 35 sayfa artı 1.086 bayt gerekir.
36 çerçeve tahsis edilecektir, bu da 2.048 - 1.086 = 962 baytlık dahili parçalanma ile sonuçlanacaktır.
En kötü durumda, bir işlem n sayfa artı 1 bayta ihtiyaç duyar.
Neredeyse tüm çerçevenin dahili parçalanmasına neden olacak şekilde n + 1 çerçeve tahsis
edilecektir .
Machine Translated by Google
0 0
1 ab
2
3 CD
4 4
5 ef
0 5
6
7 1 6 ijkl
8 2 1 8 m
9 n
3 2
10
11 ghijkl sayfa tablosu operasyon
12 12
13 milyon
14 Ö
15 p
mantıksal bellek 16
20
ab
c
d
24
ef
gh
28
fiziksel hafıza
Şekil 9.10 4 baytlık sayfaları olan 32 baytlık bir bellek için sayfalama örneği.
getconf PAGESIZE
sayfa tablosu girişlerinde tutulması gereken diğer bilgileri tanıtın. Bu bilgi, sayfa
çerçevelerini adreslemek için kullanılabilen bit sayısını azaltır. Bu nedenle, 32-bit
sayfa tablosu girişleri olan bir sistem, olası maksimumdan daha az fiziksel belleğe
hitap edebilir.
Sisteme yürütülecek bir işlem geldiğinde sayfalarla ifade edilen boyutu incelenir.
Sürecin her sayfası bir çerçeveye ihtiyaç duyar. Bu nedenle, işlem n sayfa
gerektiriyorsa, bellekte en az n çerçeve bulunmalıdır. Eğer n tane çerçeve mevcutsa,
bu gelen sürece tahsis edilirler. İşlemin ilk sayfası tahsis edilen çerçevelerden
birine yüklenir ve bu işlem için sayfa tablosuna çerçeve numarası konur. Sonraki
sayfa başka bir çerçeveye yüklenir, çerçeve numarası sayfa tablosuna konur ve bu
şekilde devam eder (Şekil 9.11).
Sayfalamanın önemli bir yönü, programcının belleğe bakış açısı ile gerçek
fiziksel bellek arasındaki net ayrımdır. Programcı, belleği yalnızca bu programı
içeren tek bir alan olarak görür. Aslında, kullanıcı programı fiziksel belleğe
dağılmıştır ve bu da
14 14 sayfa 0
15 15
sayfa 0 16 sayfa 0 16
sayfa 1 sayfa 1
sayfa 2 17 sayfa 2 17
sayfa 3 sayfa 3
yeni süreç 18 yeni süreç 18 sayfa 2
19 0 14 19
1 13
2
20 18 3
20 20 sayfa 3
(a) (b)
Şekil 9.11 Serbest çerçeveler (a) tahsis öncesi ve (b) tahsis sonrası.
9.3 Çağrı 365
Machine Translated by Google
diğer programlar. Programcının belleğe bakışı ile gerçek fiziksel bellek arasındaki
fark, adres çevirme donanımı tarafından uzlaştırılır. Mantıksal adresler fiziksel
adreslere çevrilir. Bu eşleme pingi programcıdan gizlenir ve işletim sistemi tarafından
kontrol edilir.
Kullanıcı işleminin tanım gereği sahip olmadığı belleğe erişemediğine dikkat edin.
Sayfa tablosunun dışında belleğe hitap etmenin bir yolu yoktur ve tablo yalnızca
işlemin sahip olduğu sayfaları içerir.
İşletim sistemi fiziksel belleği yönettiğinden, fiziksel belleğin tahsis
ayrıntılarının (hangi çerçevelerin ayrıldığı, hangi çerçevelerin mevcut olduğu,
toplam kaç çerçeve olduğu vb.) farkında olması gerekir. Bu bilgiler genellikle
çerçeve tablosu adı verilen sistem çapında tek bir veri yapısında tutulur. Çerçeve
tablosu, her bir fiziksel sayfa çerçevesi için, ikincisinin serbest mi yoksa tahsisli mi
olduğunu ve tahsis edilmişse, hangi işlemin (veya işlemlerin) hangi sayfasına
olduğunu gösteren bir girişe sahiptir.
Ek olarak, işletim sistemi, kullanıcı süreçlerinin kullanıcı alanında çalıştığının
farkında olmalıdır ve tüm mantıksal adreslerin fiziksel adresler üretecek şekilde
eşlenmesi gerekir. Bir kullanıcı bir sistem çağrısı yaparsa ( örneğin G/Ç yapmak
için) ve parametre olarak bir adres sağlarsa (örneğin bir arabellek), doğru fiziksel
adresi üretmek için bu adresin eşlenmesi gerekir. İşletim sistemi, talimat sayacının
ve kayıt içeriğinin bir kopyasını tuttuğu gibi, her işlem için sayfa tablosunun bir
kopyasını tutar. Bu kopya, işletim sisteminin mantıksal bir adresi fiziksel bir adresle
manuel olarak eşleştirmesi gerektiğinde, mantıksal adresleri fiziksel adreslere
çevirmek için kullanılır. Ayrıca, CPU'ya bir işlem tahsis edileceği zaman donanım
sayfa tablosunu tanımlamak için CPU gönderici tarafından kullanılır . Bu nedenle
sayfalama, bağlam değiştirme süresini artırır.
Sayfa tabloları işlem başına veri yapıları olduğundan, sayfa tablosuna bir işaretçi,
her işlemin işlem kontrol bloğunda diğer kayıt değerleriyle (talimat işaretçisi gibi)
saklanır. CPU zamanlayıcı yürütme için bir süreç seçtiğinde, kullanıcı kayıtlarını ve
uygun donanım sayfa tablosu değerlerini saklanan kullanıcı sayfası tablosundan
yeniden yüklemesi gerekir.
Sayfa tablosunun donanım uygulaması birkaç yolla yapılabilir. En basit durumda,
sayfa tablosu, sayfa adresi çevirisini çok verimli kılan, atanmış yüksek hızlı donanım
kayıtları kümesi olarak uygulanır. Bununla birlikte, bu yaklaşım bağlam değiştirme
süresini artırır, çünkü bu kayıtların her birinin bir bağlam değiştirme sırasında
değiştirilmesi gerekir.
Sayfa tablosu oldukça küçükse (örneğin, 256 giriş) sayfa tablosu için kayıtların
kullanımı tatmin edicidir. Bununla birlikte, çoğu çağdaş CPU, çok daha büyük sayfa
tablolarını destekler (örneğin, 220 girdi). Bu makineler için, sayfa tablosunu
uygulamak için hızlı kayıtların kullanılması mümkün değildir. Bunun yerine, sayfa
tablosu ana bellekte tutulur ve bir sayfa tablosu taban kaydı (PTBR) sayfa tablosuna
işaret eder. Sayfa tablolarının değiştirilmesi, yalnızca bu kaydın değiştirilmesini
gerektirir, bu da bağlam değiştirme süresini önemli ölçüde azaltır.
Sayfa tablosunu ana bellekte depolamak daha hızlı bağlam anahtarları sağlasa da,
daha yavaş bellek erişim süreleriyle de sonuçlanabilir. i konumuna erişmek
istediğimizi varsayalım . Önce içindeki değeri kullanarak sayfa tablosuna indekslemeliy
Machine Translated by Google
TLB zaten girişlerle doluysa , değiştirme için mevcut bir giriş seçilmelidir.
Değiştirme ilkeleri, en son kullanılandan (LRU) sıralı denemeye ve rastgeleye kadar
uzanır. Bazı CPU'lar , işletim sisteminin LRU girişinin değiştirilmesine katılmasına
izin verirken, diğerleri konuyu kendileri halleder.
Ayrıca, bazı TLB'ler belirli girişlerin kabloyla bağlanmasına izin verir , yani TLB'den
kaldırılamazlar . Tipik olarak, anahtar çekirdek kodu için TLB girişleri kablolanır.
Bazı TLB'ler , her TLB girişinde adres alanı tanımlayıcısını (ASID'ler) saklar . Bir
ASID , her işlemi benzersiz bir şekilde tanımlar ve bu işlem için adres alanı koruması
sağlamak için kullanılır. TLB sanal sayfa numaralarını çözümlemeye çalıştığında, o
anda çalışan işlemin ASID'sinin sanal sayfayla ilişkili ASID ile eşleşmesini sağlar.
ASID'ler eşleşmezse , deneme TLB kaçırma olarak değerlendirilir. Bir ASID , adres
alanı koruması sağlamanın yanı sıra, TLB'nin aynı anda birkaç farklı işlem için
girişleri içermesine izin verir . TLB ayrı ASID'leri desteklemiyorsa , her yeni sayfa
tablosu seçildiğinde (örneğin, her bağlam anahtarıyla), bir sonraki yürütme
işleminin
9.3 Çağrı 367
Machine Translated by Google
mantıksal adres
İşlemci
pd
sayfa çerçeve
numarası numarası
TLB isabeti
fiziksel
adres
f d
TLB
p
TLB özledim
f
fiziksel
hafıza
sayfa tablosu
yanlış çeviri bilgisi. Aksi takdirde, TLB , geçerli sanal adresleri içeren ancak önceki süreçten kalan
yanlış veya geçersiz fiziksel adresleri olan eski girdileri içerebilir.
İlgilenilen sayfa numarasının TLB'de bulunma yüzdesine isabet oranı denir . Örneğin yüzde
80'lik bir isabet oranı, istenen sayfa numarasını TLB'de zamanın yüzde 80'inde bulduğumuz
anlamına gelir . Belleğe erişmek 10 nanosaniye sürüyorsa, sayfa numarası TLB'deyken eşlenmiş
bellek erişimi 10 nanosaniye sürer . TLB'de sayfa numarasını bulamazsak, önce sayfa tablosu ve
çerçeve numarası (10 nanosaniye) için belleğe erişmeli, ardından toplam 20 nanosaniyelik
bellekte istenen bayta (10 nanosaniye) erişmeliyiz. (Bir sayfa tablosu aramasının yalnızca bir bellek
erişimi aldığını varsayıyoruz, ancak göreceğimiz gibi daha fazlasını gerektirebilir.) Etkin bellek
erişim süresini bulmak için , durumu olasılığına göre ağırlıklandırıyoruz:
Bu örnekte, ortalama bellek erişim süresinde (10 ila 12 nanosaniye) yüzde 20'lik bir yavaşlama
yaşıyoruz. Çok daha gerçekçi olan yüzde 99 isabet oranı için
Bu artan isabet oranı, erişim süresinde yalnızca yüzde 1'lik bir yavaşlama üretir.
Machine Translated by Google
Daha önce belirtildiği gibi, bugün CPU'lar birden fazla TLB düzeyi sağlayabilir.
Modern CPU'larda bellek erişim sürelerinin hesaplanması bu nedenle yukarıdaki
örnekte gösterilenden çok daha karmaşıktır. Örneğin, Intel Core i7 CPU , 128 girişli
L1 talimat TLB'sine ve 64 girişli L1 veri TLB'sine sahiptir. L1'de bir ıskalama durumunda,
L2 512 girişli TLB'deki girişi kontrol etmek CPU'nun altı çevrimini alır . L2'de bir kayıp,
CPU'nun yüzlerce döngü alabilen ilişkili çerçeve adresini bulmak için bellekteki sayfa
tablosu girişlerini gözden geçirmesi veya işi yapması için işletim sistemini kesmesi
gerektiği anlamına gelir.
Böyle bir sistemde sayfalama ek yükünün eksiksiz bir performans analizi, her TLB
katmanı hakkında yanlış oran bilgisi gerektirir. Bununla birlikte, yukarıdaki genel
bilgilerden, donanım özelliklerinin bellek performansı üzerinde önemli bir etkisi
olabileceğini ve işletim sistemi iyileştirmelerinin (sayfalama gibi) donanım
değişiklikleriyle sonuçlanabileceğini ve dolayısıyla donanım değişikliklerinden (ör.
TLB'ler). İsabet oranının TLB üzerindeki etkisini Bölüm 10'da daha ayrıntılı olarak
inceleyeceğiz.
TLB'ler bir donanım özelliğidir ve bu nedenle işletim sistemleri ve tasarımcıları
için çok az endişe verici görünmektedir. Ancak tasarımcının, donanım platformuna
göre değişen TLB'lerin işlevini ve özelliklerini anlaması gerekir . Optimal çalışma
için, belirli bir platform için bir işletim sistemi tasarımı, platformun TLB tasarımına
göre sayfalamayı gerçekleştirmelidir. Benzer şekilde, TLB tasarımındaki bir değişiklik
(örneğin, farklı nesil Intel CPU'lar arasında) , onu kullanan işletim sistemlerinin
sayfalama uygulamasında bir değişiklik gerektirebilir.
9.3.3 Koruma
Disk belleği ortamındaki bellek koruması, her bir çerçeveyle ilişkili koruma bitleri
tarafından gerçekleştirilir. Normalde bu bitler sayfa tablosunda tutulur.
Bir bit, okunacak -yazılacak veya salt okunur olarak bir sayfa tanımlayabilir.
Belleğe yapılan her başvuru, doğru çerçeve numarasını bulmak için sayfa
tablosundan geçer. Fiziksel adres hesaplanırken aynı zamanda, salt okunur bir
sayfaya yazma yapılmadığını doğrulamak için koruma bitleri kontrol edilebilir. Salt
okunur bir sayfaya yazma girişimi, işletim sisteminde bir donanım tuzağına (veya
bellek koruması ihlaline) neden olur.
Daha iyi bir koruma düzeyi sağlamak için bu yaklaşımı kolayca genişletebiliriz.
Salt okunur, okuma-yazma veya salt yürütme koruması sağlamak için donanım
oluşturabiliriz; veya her erişim türü için ayrı koruma bitleri sağlayarak bu erişimlerin
herhangi bir kombinasyonuna izin verebiliriz. Yasadışı girişimler işletim sistemine
hapsolacaktır.
Sayfa tablosundaki her girişe genellikle bir ek bit eklenir: geçerli-geçersiz bir bit.
Bu bit geçerli olarak ayarlandığında , ilişkili sayfa işlemin mantıksal adres alanındadır
ve bu nedenle yasal (veya geçerli) bir sayfadır. Bit geçersiz olarak ayarlandığında ,
sayfa işlemin mantıksal adres alanında olmaz. Geçersiz adresler, geçerli –geçersiz bit
kullanılarak yakalanır. İşletim sistemi, sayfaya erişime izin vermek veya vermemek
için her sayfa için bu biti ayarlar.
Örneğin, 14 bitlik bir adres alanına (0 ila 16383) sahip bir sistemde, yalnızca 0 ila
10468 arasındaki adresleri kullanması gereken bir programımız olduğunu varsayalım.
2 KB'lık bir sayfa boyutu verildiğinde, Şekilde gösterilen duruma sahibiz. 9.13. 0, 1, 2,
3, 4 ve 5. sayfalardaki adresler, sayfa tablosu aracılığıyla normal şekilde eşlenir.
Bununla birlikte, 6. veya 7. sayfalarda bir adres oluşturmaya yönelik herhangi bir girişim,
9.3 Çağrı 369
Machine Translated by Google
2 sayfa 0
çerçeve numarası geçerli-geçersiz bit
12.287
sayfa 5 3 Sayfa 1
10.468
0 2 v
sayfa 4 4 sayfa 2
1 3 v
2 4 v
3. sayfa 5
3 7 v
4 8 v 6
sayfa 2
5 9 v
Sayfa 1 6 0 i 7 3. sayfa
7 0 i
sayfa 0 8 sayfa 4
00000 sayfa tablosu
9 sayfa 5
•
•
•
sayfa n
Şekil 9.13 Bir sayfa tablosunda geçerli (v) veya geçersiz (i) bit.
valid –invalid bit geçersiz olarak ayarlanır ve bilgisayar işletim sistemine tuzak kurar
(geçersiz sayfa referansı).
Bu şemanın bir sorun yarattığına dikkat edin. Program yalnızca 10468 adresine
genişletildiğinden, bu adresin ötesindeki herhangi bir başvuru geçersizdir.
Ancak, sayfa 5'e yapılan referanslar geçerli olarak sınıflandırılır, bu nedenle 12287'ye
kadar olan adreslere erişim geçerlidir. Yalnızca 12288 ile 16383 arasındaki adresler
geçersizdir. Bu sorun, 2 KB'lık sayfa boyutunun bir sonucudur ve sayfalamanın dahili
parçalanmasını yansıtır.
Nadiren bir işlem tüm adres aralığını kullanır. Aslında, birçok işlem, kendilerine
sunulan adres alanının yalnızca küçük bir bölümünü kullanır. Bu durumlarda, adres
aralığındaki her sayfa için girişler içeren bir sayfa tablosu oluşturmak israf olur. Bu
tablonun çoğu kullanılmayacak, ancak değerli bellek alanını kaplayacaktır. Bazı
sistemler , sayfa tablosunun boyutunu belirtmek için bir sayfa tablosu uzunluk kaydı
(PTLR) biçiminde donanım sağlar . Bu değer, adresin işlem için geçerli aralıkta
olduğunu doğrulamak için her mantıksal adrese karşı kontrol edilir. Bu testin başarısız
olması, işletim sisteminde bir hata tuzağına neden olur.
370
Bölüm 9 Ana Bellek
her işlem kendi libc kopyasını adres alanına yükler. Bir sistemde 40 kullanıcı işlemi
varsa ve libc kitaplığı 2 MB ise, bunun için 80 MB bellek gerekir.
Ancak kod yeniden giriş koduysa , Şekil 9.14'te gösterildiği gibi paylaşılabilir.
Burada, standart C kitaplığı libc için sayfaları paylaşan üç süreç görüyoruz . (Şekil,
libc kitaplığının dört sayfa kapladığını gösterse de, gerçekte daha fazla yer kaplar.)
Yeniden giriş kodu, kendi kendini değiştirmeyen koddur: yürütme sırasında asla
değişmez. Böylece iki veya daha fazla işlem aynı kodu aynı anda çalıştırabilir. Her
işlemin, işlemin yürütülmesi için verileri tutmak için kendi kayıt kopyaları ve veri
deposu vardır. İki farklı süreç için veriler elbette farklı olacaktır. Standart C
kitaplığının yalnızca bir kopyasının fiziksel bellekte tutulması gerekir ve her kullanıcı
işlemi için sayfa tablosu libc'nin aynı fiziksel kopyasına eşlenir. Bu nedenle, 40 işlemi
desteklemek için kitaplığın yalnızca bir kopyasına ihtiyacımız var ve şimdi gereken
toplam alan 80 MB yerine 2 MB - önemli bir tasarruf!
libc gibi çalışma zamanı kitaplıklarına ek olarak , yoğun olarak kullanılan diğer
programlar da paylaşılabilir - derleyiciler, pencere sistemleri, veritabanı sistemleri vb.
Bölüm 9.1.5'te tartışılan paylaşılan kitaplıklar tipik olarak paylaşılan sayfalarla
uygulanır. Paylaşılabilir olması için kodun yeniden girişli olması gerekir. Paylaşılan
kodun salt okunur olması, kodun doğruluğuna bırakılmamalıdır; işletim sistemi bu
özelliği zorunlu kılmalıdır.
libc 1
0
3
libc 2
4
1 libc 4
6
libc 3
1
2
libc 4 ...
...
P 1 için sayfa 3 libc 1
libc 1
tablosu
3
libc 2 4 libc 2
süreç P 1
4
6
libc 3
5
1
libc 4 ...
6 libc 3
...
P 2 için sayfa
libc 1 tablosu
3 7
libc 2 süreç P
4 2
6 8
libc 3
1
libc 4 ... 9
...
P 3 için sayfa
tablosu
fiziksel hafıza
süreç P 3
Bir sistemdeki süreçler arasında belleğin paylaşımı, Bölüm 4'te açıklanan bir
görevin adres alanının iş parçacıkları tarafından paylaşılmasına benzer.
Ayrıca, Bölüm 3'te paylaşılan belleği bir süreçler arası iletişim yöntemi olarak
tanımladığımızı hatırlayın. Bazı işletim sistemleri, paylaşılan sayfaları kullanarak
paylaşılan belleği uygular.
Belleği sayfalara göre düzenlemek, birkaç işlemin aynı fiziksel sayfaları paylaşmasına
izin vermenin yanı sıra sayısız fayda sağlar. Bölüm 10'da diğer bazı faydaları ele alıyoruz.
Bu bölümde, hiyerarşik sayfalama, karma sayfa tabloları ve ters çevrilmiş sayfa tabloları
dahil olmak üzere sayfa tablosunu yapılandırmak için en yaygın tekniklerden bazılarını
keşfedeceğiz.
Çoğu modern bilgisayar sistemi, büyük bir mantıksal adres alanını (232 - 264) destekler.
Böyle bir ortamda, sayfa tablosunun kendisi aşırı derecede büyür. Örneğin, 32 bit
mantıksal adres alanına sahip bir sistem düşünün. Böyle bir sistemdeki sayfa boyutu 4
KB (212) ise, o zaman bir sayfa tablosu 1 milyondan fazla girişten oluşabilir (220 =
232/212). Her girişin 4 bayttan oluştuğunu varsayarsak, her işlem yalnızca sayfa tablosu
için 4 MB'a kadar fiziksel adres alanına ihtiyaç duyabilir. Açıkçası, sayfa tablosunu ana
bellekte bitişik olarak tahsis etmek istemeyiz. Bu sorunun basit bir çözümü, sayfa
tablosunu daha küçük parçalara bölmektir. Bu bölme işlemini birkaç şekilde
gerçekleştirebiliriz.
Bir yol, sayfa tablosunun kendisinin de sayfalandığı iki seviyeli bir sayfalama
algoritması kullanmaktır (Şekil 9.15). Örneğin, 32 bit mantıksal adres alanına ve 4 KB
sayfa boyutuna sahip sistemi yeniden ele alalım. Mantıksal bir adres, 20 bitten oluşan
bir sayfa numarasına ve 12 bitten oluşan bir sayfa ofsetine bölünür. Sayfa tablosunu
sayfaladığımız için, sayfa numarası ayrıca 10 bitlik bir sayfa numarasına ve 10 bitlik bir
sayfa uzaklığına bölünmüştür. Böylece, mantıksal bir adres aşağıdaki gibidir:
10 10 12
burada p1 dış sayfa tablosuna bir dizindir ve p2 , iç sayfa tablosunun sayfası içindeki yer
değiştirmedir. Bu mimari için adres-çeviri yöntemi Şekil 9.16'da gösterilmiştir. Adres
çevirisi, dış sayfa tablosundan içe doğru çalıştığından, bu şema, ileriye doğru eşlenmiş
sayfa tablosu olarak da bilinir .
64 bit mantıksal adres alanına sahip bir sistem için iki seviyeli bir sayfalama şeması
artık uygun değildir. Bu noktayı açıklamak için, böyle bir sistemdeki sayfa boyutunun
4 KB (212) olduğunu varsayalım . Bu durumda, sayfa tablosu en fazla 252 girişten
oluşur. İki seviyeli bir sayfalama şeması kullanırsak, iç sayfa tabloları uygun bir şekilde
bir sayfa uzunluğunda olabilir veya 210 adet 4 baytlık giriş içerebilir. Adresler şöyle
görünür:
372
Bölüm
Machine Translated by Google 9 Ana Bellek
0
1
1
• •
• •
• •
100
500
• •
• •
• •
100
500
• •
• •
• • •
•
708 •
•
• 708
•
•
•
dış sayfa 929 •
900
tablosu •
•
•
•
900 •
•
sayfa 929
sayfası tablosu
•
•
•
sayfa tablosu
hafıza
p1 p2 d
42 10 12
Dış sayfa tablosu 242 girişten veya 244 bayttan oluşur. Böyle büyük bir tablodan kaçınmanın
bariz yolu, dış sayfa tablosunu daha küçük parçalara bölmektir.
(Bu yaklaşım, ek esneklik ve verimlilik için bazı 32 bit işlemcilerde de kullanılır.)
Dış sayfa tablosunu çeşitli şekillerde bölebiliriz. Örneğin, bize üç seviyeli bir sayfalama
şeması vererek dış sayfa tablosunu sayfalandırabiliriz. Dış sayfa tablosunun standart boyutlu
sayfalardan (210 giriş veya 212 bayt) oluştuğunu varsayalım.
Bu durumda, 64 bitlik bir adres alanı hala göz korkutucudur:
p1 p2 p3 d
32 10 10 12
mantıksal adres
p1 p2 d
p1
p2
dış sayfa d
tablosu
sayfa
sayfası tablosu
Şekil 9.16 İki seviyeli 32 bitlik bir çağrı mimarisi için adres çevirisi.
her mantıksal adresi çevirmek için. Bu örnekte, 64 bit mimariler için hiyerarşik
sayfa tablolarının neden genellikle uygunsuz olarak değerlendirildiğini görebilirsiniz.
fiziksel
mantıksal adres adres
p d r d
Özet •••
fiziksel
fonksiyonu
qs pr hafıza
karma tablo
374
Bölüm 9 Ana Bellek
64 bitlik adres alanları için yararlı olan bu şemanın bir varyasyonu önerilmiştir.
Bu varyasyon , karma tablodaki her girişin tek bir sayfa yerine birkaç sayfaya (16
gibi) başvurması dışında, karma sayfa tablolarına benzeyen kümelenmiş sayfa
tablolarını kullanır. Bu nedenle, tek bir sayfa tablosu girişi, birden çok fiziksel sayfa
çerçevesi için eşlemeleri depolayabilir. Kümelenmiş sayfa tabloları, bellek
referanslarının bitişik olmadığı ve adres alanı boyunca dağıldığı seyrek adres
alanları için özellikle yararlıdır .
Genellikle, her işlemin ilişkili bir sayfa tablosu vardır. Sayfa tablosu, işlemin kullandığı
her sayfa için bir girişe (veya ikincisinin geçerliliğinden bağımsız olarak her sanal
adres için bir yuvaya) sahiptir. Referans sayfalarını sayfaların sanal adresleri
aracılığıyla işlediğinden, bu tablo gösterimi doğaldır. İşletim sistemi daha sonra
bu referansı fiziksel bir bellek adresine çevirmelidir. Tablo sanal adrese göre
sıralandığından, işletim sistemi ilişkili fiziksel adres girişinin tabloda nerede
olduğunu hesaplayabilir ve bu değeri doğrudan kullanabilir. Bu yöntemin
dezavantajlarından biri, her sayfa tablosunun milyonlarca girdiden oluşabilmesidir.
Bu tablolar, diğer fiziksel belleğin nasıl kullanıldığını takip etmek için büyük
miktarda fiziksel bellek tüketebilir.
Bu sorunu çözmek için ters çevrilmiş bir sayfa tablosu kullanabiliriz. Tersine
çevrilmiş bir sayfa tablosu, belleğin her gerçek sayfası (veya çerçevesi) için bir
girişe sahiptir. Her giriş, sayfanın sahibi olan süreç hakkında bilgilerle birlikte o
gerçek bellek konumunda saklanan sayfanın sanal adresinden oluşur. Böylece
sistemde yalnızca bir sayfa tablosu bulunur ve fiziksel belleğin her sayfası için
yalnızca bir girişi vardır. Şekil 9.18, ters çevrilmiş bir sayfa tablosunun çalışmasını
gösterir. Çalışmakta olan standart bir sayfa tablosunu gösteren Şekil 9.8 ile
karşılaştırın. Tersine çevrilmiş sayfa tabloları, genellikle sayfa tablosunun her
girişinde bir adres alanı tanımlayıcısının (Bölüm 9.3.2) saklanmasını gerektirir, çünkü tablo genellikle birkaç tane iç
arama i
pid p
sayfa tablosu
375
9.4 Sayfa Tablosunun Yapısı
fiziksel belleği eşleyen farklı adres alanları. Adres alanı tanımlayıcısının saklanması,
belirli bir işlem için mantıksal bir sayfanın karşılık gelen fiziksel sayfa çerçevesiyle
eşlenmesini sağlar. Tersine çevrilmiş sayfa tabloları kullanan sistemlere örnek olarak
64-bit UltraSPARC ve PowerPC dahildir.
Bu yöntemi göstermek için, IBM RT'de kullanılan ters çevrilmiş sayfa tablosunun
basitleştirilmiş bir sürümünü açıklıyoruz. IBM , IBM System 38 ile başlayan ve RS/6000 ve
mevcut IBM Power CPU'ları boyunca devam eden , tersine çevrilmiş sayfa tablolarını kullanan
ilk büyük şirketti . IBM RT için , sistemdeki her bir sanal adres, bir üçlüden oluşur:
Her ters çevrilmiş sayfa tablosu girişi, işlem kimliğinin adres alanı tanımlayıcısı rolünü
üstlendiği bir <işlem kimliği, sayfa numarası> çiftidir. Bir bellek referansı oluştuğunda,
sanal adresin <işlem kimliği, sayfa numarası>' ndan oluşan kısmı bellek alt sistemine
sunulur. Ters çevrilmiş sayfa tablosu daha sonra bir eşleşme için aranır. Bir eşleşme
bulunursa (örneğin, i girişinde ) fiziksel adres <i, offset> oluşturulur. Eşleşme
bulunamazsa, yasa dışı bir adres erişimi denenmiştir.
Bu şema, her sayfa tablosunu depolamak için gereken bellek miktarını azaltsa da,
bir sayfa başvurusu oluştuğunda tabloyu aramak için gereken süreyi artırır. Tersine
çevrilmiş sayfa tablosu fiziksel adrese göre sıralandığından, ancak aramalar sanal
adreslerde gerçekleştiğinden, bir eşleşme bulunmadan önce tüm tablonun aranması
gerekebilir. Bu arama çok uzun sürecektir.
Bu sorunu hafifletmek için, aramayı bir veya en fazla birkaç sayfa tablosu girişiyle
sınırlamak için Bölüm 9.4.2'de açıklandığı gibi bir karma tablo kullanıyoruz. Elbette,
karma tablosuna her erişim, prosedüre bir bellek referansı ekler, bu nedenle bir sanal
bellek referansı en az iki gerçek bellek okuması gerektirir - biri karma tablo girişi için
diğeri sayfa tablosu için. ( Karma tabloya danışılmadan önce TLB'nin arandığını ve
bazı performans iyileştirmelerinin yapıldığını hatırlayın.)
Tersine çevrilmiş sayfa tablolarıyla ilgili ilginç bir sorun, paylaşılan bellekle ilgilidir.
Standart sayfalama ile, her işlemin, birden çok sanal adresin aynı fiziksel adrese
eşlenmesine izin veren kendi sayfa tablosu vardır. Bu yöntem, ters çevrilmiş sayfa
tablolarıyla kullanılamaz; her fiziksel sayfa için yalnızca bir sanal sayfa girişi
olduğundan, bir fiziksel sayfada iki (veya daha fazla) paylaşılan sanal adres olamaz. Bu
nedenle, ters çevrilmiş sayfa tablolarında, herhangi bir zamanda sanal bir adresin
paylaşılan fiziksel adrese yalnızca bir eşlemesi gerçekleşebilir. Belleği paylaşan başka
bir işlemin referansı, bir sayfa hatasına neden olacak ve eşlemeyi farklı bir sanal adresle
değiştirecektir.
376
Bölüm 9 Ana Bellek
her sayfa için ayrı bir karma tablo girişi olması. Her girişin bir temel adresi ve girişin
temsil ettiği sayfa sayısını gösteren bir aralığı vardır.
Her adresin bir karma tablosunda arama yapması gerekiyorsa, sanaldan fiziksele
çeviri çok uzun sürer, bu nedenle CPU , hızlı donanım aramaları için çeviri tablosu
girişlerini (TTE'ler) tutan bir TLB uygular. Bu TTE'lerin önbelleği, son erişilen sayfa
başına bir giriş içeren bir çeviri depolama arabelleğinde (TSB) bulunur. Bir sanal
adres referansı oluştuğunda, donanım TLB'de bir çeviri arar. Hiçbiri bulunamazsa,
donanım, aramaya neden olan sanal adrese karşılık gelen TTE'yi arayan bellekteki
TSB'den geçer. Bu TLB yürüme işlevi birçok modern CPU'da bulunur. TSB'de bir
eşleşme bulunursa , CPU TSB girişini TLB'ye kopyalar ve bellek çevirisi tamamlanır.
TSB'de eşleşme bulunamazsa , hash tablosunu aramak için çekirdek kesintiye uğrar.
Çekirdek daha sonra uygun hash tablosundan bir TTE oluşturur ve bunu CPU bellek
yönetim birimi tarafından TLB'ye otomatik olarak yüklenmek üzere TSB'de saklar .
Son olarak, kesme işleyicisi , adres çevirisini tamamlayan ve istenen bayt veya
sözcüğü ana bellekten alan MMU'ya kontrolü geri verir .
9.5 Değiştirme
işletim
sistemi
süreç P1
1 takas etmek
süreç P2
2 takas etmek
kullanıcı
Uzay
Destek deposu
ana hafıza
Şekil 9.19 Bir diski yedekleme deposu olarak kullanan iki işlemin standart takası.
Machine Translated by Google
Standart takas, tüm işlemlerin ana bellek ile bir destek deposu arasında taşınmasını
içerir. Destek deposu genellikle hızlı ikincil depolamadır.
Depolanması ve alınması gereken süreçlerin herhangi bir bölümünü barındıracak
kadar büyük olmalı ve bu bellek görüntülerine doğrudan erişim sağlamalıdır. Bir
işlem veya parça yedek depoya değiştirildiğinde, işlemle ilişkili veri yapılarının
destek deposuna yazılması gerekir.
Çok iş parçacıklı bir süreç için, tüm iş parçacığı başına veri yapılarının da
değiştirilmesi gerekir. İşletim sistemi, değiştirilen işlemler için meta verileri de
korumalıdır, böylece bunlar belleğe geri yerleştirildiklerinde geri yüklenebilirler.
Linux ve Windows da dahil olmak üzere çoğu sistem, artık bir sürecin tamamı
yerine sayfalarının değiştirilebildiği bir takas pingi varyasyonu kullanıyor. Bu strateji
hala fiziksel belleğin gereğinden fazla kullanılmasına izin verir, ancak muhtemelen
yalnızca az sayıda sayfa değiş tokuşa dahil olacağından, tüm işlemlerin
değiştirilmesi maliyetini doğurmaz. Aslında, takas terimi artık genel olarak standart
takası ifade eder ve sayfalama , sayfalama ile değiştirmeyi ifade eder. Bir sayfa çıkışı
işlemi, bir sayfayı bellekten yedekleme deposuna taşır; tersine işlem, sayfa girişi
olarak bilinir . Sayfalama ile değiştirme, Şekil 9.20'de gösterilmektedir, burada A ve
B işlemleri için sayfaların bir alt kümesi sırasıyla sayfalandırılır ve sayfalandırılır.
Bölüm 10'da göreceğimiz gibi, disk belleği ile takas, sanal bellekle birlikte iyi çalışır.
PC'ler ve sunucular için çoğu işletim sistemi sayfa değiştirmeyi destekler. Buna
karşılık, mobil sistemler tipik olarak herhangi bir biçimde takası desteklemez. Mobil
cihazlar, kalıcı depolama için genellikle daha geniş sabit diskler yerine flash bellek
kullanır. Ortaya çıkan alan kısıtlaması, mobil işletim sistemi tasarımcılarının takas
yapmaktan kaçınmasının bir nedenidir. Diğer nedenler arasında, flash belleğin
güvenilmez hale gelmeden önce tolere edebileceği sınırlı sayıda yazma işlemi ve bu
cihazlarda ana bellek ile flash bellek arasındaki düşük verim sayılabilir.
378 Bölüm 9 Ana Bellek
Machine Translated by Google
işlem c
sayfa çıktı 0 1 2 3
A
d
4 b 5 c 6 e 7
e
8 9 10 11
f 12 13 14 15
g 18 19 16 17 j
sayfa
işlem h
B 20 21 22 23
i
j
Destek deposu
ana
hafıza
Boş bellek belirli bir eşiğin altına düştüğünde, takas kullanmak yerine, Apple'ın iOS'u
uygulamalardan gönüllü olarak ayrılmış bellekten vazgeçmelerini ister . Salt okunur veriler
(kod gibi) ana bellekten kaldırılır ve daha sonra
gerekirse flash bellekten yeniden yüklenir. Değiştirilen veriler (örn.
yığın olarak) asla kaldırılmaz. Ancak, serbest bırakılamayan tüm uygulamalar
yeterli bellek, işletim sistemi tarafından sonlandırılabilir.
Android, iOS tarafından kullanılana benzer bir strateji benimser . Bir sonlandırabilir
Yetersiz boş bellek varsa işlem yapın. Ancak, bir işlemi sonlandırmadan önce
Android, uygulama durumunu flash belleğe yazar, böylece
hızlı bir şekilde yeniden başlatıldı.
379
9.6 Örnek: Intel 32- ve 64-bit Mimarileri
fiziksel
doğrusal adres
İşlemci
mantıksal adres segmentasyonu çağrı adres fiziksel
birim birimi hafıza
tanımlayıcı tablo
segment tanımlayıcı +
Mantıksal adres, seçicinin 16 bitlik bir sayı olduğu bir çifttir (seçici, ofset):
s g p
13 1 2
IA-32 mimarisi, 4 KB veya 4 MB sayfa boyutuna izin verir . 4 KB sayfalar için IA -32, 32 bit
doğrusal adresin bölünmesinin aşağıdaki gibi olduğu iki seviyeli bir çağrı şeması kullanır:
10 10 12
Machine Translated by Google
381
9.6 Örnek: Intel 32- ve 64-bit Mimarileri
(doğrusal adres)
31 22 21 12 11 0
sayfa 4-KB
tablosu sayfa
sayfa
dizini
CR3
4 MB
kaydı
sayfa
31 22 21 0
Bu mimari için adres-çeviri şeması, Şekil 9.16'da gösterilen şemaya benzer. IA-32
adres çevirisi , Şekil 9.23'te daha ayrıntılı olarak gösterilmektedir. 10 yüksek
dereceli bit, en dıştaki sayfa tablosundaki, IA-32'nin sayfa dizini olarak adlandırdığı
bir girdiye başvurur. ( CR3 kaydı, geçerli işlem için sayfa dizinini gösterir.) Sayfa
dizini girişi, doğrusal adresteki en içteki 10 bitin içeriği tarafından indekslenen
bir iç sayfa tablosuna işaret eder. Son olarak, 0–11 arasındaki düşük sıralı bitler ,
sayfa tablosunda gösterilen 4 KB'lık sayfadaki ofseti ifade eder.
382
Bölüm 9 Ana Bellek
31 30 29 21 20 12 11 0
4-KB
sayfa
CR3
Kayıt ol sayfa dizini sayfa sayfa
işaretçi tablosu dizin masa
20 ila 24 bit arasında uzanır. PAE desteği ekleyerek 12 bit ofset ile birlikte
IA- 32'ye , adres alanını 64 GB'a kadar destekleyen 36 bite çıkardı
fiziksel bellekten. İşletim sistemi desteğine dikkat etmek önemlidir.
PAE kullanmak için gereklidir . Hem Linux hem de macOS PAE'yi destekler . Ancak 32 bit
Windows masaüstü işletim sistemlerinin sürümleri hala yalnızca
PAE etkinleştirilmiş olsa bile 4 GB fiziksel bellek.
9.6.2 x86-64
Intel'in 64 bit mimariler geliştirme konusunda ilginç bir geçmişi var. İlk girişi IA-64
(daha sonra Itanium olarak adlandırılacak) mimarisiydi, ancak bu mimari geniş çapta
benimsenmedi. Bu arada, başka bir çip üreticisi—AMD
— tabanlı x86-64 olarak bilinen 64 bitlik bir mimari geliştirmeye başladı
mevcut IA-32 komut setinin genişletilmesi hakkında. x86-64 çok destekledi
daha büyük mantıksal ve fiziksel adres alanlarının yanı sıra diğer birçok mimari
gelişme. Tarihsel olarak, AMD genellikle Intel'e dayalı çipler geliştirmişti.
mimarisi, ancak şimdi Intel, AMD'nin x86-64'ünü benimsediği için roller tersine döndü.
mimari. Bu mimariyi tartışırken, ticari
AMD64 ve Intel 64 adları için daha genel bir terim olan x86-64'ü kullanacağız .
64 bit adres alanı desteği, şaşırtıcı bir şekilde 264 baytlık veri sağlar.
adreslenebilir bellek—16 kentilyondan (veya 16 eksabayttan) büyük bir sayı.
Bununla birlikte, 64-bit sistemler potansiyel olarak bu kadar çok belleğe hitap edebilse
de, uygulamada adres gösterimi için 64 bitten çok daha azı kullanılır.
güncel tasarımlar. x86-64 mimarisi şu anda 48 bit sanal
dört düzey kullanarak 4 KB, 2 MB veya 1 GB sayfa boyutlarını destekleyen adres
sayfalama hiyerarşisi. Doğrusal adresin temsili Şekilde görülmektedir.
9.25. Bu adresleme şeması PAE kullanabildiğinden, sanal adresler 48 bittir.
boyutundadır ancak 52 bit fiziksel adresleri (4,096 terabayt) destekler.
63 4748 39 38 30 29 21 20 12 11 0
4-KB ve 16-KB granüller için dört sayfaya kadar sayfalama seviyesi kullanılabilir,
64 KB granüller için üç adede kadar sayfalama düzeyi ile . Şekil 9.26 göstermektedir
4 KB'ye kadar çeviri granülü için ARMv8 adres yapısı dörde kadar
sayfalama seviyeleri. ( ARMv8'in 64 bit bir mimari olmasına rağmen, yalnızca 48
bitler şu anda kullanılmaktadır.) için dört seviyeli hiyerarşik sayfalama yapısı
4-KB çeviri granülü Şekil 9.27'de gösterilmiştir. ( TTBR kaydı,
çeviri tablosu taban kaydı ve mevcut için seviye 0 tablosuna işaret eder
iplik.)
Dört seviyenin tümü kullanılıyorsa, ofset (Şekil 9.26'da 0-11 bitleri)
4 KB'lık bir sayfa içinde ofset . Ancak, seviye 1 için tablo girişlerinin ve
64-BİT BİLGİSAYAR
384
Bölüm 9 Ana Bellek
seviye 0 1. seviye seviye 2 seviye 3
63 4748 39 38 30 29 21 20 12 11 0
düzey 2, başka bir tabloya veya 1 GB'lik bir bölgeye (düzey-1 tablosu) veya 2 MB'lik bir
bölgeye (düzey-2 tablosu) atıfta bulunabilir. Örnek olarak, seviye-1 tablosu seviye-2
tablosundan ziyade 1-GB'lık bir bölgeye atıfta bulunuyorsa, düşük seviyeli 30 bit (Şekil
9.26'da 0-29 bitleri) bu 1-GB'lık bir ofset olarak kullanılır. bölge. Benzer şekilde, seviye-2
tablosu seviye-3 tablosundan ziyade 2-MB'lik bir bölgeye atıfta bulunuyorsa, düşük
seviyeli 21 bit (Şekil 9.26'da 0–20 bitleri) bu 2-MB bölgesindeki ofseti ifade eder.
ARM mimarisi ayrıca iki TLB seviyesini destekler . İç düzeyde iki mikro TLB vardır -
bir TLB veri için ve diğeri talimatlar için. Mikro TLB , ASID'leri de destekler . Dış seviyede
tek bir ana TLB bulunur. Adres çevirisi mikro-TLB düzeyinde başlar. Bir ıskalama
durumunda, ana TLB daha sonra kontrol edilir. Her iki TLB de ıska verirse , donanımda
bir sayfa tablosu yürüyüşü gerçekleştirilmelidir.
9.8 Özet
• Bellek, modern bir bilgisayar sisteminin işleyişinin merkezinde yer alır ve her biri kendi
adresine sahip çok sayıda bayttan oluşur.
• Her işleme bir adres alanı tahsis etmenin bir yolu, taban ve limit kayıtlarının
kullanılmasıdır. Temel kayıt, en küçük yasal fiziksel bellek adresini tutar ve sınır,
aralığın boyutunu belirtir.
3. seviye
masa
2. seviye
masa
1. seviye 4-KB
masa
seviye 0 sayfa
tablosu
TTBR
kaydı
1 GB 2 MB
bölge bölge
• Bellek ayırmaya yönelik bir yaklaşım, farklı boyutlardaki bitişik bellek bölümlerinin
ayrılmasıdır. Bu bölümler üç olası stratejiye göre ayrılabilir: (1) ilk uyum, (2) en
iyi uyum ve (3) en kötü uyum.
• Modern işletim sistemleri, belleği yönetmek için sayfalamayı kullanır. Bu
süreçte fiziksel bellek çerçeve adı verilen sabit boyutlu bloklara ve mantıksal
bellek sayfa adı verilen aynı boyuttaki bloklara bölünür.
• Sayfalama kullanıldığında, mantıksal bir adres iki bölüme ayrılır: bir sayfa numarası
ve bir sayfa ofseti. Sayfa numarası, sayfayı tutan fiziksel bellekteki çerçeveyi
içeren işlem başına sayfa tablosunda bir dizin görevi görür. Ofset, referans
alınan çerçevedeki belirli konumdur. • Bir çeviri önbelleği (TLB) , sayfa
• Çağrı sistemleri için adres çevirisinde TLB kullanılması , mantıksal adresten sayfa
numarasının alınmasını ve sayfa çerçevesinin TLB'de olup olmadığının kontrol
edilmesini içerir . Eğer öyleyse, çerçeve TLB'den elde edilir. Çerçeve TLB'de
mevcut değilse , sayfa tablosundan alınmalıdır. • Hiyerarşik sayfalama, mantıksal
bir adresin, her biri farklı sayfa tabloları seviyelerine atıfta bulunan birden çok
parçaya bölünmesini içerir. Adresler 32 bitin ötesine genişledikçe, hiyerarşik
seviyelerin sayısı artabilir. Bu sorunu ele alan iki strateji, karma sayfa tabloları ve
ters çevrilmiş sayfa tablolarıdır.
• Intel 32 bit mimarisinde iki sayfa tablosu düzeyi bulunur ve 4 KB veya 4 MB sayfa
boyutlarını destekler. Bu mimari ayrıca 32 bit işlemcilerin 4 GB'den büyük bir
fiziksel adres alanına erişmesine izin veren sayfa adresi uzantısını da destekler .
x86-64 ve ARMv9 mimarileri, hiyerarşik sayfalama kullanan 64 bit mimarilerdir.
Alıştırmalar
9.3 Bir programın iki bölüme ayrılabileceği bir sistem düşünün: kod ve veri. CPU ,
bir talimat (talimat getirme) veya veri (veri alma veya saklama) isteyip
istemediğini bilir. Bu nedenle, iki temel limit kayıt çifti sağlanır: biri talimatlar
için ve diğeri veriler için. Talimat
386 Bölüm
Machine Translated by Google 9 Ana Bellek
base –limit register çifti otomatik olarak salt okunurdur, böylece programlar
farklı kullanıcılar arasında paylaşılabilir. Bu planın avantajlarını ve
dezavantajlarını tartışın.
9.4 Her biri 1.024 sözcükten oluşan 64 sayfalık, 32 çerçevelik bir fiziksel belleğe
eşlenmiş mantıksal bir adres alanı düşünün.
a. Mantıksal adreste kaç bit var?
b. Fiziksel adreste kaç bit var?
9.5 Bir sayfa tablosundaki iki girişin bellekte aynı sayfa çerçevesini göstermesine
izin vermenin etkisi nedir? Büyük miktarda belleği bir yerden diğerine
kopyalamak için gereken süreyi azaltmak için bu etkinin nasıl
kullanılabileceğini açıklayın. Bir sayfadaki bazı baytları güncellemenin
diğer sayfada nasıl bir etkisi olur?
9.6 300 KB, 600 KB, 350 KB, 200 KB, 750 KB ve 125 KB'lik (sırasıyla) altı bellek
bölümü verildiğinde , ilk-uyum, en iyi-uyum ve en kötü-uyum algoritmaları
115 boyutlu süreçleri nasıl yerleştirir? KB, 500 KB, 358 KB, 200 KB ve 375
KB (sırayla)?
9.7 1 KB'lık bir sayfa boyutu varsayıldığında , aşağıdaki adres referansları için
sayfa numaraları ve ofsetler nelerdir (ondalık sayılar olarak sağlanır):
a. 3085
b. 42095
c. 215201
d. 650000
e. 2000001
9.8 BTV işletim sistemi 21 bit sanal adrese sahiptir , ancak bazı gömülü cihazlarda
yalnızca 16 bit fiziksel adrese sahiptir. Ayrıca 2 KB sayfa boyutuna sahiptir.
Aşağıdakilerin her birinde kaç giriş var?
a. Geleneksel, tek düzeyli bir sayfa tablosu b.
Tersine çevrilmiş bir sayfa tablosu BTV işletim
sisteminde maksimum fiziksel bellek miktarı nedir ?
9.9 64 karelik bir fiziksel belleğe eşlenmiş, 4 KB sayfa boyutunda 256 sayfalık bir
mantıksal adres alanı düşünün .
a. Mantıksal adreste kaç bit gereklidir?
b. Fiziksel adreste kaç bit gereklidir?
9.10 32 bit mantıksal adrese ve 4 KB sayfa boyutuna sahip bir bilgisayar sistemi
düşünün . Sistem 512 MB'a kadar fiziksel belleği destekler. Aşağıdakilerin
her birinde kaç giriş var?
a. Geleneksel, tek düzeyli bir sayfa tablosu b.
Ters çevrilmiş bir sayfa tablosu
Machine Translated by Google
bibliyografya 387
bibliyografya
[Jacob ve Mudge (2001)] B. Jacob ve T. Mudge, “TLB'ler Olmadan Tek İşlemcili Sanal
Bellek”, Bilgisayarlarda IEEE İşlemleri, Cilt 50, Sayı 5 (2001).
9.12 İkili dosyalar oluşturmak için aşağıdaki süreci göz önünde bulundurun. Bireysel
modüller için nesne kodunu oluşturmak için bir derleyici kullanılır ve birden çok
nesne modülünü tek bir program ikili dosyasında birleştirmek için bir bağlayıcı kullanıl
Bağlayıcı, talimatların ve verilerin bellek adreslerine bağlanmasını nasıl değiştirir?
Bağlayıcının bellek bağlama görevlerini kolaylaştırmak için derleyiciden
bağlayıcıya hangi bilgilerin iletilmesi gerekir?
9.13 100 MB, 170 MB, 40 MB, 205 MB, 300 MB ve 185 MB'lik (sırasıyla) altı bellek bölümü
verildiğinde , ilk-uyum, en iyi-uyum ve en-kötü-uyum algoritmaları 200 boyutlu
süreçleri nasıl yerleştirir? MB, 15 MB, 185 MB, 75 MB, 175 MB ve 80 MB (sırayla)?
Varsa, hangi isteklerin karşılanamayacağını belirtin. Algoritmaların her birinin
belleği ne kadar verimli yönettiği hakkında yorum yapın.
9.14 Çoğu sistem, bir programın yürütme sırasında adres alanına daha fazla bellek
ayırmasına izin verir. Programların yığın bölümlerinde veri tahsisi, bu tür tahsis
edilmiş belleğe bir örnektir. Aşağıdaki şemalarda dinamik bellek ayırmayı
desteklemek için ne gereklidir?
a. Dış parçalanma b. İç
parçalanma c. İşlemler
belleği olan bir sistemde bir işlem, sahip olmadığı belleğe erişemez. Neden? Niye?
İşletim sistemi ek belleğe erişime nasıl izin verebilir? Neden olmalı veya olmamalı?
9.17 iOS ve Android gibi mobil işletim sistemlerinin neden takası desteklemediğini açıklayın.
9.18 Android, önyükleme diskinde değiştirmeyi desteklemese de, ayrı bir SD kalıcı bellek
kartı kullanarak bir takas alanı kurmak mümkündür . Android neden önyükleme
diskinde takasa izin vermiyor, ancak ikincil bir diskte buna izin veriyor?
9.20 Birçok sistemdeki program ikili dosyaları tipik olarak aşağıdaki gibi yapılandırılmıştır.
Kod, 0 gibi küçük, sabit bir sanal adresle başlayarak depolanır. Kod bölümünü,
program değişkenlerini depolamak için kullanılan veri bölümü izler. Program
çalışmaya başladığında, yığın sanal adres alanının diğer ucunda tahsis edilir ve
daha düşük sanal adreslere doğru büyümesine izin verilir. Aşağıdaki şemalar için
bu yapının önemi nedir?
Machine Translated by Google
EX-33
b. 164250
c. 121357
d. 16479315
e. 27253187
9.22 MPV işletim sistemi gömülü sistemler için tasarlanmıştır ve 24 bit sanal adrese,
20 bit fiziksel adrese ve 4 KB sayfa boyutuna sahiptir.
Aşağıdakilerin her birinde kaç giriş var?
9.23 512 çerçevelik bir fiziksel belleğe eşlenmiş, 4 KB sayfa boyutunda 2.048 sayfalık
bir mantıksal adres alanı düşünün .
9.24 32 bit mantıksal adrese ve 8 KB sayfa boyutuna sahip bir bilgisayar sistemi
düşünün . Sistem 1 GB'a kadar fiziksel belleği destekler. Aşağıdakilerin her
birinde kaç giriş var?
a. Mantıksal bir adresi fiziksel bir adrese çevirmek için IA-32 tarafından atılan
tüm adımları açıklayın . b. Bu kadar karmaşık bellek çevirisi sağlayan
donanımın işletim sisteminin avantajları nelerdir?
Egzersizler EX-34
Machine Translated by Google
Programlama Sorunları
9.28 Bir sistemin 4 KB sayfa boyutunda 32 bit sanal adresi olduğunu varsayın.
Komut satırına sanal bir adres (ondalık olarak) geçirilen bir C programı yazın
ve verilen adres için sayfa numarası ve ofset çıktısını almasını sağlayın. Örnek
olarak, programınız aşağıdaki gibi çalışır:
./adresler 19986
Programlama Projeleri
./ayırıcı 1048576
tahsisatçı>
ayırıcı>RL P0
ayırıcı>C
ayırıcı>STAT
. .
Bellek Ayırma
• F—ilk uyum
• B—en uygun
Bu, programınızın mevcut belleği temsil eden farklı delikleri takip etmesini gerektirecektir.
Bir bellek talebi geldiğinde, tahsisat stratejisine göre belleği mevcut deliklerden birinden tahsis
edecektir.
Bir isteğe tahsis etmek için yeterli bellek yoksa, bir hata mesajı verir ve isteği reddeder.
Programınızın ayrıca, hangi işlem için hangi bellek bölgesinin tahsis edildiğini takip etmesi
gerekecektir. Bu, STAT komutunu desteklemek için gereklidir ve ayrıca, belleği serbest bırakma
işlemi bu komuta iletildiğinden, bellek RL komutu aracılığıyla serbest bırakıldığında da gereklidir .
Serbest bırakılan bir bölme mevcut bir deliğe bitişikse, iki deliği tek bir delikte birleştirdiğinizden
emin olun.
Machine Translated by Google
bibliyografya P-50
Sıkıştırma
Kullanıcı C komutunu girerse, programınız delikler grubunu daha büyük bir deliğe
sıkıştıracaktır. Örneğin, 550 KB, 375 KB, 1.900 KB ve 4.500 KB boyutunda dört ayrı
deliğiniz varsa , programınız bu dört deliği 7.325 KB boyutunda tek bir büyük
delikte birleştirecektir.
Sıkıştırmayı uygulamak için, biri Bölüm 9.2.3'te önerilen birkaç strateji vardır.
Sıkıştırmadan etkilenen tüm süreçlerin başlangıç adresini güncellediğinizden emin
olun.
Machine Translated by Google
Machine Translated by Google
10 BÖLÜM
Sanal
Hafıza
BÖLÜM HEDEFLERİ
LRU sayfa değiştirme algoritmalarını uygulayın . • Bir sürecin çalışma grubunu tanımlayın
ve bunun program yeri ile nasıl ilişkili olduğunu açıklayın. • Linux, Windows 10 ve Solaris'in sanal
belleği nasıl yönettiğini açıklayın. • C programlama alanında bir sanal bellek yöneticisi
simülasyonu tasarlayın
ölçü.
10.1 Arkaplan
Talimatların yürütülebilmesi için fiziksel bellekte olması gerekliliği hem gerekli hem de
makul görünmektedir; ama aynı zamanda talihsiz bir durumdur, çünkü bir programın boyutunu
fiziksel belleğin boyutuyla sınırlar. Aslında, gerçek programların incelenmesi bize birçok
durumda programın tamamının gerekli olmadığını gösterir. Örneğin, aşağıdakileri göz
önünde bulundurun:
• Programlar genellikle olağandışı hata durumlarını işlemek için koda sahiptir. Bu hatalar
pratikte nadiren meydana geldiğinden, bu kod neredeyse hiç yürütülmez. • Diziler, listeler
ve tablolar genellikle ihtiyaç duyduklarından daha fazla bellek tahsis edilir. Bir dizi, nadiren
10'a 10 elemandan daha büyük olmasına rağmen 100'e 100 eleman olarak bildirilebilir.
• Bir programın belirli seçenekleri ve özellikleri nadiren kullanılabilir. Örneğin, ABD devlet
bilgisayarlarındaki bütçeyi dengeleyen rutinler uzun yıllardır kullanılmamaktadır.
Tüm programın gerekli olduğu durumlarda bile, hepsine aynı anda ihtiyaç duyulmayabilir.
Yalnızca kısmen bellekte olan bir programı yürütme yeteneği birçok fayda sağlar:
anda daha fazla program çalıştırılabilir, buna karşılık gelen CPU kullanımı ve çıktı artışı
sağlanır, ancak yanıt süresinde veya geri dönüş süresinde artış olmaz.
• Programların bölümlerini yüklemek veya değiştirmek için daha az G/Ç gerekli olacaktır.
bellek, böylece her program daha hızlı çalışacaktı.
Bu nedenle, tamamen bellekte olmayan bir programı çalıştırmak hem sisteme hem de
kullanıcılarına fayda sağlayacaktır.
Sanal bellek , geliştiriciler tarafından algılandığı şekliyle mantıksal belleğin fiziksel bellekten
ayrılmasını içerir. Bu ayrım, yalnızca daha küçük bir fiziksel bellek mevcut olduğunda
programcılar için son derece büyük bir sanal belleğin sağlanmasına olanak tanır (Şekil 10.1).
Sanal bellek, programlama işini çok daha kolaylaştırır, çünkü programcının artık mevcut fiziksel
bellek miktarı hakkında endişelenmesine gerek yoktur; bunun yerine çözülmesi gereken
problemi programlamaya konsantre olabilir.
Bir işlemin sanal adres alanı , bir işlemin bellekte nasıl depolandığının mantıksal (veya
sanal) görünümüne atıfta bulunur. Tipik olarak, bu görüş, bir işlemin belirli bir mantıksal adreste
(örneğin, adres 0) başladığı ve Şekil 10.2'de gösterildiği gibi bitişik bellekte var olduğu
şeklindedir. Bölüm 9'dan, aslında fiziksel belleğin sayfa çerçevelerinde düzenlendiğini ve bir
işleme atanan fiziksel sayfa çerçevelerinin bitişik olmayabileceğini hatırlayın. Hafızaya kalmış-
Machine Translated by Google
sayfa 0
Sayfa 1
sayfa 2
•
•
•
hafıza
haritası
Destek deposu
sayfa v fiziksel
hafıza
sanal
hafıza
Şekil 10.1 Fiziksel bellekten daha büyük sanal belleği gösteren diyagram.
mantıksal sayfaları bellekteki fiziksel sayfa çerçevelerine eşlemek için yönetim birimi
(MMU) .
Şekil 10.2'de, yığının dinamik bellek tahsisi için kullanıldığı için bellekte yukarı
doğru büyümesine izin verdiğimize dikkat edin. Benzer şekilde, ardışık işlev çağrıları
yoluyla yığının bellekte aşağı doğru büyümesine izin veriyoruz. Yığın ve yığın
arasındaki büyük boş alan (veya delik), sanal adres alanının bir parçasıdır, ancak yalnızca
yığın veya yığın büyürse gerçek fiziksel sayfalar gerektirir.
Delikler içeren sanal adres alanları, seyrek adres alanları olarak bilinir.
Seyrek bir adres alanı kullanmak faydalıdır, çünkü yığın veya yığın segmentleri
büyüdükçe veya program yürütme sırasında kitaplıkları (veya muhtemelen diğer
paylaşılan nesneleri) dinamik olarak bağlamak istiyorsak delikler doldurulabilir.
maksimum
yığın
yığın
veri
Metin
392
Bölüm 10 Sanal Bellek
yığın yığın
paylaşılan
paylaşılan kitaplık paylaşılan kitaplık
sayfalar
yığın yığın
veri veri
Metin Metin
• Standart C kitaplığı gibi sistem kitaplıkları, paylaşılan nesnenin sanal bir adres
alanına eşlenmesi yoluyla birkaç işlem tarafından paylaşılabilir. Her proses
kütüphaneleri kendi sanal adres uzayının bir parçası olarak görse de,
kütüphanelerin fiziksel bellekte bulunduğu gerçek sayfalar tüm prosesler
tarafından paylaşılır (Şekil 10.3). Tipik olarak, bir kitaplık, onunla bağlantılı her
işlemin alanına salt okunur olarak eşlenir.
• Benzer şekilde, süreçler hafızayı paylaşabilir. Bölüm 3'ten iki veya daha fazla
işlemin paylaşılan bellek kullanımı yoluyla iletişim kurabileceğini hatırlayın.
Sanal bellek, bir işlemin başka bir işlemle paylaşabileceği bir bellek bölgesi
oluşturmasına izin verir. Bu bölgeyi paylaşan işlemler, onu sanal adres alanlarının
bir parçası olarak kabul eder, ancak Şekil 10.3'te gösterildiği gibi, belleğin
gerçek fiziksel sayfaları paylaşılır.
• Sayfalar, süreç oluşturma sırasında fork() sistem çağrısı ile paylaşılabilir, böylece
süreç oluşturma hızlandırılır.
0 A 2
geçerli-geçersiz
1 B bit 3
çerçeve
2 C 4 A
04 v
3 D 1 i 5
62 v
4 E 6 C AB
3 i
5 F 4 i 7
59 v C D E
6 G 8
6 i
7 H 7 i 9 F FGH
sayfa tablosu
10
mantıksal bellek
11
12
Destek deposu
13
14
15
fiziksel hafıza
394
Bölüm 10 Sanal Bellek
bununla birlikte, bit "geçerli" olarak ayarlandığında, ilişkili sayfa hem yasal hem
de bellektedir. Bit "geçersiz" olarak ayarlanırsa sayfa ya geçerli değildir (yani
işlemin mantıksal adres alanında değildir) ya da geçerlidir ancak şu anda ikincil
depolamadadır. Belleğe getirilen bir sayfanın sayfa tablosu girişi her zamanki
gibi ayarlanır, ancak o anda bellekte olmayan bir sayfanın sayfa tablosu girişi
geçersiz olarak işaretlenir. Bu durum Şekil 10.4'te gösterilmektedir.
(Sürecin o sayfaya asla erişmeye çalışmaması durumunda, bir sayfayı geçersiz olarak işaretlemenin
hiçbir etkisi olmayacağına dikkat edin.)
Ancak süreç belleğe alınmamış bir sayfaya erişmeye çalışırsa ne olur?
Geçersiz olarak işaretlenen bir sayfaya erişim, sayfa hatasına neden olur.
Sayfalama donanımı, adresi sayfa tablosu aracılığıyla çevirirken, geçersiz bitin
ayarlandığını fark edecek ve işletim sistemine bir tuzak kurulmasına neden
olacaktır. Bu tuzak, işletim sisteminin istenen sayfayı belleğe getirememesinin
sonucudur. Bu sayfa hatasını işleme prosedürü basittir (Şekil 10.5):
sayfa destek
3
mağazasında
işletim
sistemi
2
referans
tuzak kurmak
yük M i
5 4 Destek deposu
fiziksel
hafıza
6. Tuzak tarafından kesilen talimatı yeniden başlatıyoruz. İşlem artık sayfaya her zaman
bellekteymiş gibi erişebilir.
Aşırı durumda, bellekte sayfa olmayan bir işlemi yürütmeye başlayabiliriz . İşletim sistemi,
bellekte yerleşik olmayan bir sayfada bulunan işlemin ilk talimatına talimat işaretçisini
ayarladığında, işlem hemen sayfa için hata verir. Bu sayfa belleğe getirildikten sonra, ihtiyaç
duyduğu her sayfa belleğe gelene kadar işlem gerektiği gibi hata vererek yürütülmeye devam
eder. Bu noktada, daha fazla hata olmadan çalışabilir. Bu şema saf talep çağrıdır: gerekli olana
kadar asla bir sayfayı belleğe getirmeyin.
Teorik olarak, bazı programlar, her talimatın yürütülmesiyle birkaç yeni bellek sayfasına
erişebilir (yönerge için bir sayfa ve veriler için çoğu sayfa), bu da muhtemelen talimat başına
birden çok sayfa hatasına neden olabilir. Bu durum, kabul edilemez sistem performansına neden
olur. Neyse ki, çalışan süreçlerin analizi, bu davranışın son derece olası olmadığını gösteriyor.
Programlar , Bölüm 10.6.1'de açıklanan ve talep çağrısından makul bir performansla sonuçlanan
referans yerelliğine sahip olma eğilimindedir .
• Sayfa tablosu. Bu tablo, geçerli bir geçersiz bit veya özel bir koruma biti değeri aracılığıyla
bir girişi geçersiz olarak işaretleme yeteneğine sahiptir.
• İkincil bellek. Bu bellek, ana bellekte bulunmayan sayfaları tutar. İkincil bellek genellikle
yüksek hızlı bir disk veya NVM aygıtıdır. Takas cihazı olarak bilinir ve bu amaçla kullanılan
depolama bölümü takas alanı olarak bilinir. Takas alanı tahsisi Bölüm 11'de tartışılmaktadır.
Talep çağrısı için çok önemli bir gereksinim, bir sayfa hatasından sonra herhangi bir
talimatı yeniden başlatma yeteneğidir. Sayfa hatası oluştuğunda kesilen işlemin durumunu
(kayıtlar, koşul kodu, talimat sayacı) kaydettiğimiz için , istenen sayfanın artık bellekte olması
dışında işlemi tam olarak aynı yer ve durumda yeniden başlatabilmemiz gerekir. ve erişilebilir.
Çoğu durumda, bu gereksinimin karşılanması kolaydır. Herhangi bir bellek referansında bir
sayfa hatası meydana gelebilir. Talimat getirmede sayfa hatası oluşursa, talimatı tekrar getirerek
yeniden başlatabiliriz. Bir işleneni getirirken bir sayfa hatası meydana gelirse, komutu tekrar
getirmeli ve kodunu çözmeli ve ardından işleneni getirmeliyiz.
En kötü durum örneği olarak, sonucu C'ye yerleştirerek A'nın içeriğini B'ye ADD gibi üç
adresli bir talimatı düşünün . Bu talimatı yürütmek için gereken adımlar şunlardır:
2. A'yı getir.
Machine Translated by Google
4. A ve B'yi ekleyin.
C'ye kaydetmeye çalıştığımızda hata yaparsak (çünkü C şu anda bellekte olmayan bir sayfada),
istenen sayfayı almamız, getirmemiz, sayfa tablosunu düzeltmemiz ve talimatı yeniden başlatmamız
gerekecek. Yeniden başlatma, talimatın tekrar getirilmesini, tekrar kodunun çözülmesini, iki işlenenin
tekrar getirilmesini ve ardından tekrar eklenmesini gerektirecektir. Ancak, çok fazla tekrarlanan
çalışma yoktur (bir tam talimattan daha az) ve tekrar sadece bir sayfa hatası olduğunda gereklidir.
meydana gelmek.
En büyük zorluk, bir komutun birkaç farklı konumu değiştirebildiği zaman ortaya çıkar.
Örneğin, bir konumdan diğerine (muhtemelen örtüşen) bir konuma 256 bayta kadar hareket
edebilen IBM System 360/370 MVC (karakter taşıma) talimatını düşünün. Bloklardan biri (kaynak
veya hedef) bir sayfa sınırını aşıyorsa, taşıma kısmen yapıldıktan sonra bir sayfa hatası meydana
gelebilir. Ek olarak, eğer kaynak ve hedef bloklar çakışırsa, kaynak blok değiştirilmiş olabilir, bu
durumda komutu basitçe yeniden başlatamayız.
Bu problem iki farklı şekilde çözülebilir. Bir çözümde, mikro kod hesaplar ve her iki bloğun
her iki ucuna da erişmeye çalışır. Bir sayfa hatası meydana gelecekse, herhangi bir değişiklik
yapılmadan önce bu adımda gerçekleşecektir.
Hareket daha sonra gerçekleşebilir; ilgili tüm sayfalar hafızada olduğundan sayfa hatası
oluşamayacağını biliyoruz. Diğer çözüm, üzerine yazılan konumların değerlerini tutmak için
geçici kayıtlar kullanır. Bir sayfa hatası varsa, tuzak oluşmadan önce tüm eski değerler belleğe
yazılır. Bu eylem, talimatın tekrarlanabilmesi için belleği talimat başlatılmadan önceki durumuna
geri yükler.
Bu, talep çağrılarına izin vermek için mevcut bir mimariye sayfalama eklenmesinden
kaynaklanan tek mimari sorun değildir, ancak ilgili bazı zorlukları göstermektedir. Bir bilgisayar
sisteminde CPU ile bellek arasına sayfalama eklenir . Bir süreç için tamamen şeffaf olmalıdır.
Bir sayfa hatası oluştuğunda, işletim sistemi istenen sayfayı ikincil depolamadan ana belleğe
getirmelidir. Sayfa hatalarını çözmek için çoğu işletim sistemi, bu tür istekleri karşılamak için bir
serbest çerçeve listesi, bir serbest çerçeve havuzu bulundurur (Şekil 10.6). (Serbest çerçeveler, bir
süreçteki yığın veya yığın segmentleri genişlediğinde de tahsis edilmelidir.) İşletim sistemleri
tipik olarak
İsteğe bağlı olarak sıfır doldurma olarak bilinen bir teknik kullanarak ücretsiz çerçeveler
oluşturun . İsteğe bağlı sıfır doldurma çerçeveleri, tahsis edilmeden önce "sıfırlanır", böylece
önceki içerikleri silinir. ( Yeniden atamadan önce bir çerçevenin içeriğini temizlememenin olası
güvenlik sonuçlarını göz önünde bulundurun .)
Bir sistem başlatıldığında, kullanılabilir tüm bellek boş çerçeve listesine yerleştirilir. Serbest
çerçeveler talep edildiğinden (örneğin, talep sayfalama yoluyla), serbest çerçeve listesinin boyutu
küçülür. Bir noktada, liste ya sıfıra düşer ya da belirli bir eşiğin altına düşer, bu noktada yeniden
doldurulması gerekir. Bu durumların her ikisi için de stratejileri Bölüm 10.4'te ele alıyoruz.
p , bir sayfa hatası olasılığı olsun (0 p 1). p'nin sıfıra yakın olmasını beklerdik, yani sadece
birkaç sayfa hatası olmasını beklerdik . Etkin erişim süresi daha sonra
Etkili erişim süresini hesaplamak için, bir sayfa hatasına hizmet vermek için ne kadar zamana
ihtiyaç olduğunu bilmeliyiz. Bir sayfa hatası aşağıdaki sıranın
meydana gelmek:
4. Sayfa referansının yasal olup olmadığını kontrol edin ve sayfanın konumunu belirleyin.
ikincil depolamadaki sayfa.
aktarmaya başlayın.
10. İstenen sayfanın doğru olduğunu göstermek için sayfa tablosunu ve diğer tabloları düzeltin.
şimdi hafızamda.
Bu adımların tümü her durumda gerekli değildir. Örneğin, 6. adımda, G/Ç gerçekleşirken
CPU'nun başka bir işleme tahsis edildiğini varsayıyoruz .
Bu düzenleme, çoklu programlamanın CPU kullanımını sürdürmesine izin verir, ancak G/Ç
aktarımı tamamlandığında sayfa hatası hizmet rutinini sürdürmek için ek süre gerektirir.
Her durumda, sayfa hatası hizmet süresinin üç ana görev bileşeni vardır:
2. Sayfayı okuyun.
Birinci ve üçüncü görevler, dikkatli kodlama ile birkaç yüz talimata indirgenebilir. Bu
görevlerin her biri 1 ila 100 mikrosaniye arasında sürebilir.
Disk belleği cihazı olarak kullanılan HDD'leri ele alalım . Sayfa değiştirme süresi muhtemelen
8 milisaniyeye yakın olacaktır. (Tipik bir sabit diskin ortalama gecikme süresi 3 milisaniye,
arama süresi 5 milisaniye ve aktarım süresi 0,05 milisaniyedir. Bu nedenle, toplam sayfalama
süresi donanım ve yazılım süresi dahil yaklaşık 8 milisaniyedir.) sadece cihaz servis zamanına
bakarak. Cihaz için bir işlem sırası bekliyorsa, sayfalama cihazının isteğimize hizmet etmek
için ücretsiz olmasını beklerken sıraya girme süresini eklememiz gerekir, bu da sayfaya girme
süresini daha da artırır.
O halde etkin erişim süresinin sayfa hata oranıyla doğru orantılı olduğunu görüyoruz .
1000 erişimden biri sayfa hatasına neden oluyorsa, etkin erişim süresi 8,2 mikrosaniyedir.
Bilgisayar, talep çağrısı nedeniyle 40 kat yavaşlayacak! Performans düşüşünün yüzde 10'dan
az olmasını istiyorsak, sayfa hatası olasılığını aşağıdaki düzeyde tutmamız gerekir:
Yani, sayfalamadan kaynaklanan yavaşlamayı makul bir düzeyde tutmak için, 399.990'dan
daha az bir bellek erişimine sayfa hatasına izin verebiliriz. Özetle, bir talep çağrı sisteminde
sayfa hata oranını düşük tutmak önemlidir. Aksi takdirde, etkin erişim süresi artar ve işlemin
yürütülmesini önemli ölçüde yavaşlatır.
Talep sayfalamanın ek bir yönü, takas alanının ele alınması ve genel kullanımıdır. Alanı
değiştirmek için G/Ç genellikle dosya sistemine göre daha hızlıdır. Takas alanı çok daha
büyük bloklarda tahsis edildiğinden ve dosya aramaları ve dolaylı tahsis yöntemleri
kullanılmadığından daha hızlıdır (Bölüm 11). için bir seçenek
Machine Translated by Google
Sistemin daha iyi sayfalama çıktısı elde etmesi için, işlem başlangıcında tüm dosya
görüntüsünü takas alanına kopyalamak ve ardından takas alanından talep sayfalama
gerçekleştirmektir. Bu yaklaşımın bariz dezavantajı, program başlangıcında dosya
görüntüsünün kopyalanmasıdır. İkinci bir seçenek - ve Linux ve Windows dahil
olmak üzere birkaç işletim sistemi tarafından uygulanan - başlangıçta dosya
sisteminden sayfa talep etmek, ancak sayfaları değiştirildikçe takas alanı için
yazmaktır. Bu yaklaşım, dosya sisteminden yalnızca gerekli sayfaların okunmasını,
ancak sonraki tüm sayfalamaların takas alanından yapılmasını sağlayacaktır.
Bazı sistemler, ikili yürütülebilir dosyaların talep sayfalaması yoluyla kullanılan
takas alanı miktarını sınırlamaya çalışır. Bu tür dosyalar için talep sayfaları doğrudan
dosya sisteminden getirilir. Ancak, sayfa değişimi istendiğinde, bu çerçevelerin
üzerine basitçe yazılabilir (çünkü asla değiştirilmezler) ve gerekirse sayfalar dosya
sisteminden tekrar okunabilir.
Bu yaklaşımı kullanarak, dosya sisteminin kendisi destek deposu olarak hizmet eder.
Ancak, bir dosyayla ilişkili olmayan sayfalar için takas alanı yine de kullanılmalıdır
( anonim bellek olarak bilinir); bu sayfalar bir işlem için yığın ve yığın içerir.
Bu yöntem iyi bir uzlaşma gibi görünüyor ve Linux ve BSD UNIX dahil olmak üzere çeşitli
sistemlerde kullanılıyor.
Bölüm 9.5.3'te açıklandığı gibi, mobil işletim sistemleri tipik olarak takası
desteklemez. Bunun yerine, bu sistemler dosya sisteminden sayfa talep eder ve bellek
kısıtlanırsa uygulamalardan salt okunur sayfaları (kod gibi) geri alır. Bu tür veriler,
daha sonra ihtiyaç duyulursa dosya sisteminden talep-sayfalanabilir. iOS altında ,
uygulama sonlandırılmadıkça veya belleği açıkça serbest bırakmadıkça, bir
uygulamadan anonim bellek sayfaları hiçbir zaman geri alınmaz. Bölüm 10.7'de,
mobil sistemlerde takasa yaygın olarak kullanılan bir alternatif olan sıkıştırılmış
belleği ele alıyoruz.
Bölüm 10.2'de, ilk talimatı içeren sayfada talep çağrısı yaparak bir sürecin nasıl hızlı
bir şekilde başlayabileceğini gösterdik. Bununla birlikte, fork() sistem çağrısı
kullanılarak süreç oluşturma, sayfa paylaşımına benzer bir teknik kullanarak (Bölüm
9.3.4'te ele alınmıştır) başlangıçta talep sayfalama ihtiyacını atlayabilir. Bu teknik, hızlı
süreç oluşturmayı sağlar ve yeni oluşturulan sürece ayrılması gereken yeni sayfa
sayısını en aza indirir.
fork() sistem çağrısının, ebeveyninin kopyası olan bir alt süreç oluşturduğunu
hatırlayın . Geleneksel olarak, fork() , ebeveyne ait sayfaları çoğaltarak, çocuk için
ebeveynin adres alanının bir kopyasını oluşturarak çalıştı.
Ancak, birçok alt işlemin oluşturulduktan hemen sonra exec() sistem çağrısını
çağırdığı düşünüldüğünde, ebeveynin adres alanının kopyalanması gereksiz olabilir.
Bunun yerine, üst ve alt süreçlerin başlangıçta aynı sayfaları paylaşmasına izin
vererek çalışan , yazma üzerine kopyalama olarak bilinen bir teknik kullanabiliriz . Bu
paylaşılan sayfalar, yazıldığında kopyalanabilen sayfalar olarak işaretlenir, yani her
iki işlem de paylaşılan bir sayfaya yazarsa, paylaşılan sayfanın bir kopyası oluşturulur.
Yazma üzerine kopyalama, işlem 1'in C sayfasını değiştirmesinden önceki ve sonraki
fiziksel belleğin içeriğini gösteren Şekil 10.7 ve 10.8'de gösterilmektedir.
Örneğin, alt sürecin, sayfaların yazıldığında kopyalanacak şekilde ayarlandığı
yığının bölümlerini içeren bir sayfayı değiştirmeye çalıştığını varsayalım. İşletim
sistemi, serbest çerçeve listesinden bir çerçeve alacak ve bir kopya oluşturacaktır.
400
Bölüm
Machine Translated by Google 10 Sanal Bellek
fiziksel
süreç1 hafıza süreç2
sayfa A
B sayfası
sayfa C
bu sayfanın alt sürecin adres alanıyla eşleştirilmesi. Alt süreç daha sonra
kopyalanan sayfasını değiştirir ve üst sürece ait sayfayı değiştirmez. Açıkçası,
yazma üzerine kopyalama tekniği kullanıldığında, yalnızca her iki işlem
tarafından değiştirilen sayfalar kopyalanır; değiştirilmemiş tüm sayfalar üst ve
alt süreçler tarafından paylaşılabilir. Ayrıca, yalnızca değiştirilebilen sayfaların
yazma üzerine kopya olarak işaretlenmesi gerektiğini unutmayın.
Değiştirilemeyen sayfalar (yürütülebilir kod içeren sayfalar) ebeveyn ve çocuk
tarafından paylaşılabilir. Yazma üzerine kopyalama, Windows, Linux ve macOS
dahil olmak üzere çeşitli işletim sistemleri tarafından kullanılan yaygın bir tekniktir .
UNIX'in çeşitli sürümleri (Linux, macOS ve BSD UNIX dahil) , yazma üzerine
kopyalama ile fork() 'tan farklı şekilde çalışan fork() sistem çağrısının (vfork()
( sanal bellek çatalı için) bir varyasyonunu sağlar. vfork() ile ana süreç askıya
alınır ve alt süreç ebeveynin adres alanını kullanır. vfork () yazma üzerine
kopyalama kullanmadığından, alt süreç ebeveynin adres alanının herhangi bir
sayfasını değiştirirse, değiştirilen sayfalar devam ettirildiğinde üst öğe
tarafından görülebilir. Bu nedenle, alt sürecin ebeveynin adres alanını
değiştirmemesini sağlamak için vfork() dikkatli kullanılmalıdır. vfork() , alt
süreç oluşturulduktan hemen sonra exec()' i çağırdığında kullanılmak üzere
tasarlanmıştır . Sayfaların kopyalanması olmadığı için vfork()
fiziksel
süreç 1 hafıza süreç 2
sayfa A
B sayfası
sayfa C
C sayfasının kopyası
son derece verimli bir süreç oluşturma yöntemidir ve bazen UNIX komut satırı kabuk
arabirimlerini uygulamak için kullanılır.
Sayfa hatası oranıyla ilgili daha önceki tartışmamızda, her sayfaya ilk başvurulduğunda en
fazla bir kez hata verdiğini varsaymıştık. Ancak bu temsil kesin olarak doğru değildir. On
sayfalık bir işlem aslında bunların yalnızca yarısını kullanıyorsa, talep sayfalama , hiç
kullanılmayan beş sayfayı yüklemek için gereken G/Ç'den tasarruf sağlar. İki kat daha fazla
işlem çalıştırarak çoklu programlama derecemizi de artırabiliriz. Böylece, kırk çerçevemiz
olsaydı, her biri on çerçeve gerektiriyorsa (beş tanesi hiç kullanılmamış) çalışabilecek dört
işlem yerine sekiz işlem çalıştırabilirdik.
Çoklu programlama derecemizi arttırırsak, belleği aşırı tahsis etmiş oluruz. Her biri on
sayfa boyutunda olan ancak aslında yalnızca beş sayfa kullanan altı işlem çalıştırırsak,
yedeklenecek on çerçeve ile daha yüksek CPU kullanımı ve verimi elde ederiz. Bununla
birlikte, belirli bir veri kümesi için bu işlemlerin her birinin birdenbire on sayfasının tümünü
kullanmaya çalışması ve yalnızca kırk tane mevcutken altmış çerçeveye ihtiyaç duyulmasına
neden olması mümkündür.
Ayrıca, sistem belleğinin yalnızca program sayfalarını tutmak için kullanılmadığını göz
önünde bulundurun. G/Ç için arabellekler de önemli miktarda bellek tüketir. Bu kullanım,
bellek yerleştirme algoritmaları üzerindeki yükü artırabilir. G/Ç'ye ne kadar bellek ayrılacağına
ve sayfaların ne kadar programlanacağına karar vermek önemli bir zorluktur. Bazı sistemler,
G/Ç arabellekleri için sabit bir bellek yüzdesi ayırırken , diğerleri hem işlemlerin hem de G/Ç
alt sisteminin tüm sistem belleği için rekabet etmesine izin verir. Bölüm 14.6, G/Ç arabellekleri
ve sanal bellek teknikleri arasındaki tümleşik ilişkiyi tartışır .
Aşırı bellek tahsisi kendini şu şekilde gösterir. Bir işlem yürütülürken bir sayfa hatası
oluşur. İşletim sistemi, istenen sayfanın ikincil depolamada nerede bulunduğunu belirler,
ancak daha sonra serbest çerçeve listesinde boş çerçeve olmadığını tespit eder; tüm bellek
kullanımda. Bu durum Şekil 10.9'da gösterilmektedir, burada boş çerçeve olmadığı gerçeği
bir soru işareti ile gösterilmektedir.
Sayfa değiştirme aşağıdaki yaklaşımı benimser. Hiçbir çerçeve boş değilse, şu anda
kullanılmayan bir çerçeve bulur ve onu serbest bırakırız. Bir çerçeveyi yazarak serbest bırakabiliriz.
Machine Translated by Google
402
Bölüm 10 Sanal Bellek
içeriği değiştirmek ve sayfa tablosunu (ve diğer tüm tabloları) sayfanın artık bellekte olmadığını
belirtmek için değiştirmek (Şekil 10.10). Artık işlemin hatalı olduğu sayfayı tutmak için serbest
bırakılan çerçeveyi kullanabiliriz. Sayfa hatası hizmeti rutinini, sayfa değiştirmeyi içerecek şekilde
değiştiririz:
b. Boş çerçeve yoksa, seçmek için bir sayfa değiştirme algoritması kullanın.
bir kurban çerçevesi.
Hiçbir çerçeve boş değilse, iki sayfa aktarımının (biri sayfa çıkışı ve diğeri sayfa girişi için) gerekli
olduğuna dikkat edin. Bu durum, sayfa hatası hizmet süresini etkin bir şekilde ikiye katlar ve buna
bağlı olarak etkin erişim süresini artırır.
Bu ek yükü bir değişiklik biti (veya kirli bit) kullanarak azaltabiliriz. Bu şema kullanıldığında,
her sayfa veya çerçeve, donanımda kendisiyle ilişkilendirilmiş bir değiştirme bitine sahiptir. Bir
sayfanın değiştirme biti, sayfadaki herhangi bir bayt yazıldığında, sayfanın değiştirildiğini
belirten donanım tarafından ayarlanır. Değiştirilecek bir sayfa seçtiğimizde, değiştirme bitini
inceleriz. Bit ayarlanmışsa,
10.4 Sayfa Değiştirme 403
Machine Translated by Google
sayfa çıkışı
kurbanı
geçersiz
2 sayfa
0 ben olarak değiştir
1
f v
4 f kurban
için sayfa
tablosunu sıfırla
sayfa tablosu 3
yeni sayfa
istenen
sayfa
sayfa
Destek deposu
fiziksel
hafıza
G/Ç çok pahalıdır. Talep sayfalama yöntemlerindeki küçük iyileştirmeler bile sistem performansında
büyük kazanımlar sağlar.
Birçok farklı sayfa değiştirme algoritması vardır. Her işletim sisteminin
muhtemelen kendi değiştirme planı vardır. Belirli bir değiştirme algoritmasını nasıl
seçeriz? Genel olarak, sayfa hatası oranı en düşük olanı istiyoruz.
İlk olarak, belirli bir sayfa boyutu için (ve sayfa boyutu genellikle donanım veya
sistem tarafından sabitlenir), adresin tamamı yerine yalnızca sayfa numarasını dikkate
almamız gerekir. İkincisi, eğer bir p sayfasına referansımız varsa, o zaman hemen
takip eden p sayfasına yapılan referanslar asla bir sayfa hatasına neden olmaz. Sayfa
p , ilk referanstan sonra hafızada olacak, bu nedenle hemen takip eden referanslar
arızalanmayacaktır.
Örneğin, belirli bir işlemi izlersek, aşağıdaki adres sırasını kaydedebiliriz:
0100, 0432, 0101, 0612, 0102, 0103, 0104, 0101, 0611, 0102, 0103,
0104, 0101, 0610, 0102, 0103, 0104, 0101, 0609, 0102, 0105
1, 4, 1, 6, 1, 6, 1, 6, 1, 6, 1
Belirli bir referans dizgisi ve sayfa değiştirme algoritması için sayfa hatalarının
sayısını belirlemek için, mevcut sayfa çerçevelerinin sayısını da bilmemiz gerekir.
Açıktır ki, mevcut çerçeve sayısı arttıkça sayfa hatalarının sayısı azalır. Daha önce ele
alınan referans dizisi için, örneğin, üç veya daha fazla çerçevemiz olsaydı, yalnızca
üç hatamız olurdu - her sayfaya ilk referans için bir hata. Buna karşılık, yalnızca bir
çerçeve mevcut olduğunda, her referansta bir yenisini alırdık ve bu da on bir hatayla
sonuçlanırdı. Genel olarak, Şekil 10.11'deki gibi bir eğri bekliyoruz. Çerçeve sayısı
arttıkça, sayfa hatalarının sayısı bir miktar minimum seviyeye düşer. Elbette fiziksel
bellek eklemek çerçeve sayısını artırır.
En basit sayfa değiştirme algoritması, ilk giren ilk çıkar (FIFO) algoritmasıdır. Bir FIFO
değiştirme algoritması, her sayfa ile o sayfanın belleğe getirildiği zamanı ilişkilendirir.
Bir sayfanın değiştirilmesi gerektiğinde, en eski sayfa seçilir. Bir
Machine Translated by Google
16
14
12
10
8
6
4
123 456
çerçeve sayısı
sayfa getirilir. Tüm sayfaları hafızada tutmak için bir FIFO kuyruğu oluşturabiliriz.
Kuyruğun başındaki sayfayı değiştiriyoruz. Bir sayfa belleğe getirildiğinde onu
kuyruğun sonuna ekliyoruz.
Örnek referans dizimiz için, üç çerçevemiz başlangıçta boştur. İlk üç referans
(7, 0, 1) sayfa hatalarına neden olur ve bu boş çerçevelere getirilir. Sonraki referans
(2), sayfa 7'nin yerini alır, çünkü sayfa 7 önce getirilir. 0 sonraki referans ve 0 zaten
hafızada olduğundan, bu referans için bir hatamız yok. 3'e yapılan ilk referans,
şimdi ilk sırada olduğundan, sayfa 0'ın değiştirilmesiyle sonuçlanır. Bu değiştirme
nedeniyle, 0'a bir sonraki referans hata verecektir. Sayfa 1 daha sonra sayfa 0 ile
değiştirilir. Bu işlem Şekil 10.12'de gösterildiği gibi devam eder. Her hata
oluştuğunda, üç karemizde hangi sayfaların olduğunu gösteriyoruz. Toplamda on
beş kusur var.
FIFO sayfa değiştirme algoritmasının anlaşılması ve programlanması kolaydır .
Ancak performansı her zaman iyi değildir. Bir yandan değiştirilen sayfa, uzun
zaman önce kullanılan ve artık ihtiyaç duyulmayan bir başlatma modülü olabilir. Öte
yandan, erken başlatılmış ve sürekli kullanımda olan, yoğun olarak kullanılan bir
değişken içerebilir.
Dikkat edin, aktif kullanımda olan bir sayfayı değiştirmeyi seçsek bile her şey
hala düzgün çalışıyor. Aktif bir sayfayı yenisiyle değiştirdikten sonra
referans dizisi
7012030423 0 3 212 0 1 7 0 1
77 7 2 2 2 4 4 4 0 0 0 7 7 7
0 0 0 3 3 3 2 2 2 1 1 1 0 0
1 1 1 0 0 0 3 3 3 2 2 2 1
sayfa çerçeveleri
16
14
12
10
8
6
4
123 4567
çerçeve sayısı
Şekil 10.13 Bir referans dizisinde FIFO değişimi için sayfa hatası eğrisi.
bir, aktif sayfayı almak için neredeyse anında bir hata meydana gelir. Etkin sayfayı
belleğe geri getirmek için başka bir sayfanın değiştirilmesi gerekir. Bu nedenle, hatalı
bir değiştirme seçeneği sayfa hatası oranını artırır ve işlemin yürütülmesini yavaşlatır.
Bununla birlikte, yanlış yürütmeye neden olmaz.
FIFO sayfa değiştirme ile olası sorunları göstermek için
algoritma, aşağıdaki referans dizesini göz önünde bulundurun:
1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
Şekil 10.13, bu referans dizisi için sayfa hatalarının eğrisini, mevcut çerçevelerin sayısına
karşı gösterir. Dört çerçevenin (on) hata sayısının, üç çerçevenin (dokuz) hata sayısından
daha fazla olduğuna dikkat edin! Bu en beklenmedik sonuç, Belady'nin anomalisi olarak
bilinir : bazı sayfa değiştirme algoritmaları için, ayrılan çerçeve sayısı arttıkça sayfa
hatası oranı artabilir . Bir işleme daha fazla bellek vermenin performansını iyileştirmesini
beklerdik. Bazı erken araştırmalarda, araştırmacılar bu varsayımın her zaman doğru
olmadığını fark ettiler. Sonuç olarak Belady'nin anomalisi keşfedildi.
Belady'nin anomalisinin keşfinin bir sonucu, optimal bir sayfa değiştirme algoritması
arayışıydı - tüm algoritmalar arasında en düşük sayfa hatası oranına sahip olan ve
Belady'nin anomalisinden asla zarar görmeyecek olan algoritma. Böyle bir algoritma
mevcuttur ve OPT veya MIN olarak adlandırılmıştır. Bu basitçe şudur:
referans dizisi
7012030423 0 3 212 0 1 7 0 1
77 7 2 2 2 2 2 7
0 0 0 0 4 0 0 0
1 1 3 3 3 1 1
sayfa çerçeveleri
Ne yazık ki, optimal sayfa değiştirme algoritmasını uygulamak zordur, çünkü referans
dizgisi hakkında gelecekte bilgi sahibi olmayı gerektirir.
(Bölüm 5.3.2'de SJF CPU-zamanlama algoritması ile benzer bir durumla karşılaştık .) Sonuç
olarak, karşılaştırma çalışmaları için en uygun algoritma kullanılmaktadır. Örneğin, yeni
bir algoritma optimal olmasa da, en kötü ihtimalle yüzde 12,3 ve ortalama yüzde 4,7 içinde
olduğunu bilmek faydalı olabilir.
77 7 2 2 4 4 4 0 1 1 1
0 0 0 0 0 0 3 3 3 0 0
1 1 3 3 2 2 2 2 2 7
sayfa çerçeveleri
2. sayfa için, LRU algoritması 3. sayfanın yerini alır, çünkü artık bellekteki üç sayfa
arasında en az kullanılanıdır. Bu sorunlara rağmen, on iki arızalı LRU değiştirme,
on beş arızalı FIFO değiştirmeden çok daha iyidir .
LRU politikası genellikle bir sayfa değiştirme algoritması olarak kullanılır ve iyi
olduğu düşünülür . En büyük sorun, LRU değişiminin nasıl uygulanacağıdır .
Bir LRU sayfa değiştirme algoritması, önemli ölçüde donanım yardımı gerektirebilir.
Sorun, son kullanım zamanına göre tanımlanan çerçeveler için bir sıra belirlemektir.
İki uygulama mümkündür:
• Sayaçlar. En basit durumda, her sayfa tablosu girişiyle bir kullanım süresi alanı
ilişkilendiririz ve CPU'ya bir mantıksal saat veya sayaç ekleriz. Her bellek referansı
için saat artırılır. Bir sayfaya atıfta bulunulduğunda, saat kaydının içeriği o
sayfanın sayfa tablosu girişindeki kullanım süresi alanına kopyalanır. Bu şekilde,
her zaman her sayfaya yapılan son referansın “zamanına” sahibiz. Sayfayı en
küçük zaman değeriyle değiştiriyoruz. Bu şema, LRU sayfasını bulmak için
sayfa tablosunun aranmasını ve her bellek erişimi için belleğe (sayfa
tablosundaki kullanım süresi alanına) bir yazma gerektirir. Sayfa tabloları
değiştirildiğinde ( CPU zamanlaması nedeniyle) zamanlar da korunmalıdır .
Saatin taşması dikkate alınmalıdır.
• Yığın. LRU değiştirmeyi uygulamaya yönelik başka bir yaklaşım, bir sayfa
numarası yığını tutmaktır. Bir sayfaya atıfta bulunulduğunda, yığından çıkarılır
ve en üste konur. Bu şekilde, en son kullanılan sayfa her zaman yığının en
üstünde ve en az kullanılan sayfa her zaman en altta olur (Şekil 10.16). Girişlerin
yığının ortasından kaldırılması gerektiğinden, bu yaklaşımı bir baş işaretçi ve
bir kuyruk işaretçisi ile çift bağlantılı bir liste kullanarak uygulamak en iyisidir.
Bir sayfayı kaldırmak ve yığının en üstüne koymak, en kötü ihtimalle altı
işaretçiyi değiştirmeyi gerektirir. Her güncelleme biraz daha pahalıdır, ancak
değiştirme arayışı yoktur; kuyruk işaretçisi, LRU sayfası olan yığının altını
gösterir . Bu yaklaşım, özellikle LRU değişiminin yazılım veya mikro kod
uygulamaları için uygundur.
referans dizisi
4707101212 2 7 1
2 7
ab
1 2
0 1
7 0
4 4
önce b'den
yığın sonra
a yığın
Şekil 10.16 En son sayfa referanslarını kaydetmek için bir yığın kullanımı.
Pek çok bilgisayar sistemi, gerçek LRU sayfa değişimi için yeterli donanım desteği
sağlamaz . Aslında, bazı sistemler donanım desteği sağlamaz ve diğer sayfa
değiştirme algoritmaları ( FIFO algoritması gibi) kullanılmalıdır.
Bununla birlikte, birçok sistem bir referans biti şeklinde bir miktar yardım sağlar.
Bir sayfanın referans biti, o sayfaya her başvuru yapıldığında donanım tarafından
belirlenir (sayfadaki herhangi bir bayta okuma veya yazma). Referans bitleri, sayfa
tablosundaki her girişle ilişkilendirilir.
Başlangıçta, tüm bitler işletim sistemi tarafından (0'a kadar) temizlenir. Bir işlem
yürütülürken, başvurulan her sayfayla ilişkili bit donanım tarafından (1'e) ayarlanır.
Bir süre sonra, kullanım sırasını bilmesek de referans bitlerini inceleyerek hangi
sayfaların kullanıldığını ve hangilerinin kullanılmadığını belirleyebiliriz . Bu bilgi,
LRU değişimine yaklaşan birçok sayfa değiştirme algoritmasının temelidir .
bitlerini düzenli aralıklarla kaydederek ek sıralama bilgisi elde edebiliriz. Bellekte bir
tablodaki her sayfa için 8 bitlik bir bayt tutabiliriz.
Düzenli aralıklarla (örneğin, her 100 milisaniyede bir), bir zamanlayıcı kesmesi,
kontrolü işletim sistemine aktarır. İşletim sistemi, her sayfanın referans bitini,
diğer bitleri sağa kaydırarak, 8 bitlik baytın yüksek sıralı bitine kaydırır.
Machine Translated by Google
değiştirmenin temel algoritması, bir FIFO değiştirme algoritması ritmidir. Ancak bir sayfa
seçildiğinde, onun referans bitini inceleriz. Değer 0 ise bu sayfayı değiştirmeye geçiyoruz;
ancak referans biti 1'e ayarlanmışsa, sayfaya ikinci bir şans veriyoruz ve bir sonraki FIFO
sayfasını seçmeye geçiyoruz.
Bir sayfaya ikinci bir şans verildiğinde, referans biti temizlenir ve varış zamanı mevcut zamana
sıfırlanır. Bu nedenle, ikinci bir şans verilen bir sayfa, diğer tüm sayfalar değiştirilene (veya
ikinci bir şans verilene) kadar değiştirilmeyecektir. Ek olarak, bir sayfa referans bitini korumak
için yeterince sık kullanılıyorsa, asla değiştirilmeyecektir.
İkinci şans algoritmasını (bazen saat algoritması olarak anılır ) uygulamanın bir yolu
dairesel bir kuyruktur. Bir işaretçi (yani, saatteki bir el), sonraki hangi sayfanın değiştirileceğini
gösterir. Bir çerçeve gerektiğinde, işaretçi 0 referans biti olan bir sayfa bulana kadar ilerler.
İlerledikçe referans bitlerini temizler (Şekil 10.17). Bir kurban sayfası bulunduğunda, sayfa
değiştirilir ve yeni sayfa o konumda dairesel kuyruğa eklenir.
En kötü durumda, tüm bitler ayarlandığında, işaretçinin tüm kuyruk boyunca dönüp her
sayfaya ikinci bir şans verdiğine dikkat edin. Değiştirilecek sonraki sayfayı seçmeden önce
tüm referans bitlerini temizler. Tüm bitler ayarlanmışsa, ikinci şans değiştirme, FIFO
değiştirmeye dönüşür.
algoritmasını, referans biti ve değiştirme bitini (Bölüm 10.4.1'de açıklanmıştır) sıralı bir çift
olarak dikkate alarak geliştirebiliriz. Bu iki bit ile aşağıdaki dört olası sınıfa sahibiz:
sayfa 2. (0, 1) yakın zamanda kullanılmamış ancak değiştirilmiş—o kadar iyi değil çünkü
sayfanın değiştirilmeden önce yazılması gerekecek 3. (1 , 0) yakın zamanda kullanılmış
0 0
0 0
1 0
sonraki kurban
1 0
0 0
1 1
1 1
(a) (b)
Sayfa değiştirme için kullanılabilecek başka birçok algoritma vardır. Örneğin, her
sayfaya yapılan referansların sayısının bir sayacını tutabilir ve aşağıdaki iki şemayı
geliştirebiliriz.
bir süreç ama sonra bir daha asla kullanılmaz. Yoğun olarak kullanıldığı için
sayıca çoktur ve artık ihtiyaç duyulmasa da hafızada kalır.
Bir çözüm, sayıları düzenli aralıklarla 1 bit sağa kaydırarak, katlanarak azalan bir
ortalama kullanım sayısı oluşturmaktır. • En sık kullanılan (MFU) sayfa değiştirme
Başka bir değişiklik, bir boş kare havuzu tutmak, ancak her karede hangi sayfanın
olduğunu hatırlamaktır. Çerçeve ikincil depolamaya yazıldığında çerçeve içeriği
değiştirilmediğinden, çerçeve yeniden kullanılmadan önce gerekirse eski sayfa
doğrudan serbest çerçeve havuzundan yeniden kullanılabilir. Bu durumda G/Ç'ye
gerek yoktur. Bir sayfa hatası oluştuğunda, öncelikle istenen sayfanın serbest çerçeve
havuzunda olup olmadığını kontrol ederiz. Değilse, boş bir çerçeve seçmeli ve onu
okumalıyız.
UNIX sisteminin bazı sürümleri, bu yöntemi ikinci şans algoritması ile birlikte
kullanır. Yanlış kurban sayfasının seçilmesi durumunda maruz kalınan cezayı azaltmak
için herhangi bir sayfa değiştirme algoritmasına faydalı bir ekleme olabilir. Bu ve
diğer değişiklikleri Bölüm 10.5.3'te açıklıyoruz.
Başka bir örnekte, veri ambarları sıklıkla büyük ardışık depolama okumaları,
ardından hesaplamalar ve yazmalar gerçekleştirir. LRU algoritması _
10.5 Çerçevelerin Tahsisi 413
Machine Translated by Google
eski sayfaları silip yenilerini korurken, uygulamanın yeni sayfalardansa eski sayfaları okuması
daha olasıdır (sıralı okumalarını yeniden başlattığı için). Burada, MFU aslında LRU'dan daha
verimli olacaktır .
Bu tür sorunlar nedeniyle, bazı işletim sistemleri, özel programlara, herhangi bir
dosya sistemi veri yapısı olmaksızın, büyük bir ardışık mantıksal blok dizisi olarak
ikincil bir depolama bölümü kullanma yeteneği verir. Bu dizi bazen ham disk olarak
adlandırılır ve bu diziye yönelik G/Ç , ham G/Ç olarak adlandırılır. Ham G/Ç , dosya G/
Ç talep sayfalama, dosya kilitleme, önceden getirme, alan ayırma, dosya adları ve
dizinler gibi tüm dosya sistemi hizmetlerini atlar . Bazı uygulamaların kendi özel
amaçlı depolama hizmetlerini ham bir bölüm üzerinde uygularken daha verimli
olmasına rağmen, çoğu uygulamanın normal dosya sistemi hizmetlerini
kullandıklarında daha iyi performans gösterdiğine dikkat edin.
Tahsis konusuna dönüyoruz. Sabit miktarda boş belleği çeşitli işlemler arasında
nasıl tahsis ederiz? 93 boş çerçevemiz ve iki işlemimiz varsa, her işlem kaç kare alır?
128 çerçeveli basit bir sistem durumu düşünün. İşletim sistemi, kullanıcı işlemi
için 93 çerçeve bırakarak 35 alabilir. Saf talep çağrısı altında, 93 çerçevenin tümü
başlangıçta serbest çerçeve listesine alınır. Bir kullanıcı işlemi yürütmeye
başladığında, bir dizi sayfa hatası üretecektir. İlk 93 sayfa hatalarının tümü, serbest
çerçeve listesinden ücretsiz çerçeveler alacaktır. Serbest çerçeve listesi
tükendiğinde, 94. sayfayla değiştirilecek 93 bellek içi sayfadan birini seçmek için
bir sayfa değiştirme algoritması kullanılır ve bu böyle devam eder. İşlem sona
erdiğinde, 93 kare bir kez daha serbest kare listesine yerleştirilir.
m çerçeveyi n süreç arasında bölmenin en kolay yolu, herkese eşit bir pay, m/n
çerçeve vermektir (şu an için işletim sisteminin ihtiyaç duyduğu çerçeveleri yok
sayarak). Örneğin, 93 çerçeve ve 5 süreç varsa, her süreç 18 çerçeve alacaktır. Kalan
3 çerçeve, serbest çerçeve arabellek havuzu olarak kullanılabilir.
Bu şemaya eşit tahsis denir .
Bir alternatif, çeşitli işlemlerin farklı miktarlarda belleğe ihtiyaç duyacağını
kabul etmektir. 1 KB çerçeve boyutuna sahip bir sistem düşünün . 10 KB'lık küçük bir
öğrenci süreci ve 127 KB'lık etkileşimli bir veritabanı, 62 boş çerçeveli bir sistemde
çalışan iki süreç ise, her sürece 31 çerçeve vermek pek mantıklı değil. Öğrenci
süreci 10'dan fazla çerçeveye ihtiyaç duymaz, bu nedenle diğer 21'i kesinlikle boşa
harcanır.
Bu sorunu çözmek için , her işleme boyutuna göre kullanılabilir belleği
ayırdığımız orantılı tahsisi kullanabiliriz. pi işlemi için sanal belleğin boyutu si olsun
ve tanımla
S= si .
Ardından, mevcut çerçevelerin toplam sayısı m ise, ai'nin yaklaşık olarak pi işlemi
olduğu yere ai çerçevelerini tahsis ederiz ,
ai = si /S × m.
Elbette, her ai'yi , toplamı m'yi aşmayan, talimat kümesinin gerektirdiği minimum
çerçeve sayısından daha büyük bir tam sayı olacak şekilde ayarlamamız gerekir .
Orantılı tahsis ile 62 kareyi, biri 10 sayfadan biri 127 sayfadan biri olmak üzere
iki işlem arasında sırasıyla 4 kare ve 57 kare ayırarak bölerdik.
10.5 Çerçevelerin Tahsisi 415
Machine Translated by Google
10/137 × 62 4 ve
127/137 × 62 57.
Bu şekilde, her iki süreç de mevcut çerçeveleri eşit olarak değil “ihtiyaçlarına” göre
paylaşır.
Hem eşit hem de orantılı tahsiste, elbette tahsis, çoklu programlama seviyesine
göre değişebilir. Çoklu programlama seviyesi artırılırsa, her işlem yeni işlem için
gereken belleği sağlamak için bazı çerçeveleri kaybeder. Tersine, çoklu
programlama seviyesi düşerse, ayrılan sürece tahsis edilen çerçeveler kalan süreçlere
yayılabilir.
Eşit veya orantılı tahsisle, yüksek öncelikli bir sürecin düşük öncelikli bir süreçle
aynı şekilde ele alındığına dikkat edin. Bununla birlikte, tanımı gereği, düşük
öncelikli süreçlerin zararına, yürütmesini hızlandırmak için yüksek öncelikli sürece
daha fazla bellek vermek isteyebiliriz. Bir çözüm, çerçeve oranının, süreçlerin
göreceli boyutlarına değil, daha çok süreçlerin önceliklerine veya bir boyut ve
öncelik kombinasyonuna bağlı olduğu bir orantılı tahsis şeması kullanmaktır.
Çerçevelerin çeşitli süreçlere atanma biçimindeki bir diğer önemli faktör de sayfa
değiştirmedir. Çerçeveler için yarışan birden çok süreçle, sayfa değiştirme
algoritmalarını iki geniş kategoride sınıflandırabiliriz: genel değiştirme ve yerel
değiştirme. Genel değiştirme, bir çerçevenin halihazırda başka bir işleme tahsis
edilmiş olsa bile, tüm çerçeveler kümesinden bir yedek çerçeve seçmesine izin verir;
yani, bir süreç diğerinden bir çerçeve alabilir. Yerel değiştirme, her işlemin yalnızca
kendi tahsis edilmiş çerçeve kümesinden seçim yapmasını gerektirir.
Genel değiştirme algoritmasıyla ilgili bir sorun, bir işlem için bellekteki sayfa
kümesinin yalnızca o işlemin sayfalama davranışına değil, aynı zamanda diğer
işlemlerin sayfalama davranışına da bağlı olmasıdır. Bu nedenle, tamamen dış
koşullar nedeniyle aynı işlem oldukça farklı şekilde çalışabilir (örneğin, bir yürütme
için 0,5 saniye ve bir sonraki yürütme için 4,3 saniye sürme). Yerel değiştirme
algoritmasında durum böyle değildir. Yerel değiştirme altında, bir işlem için
bellekteki sayfalar kümesi, yalnızca o işlemin sayfalama davranışından etkilenir. Yerel
değiştirme, ancak daha az kullanılan bellek sayfalarını kullanıma sunmayarak bir
süreci engelleyebilir.
Bu nedenle, genel değiştirme genellikle daha fazla sistem verimi ile sonuçlanır. Bu
nedenle daha yaygın olarak kullanılan yöntemdir.
Machine Translated by Google
Bölüm 10.2.1'de açıklandığı gibi, bir sayfa açılmadığında bir sayfa hatası oluşur.
bir işlemin adres alanında geçerli bir eşlemeye sahip olmak. İşletim sistemleri
genellikle iki tür sayfa hatası arasında ayrım yapar: büyük ve küçük
hatalar. (Windows, büyük ve küçük hataları sert ve yumuşak hatalar olarak ifade eder,
sırasıyla.) Bir sayfaya atıfta bulunulduğunda büyük bir sayfa hatası oluşur ve
sayfa hafızada değil. Büyük bir sayfa hatasına hizmet vermek, aşağıdakilerin okunmasını gerektirir:
destek mağazasından istenen sayfa ücretsiz bir çerçeveye dönüştürülür ve sayfa güncellenir
masa. Talep sayfalama genellikle başlangıçta yüksek oranda ana sayfa oluşturur
hatalar.
Bir işlemin mantıksal eşlemesi olmadığında küçük sayfa hataları oluşur
bir sayfaya, ancak o sayfa bellekte. İkisinden biri için küçük arızalar meydana gelebilir
sebepler. İlk olarak, bir işlem bellekteki paylaşılan bir kitaplığa başvurabilir, ancak
işlemin sayfa tablosunda bir eşlemesi yoktur. Bu durumda,
içindeki mevcut sayfaya atıfta bulunmak için sadece sayfa tablosunu güncellemek gerekir.
hafıza. Küçük hataların ikinci nedeni, bir sayfa geri alındığında ortaya çıkar.
bir süreçten alınmış ve serbest çerçeve listesine yerleştirilmiş, ancak sayfa henüz
sıfırlandı ve başka bir işleme tahsis edildi. Bu tür bir hata olduğunda
oluşursa, çerçeve serbest çerçeve listesinden kaldırılır ve çerçeveye yeniden atanır.
işlem. Beklenebileceği gibi, küçük bir sayfa hatasını çözmek genellikle
büyük bir sayfa hatasını çözmekten daha az zaman alır.
Bir Linux'ta büyük ve küçük sayfa hatalarının sayısını gözlemleyebilirsiniz.
çıktı veren ps -eo min flt,maj flt,cmd komutunu kullanan sistem
küçük ve büyük sayfa hatalarının sayısı ve ayrıca aşağıdaki komut
süreci başlattı. Bu ps komutunun örnek bir çıktısı aşağıda görünür:
Ardından, bir stratejiyi uygulamak için kullanabileceğimiz olası bir stratejiye odaklanıyoruz.
genel sayfa değiştirme politikası. Bu yaklaşımla, tüm hafızayı tatmin ediyoruz.
serbest çerçeve listesinden istekler, ancak listenin düşmesini beklemek yerine
değiştirilecek sayfaları seçmeye başlamadan önce sıfır, liste belirli bir eşiğin altına düştüğünde
sayfa değiştirmeyi tetikleriz. Bu strateji,
yeni istekleri karşılamak için her zaman yeterli boş bellek olduğundan emin olun.
Böyle bir strateji Şekil 10.18'de gösterilmektedir. Stratejinin amacı,
boş bellek miktarını minimum eşiğin üzerinde tutun. düştüğünde
Machine Translated by Google
b d maksimum
eşik
asgari
eşik
a c
zaman
çekirdek özgeçmişleri
sayfaları
geri almak
bu eşiğin altında, sayfaları geri almaya başlayan bir çekirdek rutini tetiklenir
sistemdeki tüm işlemlerden (genellikle çekirdek hariç). Böyle bir çekirdek
rutinler genellikle biçerdöverler olarak bilinir ve Bölüm 10.4'te ele alınan sayfa
değiştirme algoritmalarından herhangi birini uygulayabilirler. ücretsiz miktar ne zaman
bellek maksimum eşiğe ulaşır, orak makinesi rutini askıya alınır, yalnızca
boş hafıza tekrar minimum eşiğin altına düştüğünde devam etmek için.
Şekil 10.18'de, a noktasında boş hafıza miktarının düştüğünü görüyoruz.
minimum eşiğin altında ve çekirdek sayfaları geri almaya başlar ve
onları serbest çerçeve listesine ekleyerek. Maksimum eşik olana kadar devam eder.
ulaşıldı (b noktası). Zamanla, bellek için ek istekler vardır ve
c noktası, boş bellek miktarı tekrar minimum eşiğin altına düşer.
Sayfa geri alma işlemi devam eder, yalnızca ücretsiz
bellek maksimum eşiğe ulaşır (d noktası). Bu süreç şu şekilde devam ediyor
sistem çalıştığı sürece.
Yukarıda bahsedildiği gibi, çekirdek reaper rutini herhangi bir sayfa değiştirme
algoritmasını benimseyebilir, ancak tipik olarak bir tür LRU yaklaşımı kullanır.
Yine de, orak makinesi rutini sürdürülemezse ne olabileceğini bir düşünün.
minimum eşiğin altındaki boş çerçevelerin listesi. Bu şartlar altında
Machine Translated by Google
418
Bölüm 10 Sanal Bellek
duruşlar, orak makinesi rutini sayfaları daha agresif bir şekilde geri almaya
başlayabilir. Örneğin, belki ikinci şans algoritmasını askıya alacak ve saf FIFO
kullanacak. Bir başka, daha uç örnek, Linux'ta görülür; boş bellek miktarı çok düşük
seviyelere düştüğünde, yetersiz bellek (OOM) öldürücü olarak bilinen bir rutin,
sonlandırmak için bir işlem seçer ve böylece belleği boşaltır. Linux hangi işlemin
sonlandırılacağını nasıl belirler? Her işlem, OOM skoru olarak bilinen şeye sahiptir
ve daha yüksek bir skor, işlemin OOM katil rutini tarafından sonlandırılma olasılığını
artırır . OOM puanları, bir işlemin kullandığı bellek yüzdesine göre hesaplanır;
yüzde ne kadar yüksek olursa, OOM puanı da o kadar yüksek olur. (OOM puanları /
proc dosya sisteminde görüntülenebilir; burada pid 2500'e sahip bir işlemin puanı /
proc/2500/oom puanı olarak görüntülenebilir.)
Genel olarak, orakçı rutinleri hafızayı ne kadar agresif bir şekilde geri
kazandıklarını değiştirmekle kalmaz, aynı zamanda minimum ve maksimum
eşiklerin değerleri de değiştirilebilir. Bu değerler varsayılan değerlere
ayarlanabilir, ancak bazı sistemler sistem yöneticisinin sistemdeki fiziksel bellek
miktarına göre bunları yapılandırmasına izin verebilir.
sanal bellek kapsamımızda, tüm ana belleğin eşit yaratıldığını veya en azından eşit
olarak erişildiğini varsaydık. Birden çok CPU'ya sahip tek tip olmayan bellek erişimi
(NUMA) sistemlerinde (Bölüm 1.3.2 ), durum böyle değildir. Bu sistemlerde, belirli
bir CPU , ana belleğin bazı bölümlerine diğerlerine erişebildiğinden daha hızlı
erişebilir. Bu performans farklılıkları , sistemde CPU'ların ve belleğin birbirine nasıl
bağlı olduğundan kaynaklanır. Böyle bir sistem , her biri kendi yerel belleğine
sahip birden fazla CPU'dan oluşur (Şekil 10.19). CPU'lar , paylaşılan bir sistem ara
bağlantısı kullanılarak düzenlenir ve beklediğiniz gibi, bir CPU yerel belleğine
başka bir CPU'nun yerel belleğinden daha hızlı erişebilir . NUMA sistemleri istisnasız
olarak ana belleğe tüm erişimlerin eşit muamele gördüğü sistemlerden daha
yavaştır. Ancak, Bölüm 1.3.2'de açıklandığı gibi, NUMA sistemleri daha fazla CPU'yu
barındırabilir ve bu nedenle daha yüksek verim ve paralellik seviyelerine ulaşabilir.
hafıza0 hafıza1
ara bağlantı
CPU0 CPU1
CPU2 CPU3
hafıza2 hafıza3
10.6 Çarpma
Bir işlemin "yeterli" çerçeveleri yoksa, yani çalışma kümesindeki sayfaları desteklemek
için ihtiyaç duyduğu minimum çerçeve sayısına sahip değilse ne olacağını düşünün.
İşlem hızlı bir şekilde sayfa hatası olacaktır. Bu noktada, bazı sayfaları değiştirmelidir.
Ancak tüm sayfaları aktif kullanımda olduğu için bir an önce yeniden ihtiyaç duyulacak
bir sayfanın yerini alması gerekir. Sonuç olarak, hemen geri getirmesi gereken sayfaları
değiştirerek hızla tekrar ve tekrar hata verir.
Bu yüksek çağrı etkinliğine thrashing denir . Bir süreç, sayfalama yapmak için
yürütmekten daha fazla zaman harcıyorsa çöküyor. Tahmin edebileceğiniz gibi,
thrashing ciddi performans sorunlarına neden olur.
420
Bölüm 10 Sanal Bellek
çok düşükse, sisteme yeni bir süreç ekleyerek çoklu programlamanın derecesini
arttırıyoruz. Genel bir sayfa değiştirme algoritması kullanılır; ait oldukları sürece
bakılmaksızın sayfaları değiştirir. Şimdi, bir sürecin yürütülmesinde yeni bir aşamaya
girdiğini ve daha fazla çerçeveye ihtiyaç duyduğunu varsayalım. Faylanmaya ve
çerçeveleri diğer süreçlerden uzaklaştırmaya başlar. Ancak bu süreçlerin bu sayfalara
ihtiyacı vardır ve bu nedenle diğer süreçlerden çerçeveler alarak hata yaparlar. Bu
arızalı işlemler, sayfaları içeri ve dışarı değiştirmek için çağrı cihazını kullanmalıdır.
Çağrı cihazı için sıraya girdiklerinde, hazır kuyruk boşalır. İşlemler sayfalama cihazını
beklerken CPU kullanımı azalır.
CPU zamanlayıcı , azalan CPU kullanımını görür ve sonuç olarak çoklu programlama
derecesini artırır . Yeni işlem, çalışan işlemlerden çerçeveler alarak başlamaya çalışır,
bu da daha fazla sayfa hatasına ve sayfalama aygıtı için daha uzun bir kuyruğa neden
olur. Sonuç olarak, CPU kullanımı daha da düşer ve CPU zamanlayıcısı çoklu
programlamanın derecesini daha da artırmaya çalışır. Thrashing meydana geldi ve
sistem verimi düşüyor. Sayfa hata oranı muazzam bir şekilde artar. Sonuç olarak, etkin
bellek erişim süresi artar. Hiçbir iş yapılmıyor, çünkü süreçler tüm zamanlarını
sayfalamaya harcıyor.
hırpalama
çağrı cihazı için daha uzun ortalama kuyruk nedeniyle. Böylece thrash olmayan bir
işlem için bile efektif erişim süresi artacaktır.
Thrash'i önlemek için, ihtiyaç duyduğu kadar çok çerçeve içeren bir süreç
sağlamalıyız. Ama kaç tane çerçeveye "ihtiyacı olduğunu" nasıl bileceğiz? Bir
strateji, bir sürecin gerçekte kaç çerçeve kullandığına bakarak başlar. Bu yaklaşım,
süreç yürütmenin yerellik modelini tanımlar .
Yerellik modeli, bir süreç yürütülürken yerellikten yerelliğe doğru hareket
ettiğini belirtir. Yerellik, birlikte aktif olarak kullanılan bir sayfalar kümesidir. Çalışan
bir program genellikle üst üste binebilen birkaç farklı bölgeden oluşur. Örneğin,
bir işlev çağrıldığında yeni bir yerellik tanımlar. Bunda
34
32
30
28
26
24
22
20
18
(a) (b)
uygulama vakti
Δ Δ
t1 t2
WS(t1) = {1,2,5,6,7} WS(t2) = {3,4}
D= WSSi ,
burada D , çerçeveler için toplam taleptir. Her süreç kendi çalışma setindeki sayfaları
aktif olarak kullanmaktadır. Bu nedenle, işlem i'nin WSSi çerçevelerine ihtiyacı var.
Toplam talep, mevcut çerçevelerin toplam sayısından (D > m) daha büyükse, bazı
işlemler yeterli çerçeveye sahip olmayacağından, çarpma meydana gelir.
Δ seçildikten sonra, çalışma seti modelinin kullanımı basittir. İşletim sistemi, her
işlemin çalışma grubunu izler ve çalışma kümesi boyutunu sağlamak için bu çalışma
kümesine yeterli çerçeveyi tahsis eder. Yeterli ekstra çerçeve varsa, başka bir işlem
başlatılabilir. Çalışma kümesi boyutlarının toplamı, kullanılabilir çerçevelerin toplam
sayısını aşacak şekilde artarsa, işletim sistemi askıya alınacak bir işlem seçer. İşlemin
sayfaları yazılır (değiştirilir) ve çerçeveleri diğer işlemlere yeniden tahsis edilir. Askıya
alınan işlem daha sonra yeniden başlatılabilir.
Bir sürecin çalışma grubu ile sayfa hata oranı arasında doğrudan bir ilişki vardır.
Tipik olarak, Şekil 10.22'de gösterildiği gibi, veri ve kod bölümlerine yapılan
referanslar bir bölgeden diğerine hareket ettikçe, bir sürecin çalışma seti zamanla
değişir. Bir işlemin çalışma kümesini depolamak için yeterli bellek olduğunu
varsayarsak (yani, işlem çökmüyor), işlemin sayfa hata oranı zaman içinde tepeler
ve vadiler arasında geçiş yapacaktır. Bu genel davranış aşağıda gösterilmiştir:
çalışma seti
sayfa
hata
oranı
0
zaman
Yeni bir yerellik için talep-çağrı yapmaya başladığımızda, sayfa hata oranında
bir zirve meydana gelir. Ancak, bu yeni konumun çalışma kümesi belleğe
alındığında, sayfa hatası oranı düşer. İşlem yeni bir çalışma grubuna geçtiğinde,
sayfa hatası oranı bir kez daha zirveye doğru yükselir ve yeni çalışma grubu
belleğe yüklendiğinde daha düşük bir orana döner. Bir tepe noktasının başlangıcı
ile bir sonraki tepe noktasının başlangıcı arasındaki zaman aralığı, bir çalışma
kümesinden diğerine geçişi temsil eder.
Machine Translated by Google
çalışma kümesi penceresi hareketli bir penceredir. Her bellek referansında, bir uçta
yeni bir referans görünür ve diğer uçta en eski referans düşer.
Çalışma kümesi penceresinde herhangi bir yere başvuruluyorsa, bir sayfa çalışma
kümesindedir.
Çalışma kümesi modeline sabit aralıklı bir zamanlayıcı kesmesi ve bir referans biti
ile yaklaşabiliriz. Örneğin, Δ'nin 10.000 referansa eşit olduğunu ve her 5.000 referansta
bir zamanlayıcı kesintisine neden olabileceğimizi varsayalım. Bir zamanlayıcı kesmesi
aldığımızda, her sayfa için referans bit değerlerini kopyalayıp temizliyoruz. Böylece,
bir sayfa hatası meydana gelirse, bir sayfanın son 10.000 ila 15.000 referans arasında
kullanılıp kullanılmadığını belirlemek için mevcut referans bitini ve iki bellek içi biti
inceleyebiliriz. Kullanılmışsa, bu bitlerden en az biri açık olacaktır.
Kullanılmamışsa, bu bitler kapalı olacaktır. En az bir biti olan sayfalar çalışma kümesinde
kabul edilecektir.
Bu düzenlemenin tamamen doğru olmadığına dikkat edin, çünkü 5.000'lik bir
aralık içinde bir referansın nerede meydana geldiğini söyleyemeyiz. Geçmiş bitlerinin
sayısını ve kesintilerin sıklığını artırarak belirsizliği azaltabiliriz (örneğin, her 1000
referansta bir 10 bit ve kesintiler). Bununla birlikte, bu daha sık kesintilere hizmet
vermenin maliyeti, buna bağlı olarak daha yüksek olacaktır.
Çalışma seti modeli başarılıdır ve çalışma seti bilgisi ön sayfalama için faydalı olabilir
(Bölüm 10.9.1), ancak bu, yığılmayı kontrol etmenin beceriksiz bir yolu gibi
görünmektedir. Sayfa hatası frekansını (PFF) kullanan bir strateji daha doğrudan bir
yaklaşım benimser.
Spesifik sorun, thrash'in nasıl önleneceğidir. Thrashing'in yüksek sayfa hatası
oranı vardır. Böylece sayfa hata oranını kontrol etmek istiyoruz. Çok yüksek olduğunda,
işlemin daha fazla kareye ihtiyacı olduğunu biliyoruz. Tersine, sayfa hata oranı çok
düşükse, işlemin çok fazla çerçevesi olabilir. İstenen sayfa-hata oranı üzerinde alt ve
üst sınır oluşturabiliriz (Şekil 10.23).
Gerçek sayfa hata oranı üst sınırı aşarsa, işlemi tahsis ederiz.
çerçeve sayısını
artır
üst sınır
çerçeve sayısı
başka bir çerçeve. Sayfa hata oranı alt sınırın altına düşerse, bir
süreçten kare. Böylece, thrash'i önlemek için sayfa hata oranını doğrudan ölçebilir ve
kontrol edebiliriz.
Çalışma seti stratejisinde olduğu gibi, bir süreci değiştirmemiz gerekebilir. Eğer
sayfa hata oranı artar ve boş çerçeve yok, bazılarını seçmeliyiz
işleyin ve destek mağazasına değiştirin. Serbest bırakılan çerçeveler daha sonra dağıtılır
yüksek sayfa hatası oranlarına sahip işlemlere.
Pratik olarak konuşursak, dövülme ve sonuçta ortaya çıkan takas, hoş olmayan bir şekilde
performans üzerinde yüksek etkisi. uygulanmasında mevcut en iyi uygulama
bilgisayar sistemi, mümkün olduğunda yeterli fiziksel bellek içerecektir,
thrashing ve takas önlemek için. Akıllı telefonlardan büyük sunucular aracılığıyla,
tüm çalışma setlerini aynı anda bellekte tutacak kadar bellek sağlamak,
aşırı koşullar dışında, en iyi kullanıcı deneyimini sağlar.
kafa 7 2 9 21 27 16
kafa 15 3 35 26
426
Bölüm 10 Sanal Bellek
serbest çerçeve listesi
kafa 2 9 21 27 16 15 3 35
kafa 26
1. Çekirdek, bazıları bir sayfadan daha küçük olan çeşitli boyutlardaki veri yapıları
için bellek ister. Sonuç olarak, çekirdek belleği muhafazakar bir şekilde
kullanmalı ve parçalanma nedeniyle israfı en aza indirmeye çalışmalıdır. Bu
özellikle önemlidir çünkü birçok işletim sistemi çekirdek kodunu veya verilerini
sayfalama sistemine tabi tutmaz.
Aşağıdaki bölümlerde, çekirdek süreçlerine atanan boş belleği yönetmek için iki
stratejiyi inceleyeceğiz: “arkadaş sistemi” ve slab tahsisi.
Arkadaşlık sistemi, fiziksel olarak bitişik sayfalardan oluşan sabit boyutlu bir bölümden
bellek ayırır. Bu bölümden bellek, 2'nin gücü (4 KB, 8 KB, 16 KB vb.) olarak
boyutlandırılmış birimlerde talepleri karşılayan , 2'nin gücünde bir ayırıcı kullanılarak
ayrılır. Uygun boyutta olmayan birimlerdeki bir istek, bir sonraki en yüksek güç olan
2'ye yuvarlanır. Örneğin, 11 KB'lık bir istek, 16 KB'lık bir segmentle karşılanır .
Basit bir örnek düşünelim. Bir bellek bölümünün boyutunun başlangıçta 256 KB
olduğunu ve çekirdeğin 21 KB bellek istediğini varsayalım. Segment başlangıçta
her biri 128 KB boyutunda olan AL ve AR olarak adlandıracağımız iki arkadaşa
bölünmüştür . Bu arkadaşlardan biri ayrıca 64 KB'lık iki arkadaşa bölünmüştür: BL ve
BR. Bununla birlikte, 21 KB'den 2'nin bir sonraki en yüksek gücü 32 KB'dir , bu nedenle
BL veya BR tekrar iki 32 KB'lik arkadaşlara, CL ve CR'ye bölünür . Bu arkadaşlardan biri
21 KB'lik isteği karşılamak için kullanılır. Bu şema, Şekil 10.26'da gösterilmektedir,
burada CL , 21-KB isteğine tahsis edilen segmenttir .
Arkadaşlık sisteminin bir avantajı, birleştirme olarak bilinen bir teknik kullanılarak
bitişik arkadaşların daha büyük bölümler oluşturmak için ne kadar hızlı bir şekilde
birleştirilebileceğidir. Şekil 10.26'da, örneğin, çekirdek tahsis edilen CL birimini
serbest bıraktığında, sistem CL ve CR'yi 64 KB'lık bir segmentte birleştirebilir. Bu
segment, BL, 128 KB'lık bir segment oluşturmak için arkadaşı BR ile birleştirilebilir .
Sonuç olarak, orijinal 256 KB segmenti elde edebiliriz.
Buddy sisteminin bariz dezavantajı, bir sonraki en yüksek güç olan 2'ye
yuvarlamanın, tahsis edilen segmentler içinde parçalanmaya neden olma olasılığının
çok yüksek olmasıdır. Örneğin, 33 KB'lık bir istek yalnızca 64 KB'lık bir segmentle karşılanabilir.
Aslında, tahsis edilen birimin yüzde 50'sinden daha azının dahili parçalanma nedeniyle
boşa harcanacağını garanti edemeyiz. Aşağıdaki bölümde, parçalanma nedeniyle
alan kaybının olmadığı bir bellek ayırma şemasını inceleyeceğiz.
Çekirdek belleği tahsis etmek için ikinci bir strateji, levha tahsisi olarak bilinir . Bir
levha , bir veya daha fazla fiziksel olarak bitişik sayfadan oluşur. Bir önbellek oluşur
Machine Translated by Google
428
Bölüm 10 Sanal Bellek
fiziksel olarak bitişik sayfalar
256 KB
128 KB 128 KB
AL AR
64 KB 64 KB
BL BR
32 KB 32 KB
CL CR
bir veya daha fazla levhadan. Her benzersiz çekirdek veri yapısı için tek bir önbellek vardır;
örneğin, işlem tanımlayıcılarını temsil eden veri yapısı için ayrı bir önbellek, dosya nesneleri
için ayrı bir önbellek, semaforlar için ayrı bir önbellek vb. Her önbellek, önbelleğin temsil
ettiği çekirdek veri yapısının örnekleri olan nesnelerle doldurulur . Örneğin, semaforları
temsil eden önbellek, semafor nesnelerinin örneklerini depolar, süreç tanımlayıcılarını
temsil eden önbellek, süreç tanımlayıcı nesnelerinin örneklerini depolar ve benzerleri.
3 KB
nesneler
fiziksel olarak
bitişik sayfalar
7 KB
nesneler
Döşeme tahsisi algoritması, çekirdek nesnelerini depolamak için önbellekleri kullanır. Bir
önbellek oluşturulduğunda, başlangıçta ücretsiz olarak işaretlenen bir dizi nesne önbelleğe
tahsis edilir. Önbellekteki nesnelerin sayısı, ilişkili döşemenin boyutuna bağlıdır. Örneğin, 12
KB'lık bir levha (üç bitişik 4 KB sayfadan oluşan) altı adet 2 KB'lık nesne depolayabilir . Başlangıçta,
önbellekteki tüm nesneler ücretsiz olarak işaretlenir. Bir çekirdek veri yapısı için yeni bir nesneye
ihtiyaç duyulduğunda, ayırıcı, talebi karşılamak için önbellekten herhangi bir boş nesne atayabilir.
Önbellekten atanan nesne kullanılmış olarak işaretlenir.
Çekirdeğin, bir süreç tanımlayıcısını temsil eden bir nesne için levha ayırıcıdan bellek talep
ettiği bir senaryoyu ele alalım. Linux sistemlerinde, bir süreç tanımlayıcısı, yaklaşık 1,7 KB bellek
gerektiren struct task struct türündedir . Linux çekirdeği yeni bir görev oluşturduğunda ,
önbelleğinden struct task struct nesnesi için gerekli belleği talep eder. Önbellek, bir döşemede
önceden tahsis edilmiş ve boş olarak işaretlenmiş bir struct görevi struct nesnesini kullanarak
talebi yerine getirecektir .
Döşeme ayırıcı, önce talebi kısmi bir döşemede serbest bir nesneyle karşılamaya çalışır. Hiçbiri
yoksa, boş bir levhadan serbest bir nesne atanır. Boş levha yoksa, bitişik fiziksel sayfalardan yeni
bir levha tahsis edilir ve bir önbelleğe atanır; nesne için bellek bu levhadan tahsis edilir.
1. Parçalanma nedeniyle bellek boşa harcanmaz. Parçalanma bir sorun değildir, çünkü her
benzersiz çekirdek veri yapısı ilişkili bir önbelleğe sahiptir ve her önbellek, temsil edilen
nesnelerin boyutundaki parçalara bölünmüş bir veya daha fazla levhadan oluşur. Bu
nedenle, çekirdek bir nesne için bellek istediğinde, levha ayırıcı, nesneyi temsil etmek için
gereken tam bellek miktarını döndürür.
2. Bellek istekleri hızlı bir şekilde karşılanabilir. Döşeme tahsis şeması, bu nedenle, genellikle
çekirdekten gelen taleplerde olduğu gibi, nesneler sıklıkla tahsis edildiğinde ve yeniden
tahsis edildiğinde, belleği yönetmek için özellikle etkilidir. Belleği ayırma ve serbest
bırakma eylemi zaman alıcı bir süreç olabilir. Ancak nesneler önceden oluşturulur ve bu
nedenle önbellekten hızlı bir şekilde tahsis edilebilir. Ayrıca, çekirdek bir nesneyi bitirip onu
serbest bıraktığında, özgür olarak işaretlenir ve önbelleğine geri döner, böylece
çekirdekten gelen sonraki istekler için hemen kullanılabilir hale gelir.
Döşeme ayırıcısı ilk olarak Solaris 2.4 çekirdeğinde ortaya çıktı. Genel amaçlı doğası
nedeniyle, bu ayırıcı artık Solaris'te belirli kullanıcı modu bellek istekleri için de kullanılmaktadır.
Linux başlangıçta buddy sistemini kullandı; ancak, Sürüm 2.2'den başlayarak, Linux çekirdeği slab
ayırıcıyı benimsemiştir. Linux
430 Bölüm
Machine Translated by Google 10 Sanal Bellek
SLAB olarak döşeme uygulamasına atıfta bulunur . Linux'un son dağıtımları, diğer iki
çekirdek bellek ayırıcısını içerir: SLOB ve SLUB ayırıcıları.
SLOB ayırıcı, gömülü sistemler gibi sınırlı miktarda belleğe sahip sistemler için
tasarlanmıştır . SLOB ("basit blok listesi" anlamına gelir) üç nesne listesi tutar: küçük (256
bayttan küçük nesneler için), orta (1.024 bayttan küçük nesneler için) ve büyük (boyutundan
küçük diğer tüm nesneler için ). Bir sayfa). Bellek istekleri, ilk sığdırma ilkesi kullanılarak
uygun listedeki bir nesneden ayrılır.
Sürüm 2.6.24'ten itibaren, SLUB ayırıcı , Linux çekirdeği için varsayılan ayırıcı olarak
SLAB'ın yerini aldı . SLUB , SLAB tahsisatçısının gerektirdiği ek yükün çoğunu azalttı .
Örneğin, SLAB her kütük ile belirli meta verileri depolarken, SLUB bu verileri Linux
çekirdeğinin her sayfa için kullandığı sayfa yapısında depolar. Ayrıca, SLUB , SLAB ayırıcısının
her önbellekteki nesneler için tuttuğu CPU başına kuyrukları içermez . Çok sayıda işlemciye
sahip sistemler için bu kuyruklara ayrılan bellek miktarı önemlidir. Böylece SLUB , bir
sistemdeki işlemci sayısı arttıkça daha iyi performans sağlar.
Bir çağrı sistemi için verdiğimiz başlıca kararlar, bu bölümde daha önce tartıştığımız bir
değiştirme algoritması ve bir tahsis politikası seçimleridir. Başka birçok husus da var ve
bunlardan birkaçını burada tartışıyoruz.
10.9.1 Hazırlama
Saf talep sayfalamanın bariz bir özelliği, bir süreç başlatıldığında meydana gelen çok sayıda
sayfa hatasıdır. Bu durum, ilk yerelliği belleğe almaya çalışmaktan kaynaklanır. Ön
sayfalama , bu yüksek seviyedeki ilk sayfalamayı önleme girişimidir. Strateji, ihtiyaç duyulacak
sayfaların bir kısmını veya tamamını bir kerede belleğe getirmektir.
Örneğin, çalışma kümesi modelini kullanan bir sistemde, her işlemle, çalışma
kümesindeki sayfaların bir listesini tutabiliriz. Bir işlemi askıya almamız gerekirse (boş
çerçevelerin olmaması nedeniyle), bu işlem için çalışma setini hatırlarız.
İşlem devam ettirileceğinde ( G/Ç bittiğinden veya yeterli boş çerçeve bulunduğundan),
işlemi yeniden başlatmadan önce tüm çalışma setini otomatik olarak belleğe geri getiririz.
Mevcut bir makine için bir işletim sistemi tasarımcılarının nadiren sayfa boyutuyla
ilgili bir seçeneği vardır. Ancak, yeni makineler tasarlanırken, en iyi sayfa boyutuna
ilişkin bir karar verilmelidir. Tahmin edebileceğiniz gibi, tek bir en iyi sayfa boyutu
yoktur. Bunun yerine, çeşitli boyutları destekleyen bir dizi faktör vardır. Sayfa
boyutları her zaman 2'nin katıdır ve genellikle 4.096 (212) ile 4.194.304 (222) bayt
arasında değişir.
Sayfa boyutunu nasıl seçeriz? Bir endişe, sayfa tablosunun boyutudur. Belirli bir
sanal bellek alanı için sayfa boyutunu azaltmak, sayfa sayısını ve dolayısıyla sayfa
tablosunun boyutunu artırır. Örneğin 4 MB (222) sanal bellek için 4.096 sayfa 1.024
bayt, ancak yalnızca 512 sayfa 8.192 bayt olacaktır. Her etkin işlemin kendi sayfa
tablosu kopyasına sahip olması gerektiğinden, büyük bir sayfa boyutu tercih edilir.
Bununla birlikte, bellek daha küçük sayfalarda daha iyi kullanılır. Bir işleme
00000 konumundan başlayan ve ihtiyaç duyduğu kadarına sahip olana kadar devam
eden bir bellek tahsis edilirse, muhtemelen tam olarak bir sayfa sınırında
bitmeyecektir. Bu nedenle, son sayfanın bir kısmı tahsis edilmelidir (çünkü sayfalar
tahsis birimleridir), ancak kullanılmayacaktır (iç parçalanma yaratarak). İşlem
boyutundan ve sayfa boyutundan bağımsız olduğunu varsayarsak, ortalama olarak
her işlemin son sayfasının yarısının boşa gitmesini bekleyebiliriz. Bu kayıp 512 baytlık
bir sayfa için yalnızca 256 bayt iken 8.192 baytlık bir sayfa için 4.096 bayttır. Dahili
parçalanmayı en aza indirmek için küçük bir sayfa boyutuna ihtiyacımız var.
Başka bir sorun, bir sayfayı okumak veya yazmak için gereken zamandır. Bölüm
11.1'de göreceğiniz gibi, depolama aygıtı bir HDD olduğunda, G/Ç süresi arama,
gecikme ve aktarım sürelerinden oluşur. Aktarım süresi, aktarılan miktarla (yani sayfa
boyutuyla) orantılıdır; bu, küçük bir sayfa boyutu için tartışılacak gibi görünen bir
gerçektir. Ancak, gecikme ve arama süresi normalde aktarım süresini cüce eder.
Saniyede 50 MB aktarım hızında, 512 bayt aktarımı yalnızca 0,01 milisaniye sürer.
Ancak gecikme süresi belki 3 milisaniyedir ve arama süresi 5 milisaniyedir. Toplam G/
Ç süresinin (8.01 milisaniye), bu nedenle, gerçek aktarıma yalnızca yaklaşık yüzde
0,1'i atfedilebilir. Sayfa boyutunu iki katına çıkarmak, G/Ç süresini yalnızca 8,02
milisaniyeye çıkarır. 1.024 baytlık tek bir sayfayı okumak 8.02 milisaniye, her biri 512
baytlık iki sayfayla aynı miktarda okumak 16.02 milisaniye sürer. Bu nedenle, G/Ç
süresini en aza indirme arzusu, daha büyük bir sayfa boyutu için tartışır.
9. Bölümde , TLB'nin isabet oranını tanıttık . TLB için isabet oranının , sayfa
tablosundan ziyade TLB'de çözümlenen sanal adres çevirilerinin yüzdesini ifade
ettiğini hatırlayın. Açıkçası, isabet oranı TLB'deki giriş sayısı ile ilgilidir ve isabet
oranını artırmanın yolu, giriş sayısını artırmaktır. Ancak bu, TLB'yi oluşturmak için
kullanılan çağrışımsal bellek hem pahalı hem de güç tükettiği için ucuza gelmiyor .
İsabet oranıyla ilgili benzer bir ölçümdür: TLB erişimi. TLB erişimi , TLB'den
erişilebilen bellek miktarını ifade eder ve yalnızca sayfa boyutuyla çarpılan giriş
sayısıdır. İdeal olarak, bir işlem için çalışma seti TLB'de saklanır. Değilse, işlem TLB
yerine sayfa tablosundaki bellek referanslarını çözmek için önemli miktarda zaman
harcar . TLB'deki giriş sayısını ikiye katlarsak, TLB erişimini ikiye katlarız . Ancak, bazı
bellek yoğun uygulamalar için bu, çalışma setini depolamak için yine de yetersiz
olabilir.
TLB erişimini artırmaya yönelik başka bir yaklaşım , sayfa boyutunu artırmak
veya birden çok sayfa boyutu sağlamaktır. Sayfa boyutunu 4 KB'den 16 KB'ye
çıkarırsak, TLB erişimini dört katına çıkarırız. Ancak bu, bu kadar büyük sayfa boyutu
gerektirmeyen bazı uygulamalar için parçalanmanın artmasına neden olabilir.
Alternatif olarak, çoğu mimari birden fazla sayfa boyutu için destek sağlar ve bu
destekten yararlanmak için bir işletim sistemi yapılandırılabilir. Örneğin, Linux
sistemlerinde varsayılan sayfa boyutu 4 KB'dir; bununla birlikte, Linux ayrıca büyük
sayfalar da sağlar; bu özellik, daha büyük sayfaların (örneğin, 2 MB) kullanılabileceği
bir fiziksel bellek bölgesini belirtir .
ARMv8 mimarisinin farklı boyutlardaki sayfalar ve bölgeler için destek
sağladığını Bölüm 9.7'den hatırlayın. Ek olarak, ARMv8'deki her TLB girişi bitişik bir
bit içerir . Bu bit belirli bir TLB girişi için ayarlanmışsa, bu giriş bitişik (bitişik) bellek
bloklarını eşler. Üç olası düzenleme
Machine Translated by Google
3. 32 × 64 KB bitişik blokları veya 128 × 16 KB bitişik blokları içeren 2-MB TLB girişi .
Birden çok sayfa boyutu için destek sağlamak, TLB'yi yönetmek için donanım
yerine işletim sisteminin gerektirebilir . Örneğin, bir TLB girişindeki alanlardan biri,
girişe karşılık gelen sayfa çerçevesinin boyutunu belirtmelidir veya ARM mimarileri
durumunda, girişin bitişik bir bellek bloğuna atıfta bulunduğunu belirtmelidir. TLB'yi
donanımda değil yazılımda yönetmenin performansta bir maliyeti vardır. Ancak artan
isabet oranı ve TLB erişimi performans maliyetlerini dengeler.
Bölüm 9.4.3, tersine çevrilmiş sayfa tablosu kavramını tanıttı. Bu sayfa yönetimi
biçiminin amacı, sanaldan fiziksele adres çevirilerini izlemek için gereken fiziksel
bellek miktarını azaltmaktır. Bu tasarrufu, <işlem-kimliği, sayfa-numarası> çifti
tarafından indekslenen, fiziksel belleğin her sayfası için bir girişi olan bir tablo
oluşturarak gerçekleştiririz.
Her bir fiziksel çerçevede hangi sanal bellek sayfasının depolandığı hakkında
bilgi tuttukları için, ters çevrilmiş sayfa tabloları bu bilgiyi depolamak için gereken
fiziksel bellek miktarını azaltır. Ancak, tersine çevrilmiş sayfa tablosu artık bir işlemin
mantıksal adres alanı hakkında tam bilgi içermez ve başvurulan bir sayfa şu anda
bellekte değilse bu bilgi gereklidir. Talep sayfalama, sayfa hatalarını işlemek için bu
bilgiyi gerektirir. Bilginin mevcut olması için harici bir sayfa tablosu (işlem başına bir
tane) tutulmalıdır. Bu tür tabloların her biri geleneksel süreç başına sayfa tablosuna
benzer ve her bir sanal sayfanın nerede bulunduğuna ilişkin bilgileri içerir.
Ancak harici sayfa tabloları, ters çevrilmiş sayfa tablolarının faydasını olumsuzlar
mı? Bu tablolara yalnızca bir sayfa hatası oluştuğunda başvurulduğundan, hızlı bir
şekilde kullanılabilir olmaları gerekmez. Bunun yerine, gerektiği şekilde belleğe girip
çıkarlar. Ne yazık ki, bir sayfa hatası artık sanal bellek yöneticisinin, sanal sayfayı
yedekleme deposunda bulması için ihtiyaç duyduğu harici sayfa tablosunda sayfalar
oluştururken başka bir sayfa hatası oluşturmasına neden olabilir. Bu özel durum,
çekirdekte dikkatli işlem yapılmasını ve sayfa arama işleminde gecikme olmasını gerektirir.
Talep sayfalama, kullanıcı programı için şeffaf olacak şekilde tasarlanmıştır. Çoğu
durumda, kullanıcı belleğin disk belleği doğasından tamamen habersizdir. Ancak
diğer durumlarda, kullanıcı (veya derleyici) altta yatan talep sayfalama konusunda bir
farkındalığa sahipse sistem performansı geliştirilebilir.
Yapmacık ama bilgilendirici bir örneğe bakalım. Sayfaların boyutunun 128 kelime
olduğunu varsayın. İşlevi 128'e 128 dizinin her öğesini 0'a başlatmak olan bir C
programı düşünün. Aşağıdaki kod tipiktir:
434 Bölüm 10 Sanal Bellek
Machine Translated by Google
int i, j;
int[128][128] veri;
Dizinin ana satırda saklandığına dikkat edin; yani dizi depolanır data[0][0], data[0]
[1], ···, data[0][127], data[1][0], data[1][1] , ···, veri[127][127]. 128 kelimelik sayfalar için
her satır bir sayfa alır. Böylece, önceki kod her sayfada bir kelimeyi, ardından her
sayfada başka bir kelimeyi sıfırlar ve bu böyle devam eder. İşletim sistemi tüm
programa 128'den az çerçeve ayırırsa, yürütülmesi 128 × 128 = 16.384 sayfa hatasıyla
sonuçlanacaktır.
Buna karşılık, kodu şu şekilde değiştirdiğimizi varsayalım:
int i, j;
int[128][128] veri;
Bu kod, sonraki sayfaya başlamadan önce bir sayfadaki tüm kelimeleri sıfırlar ve sayfa
hatalarının sayısını 128'e düşürür.
Veri yapılarının ve programlama yapılarının dikkatli seçimi, yerelliği artırabilir ve
dolayısıyla sayfa hata oranını ve çalışma kümesindeki sayfa sayısını azaltabilir. Örneğin,
erişim her zaman en üste yapıldığından, bir yığın iyi bir konuma sahiptir. Buna karşılık,
bir karma tablo, referansları dağıtmak ve kötü yerellik üretmek için tasarlanmıştır.
Elbette, referansın yeri, bir veri yapısının kullanımının verimliliğinin sadece bir
ölçüsüdür. Diğer ağır ağırlıklı faktörler arasında arama hızı, toplam bellek referansı
sayısı ve dokunulan toplam sayfa sayısı yer alır.
Daha sonraki bir aşamada, derleyici ve yükleyici, sayfalama üzerinde önemli bir etkiye
sahip olabilir. Kodu ve verileri ayırmak ve yeniden giriş kodu oluşturmak, kod sayfalarının
salt okunur olabileceği ve dolayısıyla hiçbir zaman değiştirilemeyeceği anlamına gelir.
Temiz sayfaların değiştirilmeleri için sayfalarının çıkarılması gerekmez. Yükleyici, her bir
rutini tamamen tek bir sayfada tutarak rutinleri sayfa sınırlarının ötesine yerleştirmekten kaçınabi
Birbirini defalarca arayan rutinler aynı sayfaya sığdırılabilir.
Bu paketleme, yöneylem araştırmasının bin-paketleme probleminin bir çeşididir:
değişken boyutlu yük bölümlerini sabit boyutlu sayfalara yerleştirmeye çalışın,
böylece sayfalar arası referanslar en aza indirilir. Böyle bir yaklaşım, özellikle büyük
sayfa boyutları için kullanışlıdır.
aktarılacak bayt sayısı ve arabellek için bir bellek adresi (Şekil 10.28). Aktarım
tamamlandığında CPU kesintiye uğrar.
Aşağıdaki olaylar dizisinin meydana gelmediğinden emin olmalıyız: Bir işlem
bir G/Ç isteği yayınlar ve bu G/Ç aygıtı için kuyruğa alınır. Bu arada CPU diğer
işlemlere verilir. Bu işlemler sayfa hatalarına neden olur ve bunlardan biri, global bir
değiştirme algoritması kullanarak, bekleme işlemi için bellek arabelleğini içeren
sayfayı değiştirir. Sayfalar sayfalandırılmıştır. Bir süre sonra, G/Ç isteği aygıt
kuyruğunun başına geçtiğinde, belirtilen adrese G/Ç gerçekleşir. Ancak bu çerçeve
artık başka bir işleme ait farklı bir sayfa için kullanılıyor.
Bu sorunun iki ortak çözümü vardır. Bir çözüm, hiçbir zaman kullanıcı belleğine
G/Ç yürütmemektir. Bunun yerine, veriler her zaman sistem belleği ile kullanıcı
belleği arasında kopyalanır. G/Ç yalnızca sistem belleği ile G/Ç aygıtı arasında
gerçekleşir. Bu yüzden teyp üzerine bir blok yazmak için önce bloğu sistem
belleğine kopyalıyoruz ve sonra teybe yazıyoruz. Bu fazladan kopyalama, kabul
edilemez derecede yüksek ek yüke neden olabilir.
Başka bir çözüm, sayfaların belleğe kilitlenmesine izin vermektir. Burada, her
çerçeve ile bir kilit biti ilişkilendirilir. Çerçeve kilitliyse, değiştirilmek üzere seçilemez.
Bu yaklaşım altında, diske bir blok yazmak için, bloğu içeren sayfaları belleğe
kilitleriz. Sistem daha sonra her zamanki gibi devam edebilir.
Kilitli sayfalar değiştirilemez. G/Ç tamamlandığında , sayfalar
kilidi açıldı.
Kilit bitleri çeşitli durumlarda kullanılır. Sıklıkla, işletim sistemi çekirdeğinin bir
kısmı veya tamamı belleğe kilitlenir. Çoğu işletim sistemi, çekirdekten veya bellek
yönetimini gerçekleştiren de dahil olmak üzere belirli bir çekirdek modülünden
kaynaklanan bir sayfa hatasına tahammül edemez. Kullanıcı işlemlerinin ayrıca
sayfaları belleğe kilitlemesi gerekebilir. Bir veritabanı işlemi, örneğin blokları ikincil
depolama ve depolama arasında taşımak gibi bir bellek yığınını yönetmek isteyebilir.
tampon
disk sürücüsü
Şekil 10.28 G/Ç için kullanılan çerçevelerin neden bellekte olması gerektiğinin nedeni.
Machine Translated by Google
belleğin kendisidir, çünkü verilerini nasıl kullanacağına dair en iyi bilgiye sahiptir.
Sayfaların bellekte bu şekilde sabitlenmesi oldukça yaygındır ve çoğu işletim
sisteminde, bir uygulamanın mantıksal adres alanının bir bölgesinin sabitlenmesini
istemesine izin veren bir sistem çağrısı vardır. Bu özelliğin kötüye kullanılabileceğini
ve bellek yönetimi algoritmalarında strese neden olabileceğini unutmayın. Bu
nedenle, bir uygulama genellikle böyle bir istekte bulunmak için özel ayrıcalıklar gerektirir.
Kilit biti için başka bir kullanım, normal sayfa değiştirmeyi içerir. Aşağıdaki
olaylar dizisini göz önünde bulundurun: Düşük öncelikli bir süreç hataları. Yedek
çerçeve seçildiğinde, çağrı sistemi gerekli sayfayı belleğe okur.
Devam etmeye hazır, düşük öncelikli süreç hazır kuyruğuna girer ve CPU'yu bekler .
Düşük öncelikli bir süreç olduğundan, bir süre CPU zamanlayıcısı tarafından
seçilmeyebilir . Düşük öncelikli süreç beklerken, yüksek öncelikli bir süreç arızalanır.
Değiştirme ararken, çağrı sistemi bellekte bulunan ancak referans alınmamış veya
değiştirilmemiş bir sayfa görür: bu, düşük öncelikli işlemin yeni getirdiği sayfadır.
Bu sayfa mükemmel bir değiştirme gibi görünüyor.
Temizdir ve yazılmasına gerek yoktur ve görünüşe göre uzun süredir kullanılmamıştır.
Yüksek öncelikli sürecin düşük öncelikli sürecin yerini alıp alamayacağı bir
politika kararıdır. Sonuçta, yüksek öncelikli sürecin yararına düşük öncelikli süreci
erteliyoruz. Ancak, düşük öncelikli süreç için sayfayı getirmek için harcanan çabayı
boşa harcıyoruz.
Yeni getirilen bir sayfanın en az bir kez kullanılabilene kadar değiştirilmesini
engellemeye karar verirsek, bu mekanizmayı uygulamak için kilit bitini kullanabiliriz.
Değiştirilmek üzere bir sayfa seçildiğinde, kilit biti açılır. Arıza süreci tekrar
gönderilene kadar açık kalır.
Bir kilit biti kullanmak tehlikeli olabilir: kilit biti açılabilir ama asla kapanmayabilir.
Bu durum meydana gelirse (örneğin işletim sistemindeki bir hata nedeniyle), kilitli
çerçeve kullanılamaz hale gelir. Örneğin, Solaris kilitleme "ipuçlarına" izin verir,
ancak serbest çerçeve havuzu çok küçülürse veya bireysel bir işlem bellekte çok
fazla sayfanın kilitlenmesini isterse bu ipuçlarını göz ardı etmekte serbesttir.
10.10.1 Linux
Bölüm 10.8.2'de, Linux'un slab tahsisini kullanarak çekirdek belleği nasıl yönettiğini
tartıştık. Şimdi Linux'un sanal belleği nasıl yönettiğini ele alıyoruz. Linux, sayfaları
boş çerçeveler listesinden ayırarak talep çağrısını kullanır. Ayrıca, Bölüm 10.4.5.2'de
açıklanan LRU yaklaşımı saat algoritmasına benzer bir genel sayfa değiştirme ilkesi
kullanır . Linux, belleği yönetmek için iki tür sayfa listesi tutar: etkin liste ve etkin
olmayan liste. Aktif liste , kullanımda olduğu düşünülen sayfaları içerirken, aktif
olmayan liste , yakın zamanda referans verilmemiş ve geri alınmaya uygun sayfaları
içerir.
Machine Translated by Google
başvurulan
yeni
arka ön
sayfa
aktif_liste
başvurulan
ön arka
inactive_list
Her sayfa, sayfaya her başvuru yapıldığında ayarlanan bir erişim bitine sahiptir.
(Sayfa erişimini işaretlemek için kullanılan gerçek bitler mimariye göre değişir.)
önce tahsis edilir, erişilen biti ayarlanır ve dizinin arkasına eklenir.
aktif liste. Benzer şekilde, etkin listedeki bir sayfaya başvurulduğunda,
erişilen biti ayarlanır ve sayfa listenin arkasına taşınır. Periyodik olarak,
aktif listedeki sayfalar için erişilen bitler sıfırlanır. Zamanla, en az
son kullanılan sayfa aktif listenin başında olacaktır . Oradan, olabilir
etkin olmayan listenin arkasına taşıyın. Etkin olmayan listede bir sayfa varsa
referans alındığında, aktif listenin arkasına geri döner . Bu desen
Şekil 10.29'da gösterilmiştir.
İki liste göreceli dengede tutulur ve aktif liste büyüdüğünde
etkin olmayan listeden çok daha büyük, etkin listenin önündeki sayfalar
ıslah için uygun hale geldikleri etkin olmayan listeye gidin. bu
Linux çekirdeğinde, sistemdeki boş bellek miktarını periyodik olarak uyandıran ve
kontrol eden bir sayfa çıkış arka plan süreci süreci kswapd vardır. Eğer boş hafıza
belirli bir eşiğin altına düşerse, kswapd etkin olmayan listedeki sayfaları taramaya
ve bunları ücretsiz liste için geri almaya başlar. Linux sanal bellek yönetimi, Bölüm
20'de daha ayrıntılı olarak tartışılmaktadır.
10.10.2 Pencereler
Windows 10, Intel üzerinde çalışan 32 ve 64 bit sistemleri destekler (IA-32 ve x86-
64) ve ARM mimarileri. 32 bit sistemlerde varsayılan sanal adres alanı
2 GB'dir, ancak 3 GB'a kadar genişletilebilir. 32 bit sistem desteği
4 GB fiziksel bellek. 64 bit sistemlerde Windows 10, 128 TB sanal adres alanına sahiptir
ve 24 TB'a kadar fiziksel belleği destekler. (Sürümleri
Windows Server 128 TB'a kadar fiziksel belleği destekler.) Windows 10, şu ana kadar
açıklanan bellek yönetimi özelliklerinin çoğunu uygular.
paylaşılan kitaplıklar, talep sayfalama, yazma üzerine kopyalama, sayfalama ve bellek
sıkıştırma.
Machine Translated by Google
10.10.3 Solaris
Solaris'te, bir iş parçacığı bir sayfa hatasına neden olduğunda, çekirdek,
bakımını yaptığı boş sayfalar listesinden kusurlu iş parçacığına bir sayfa atar.
Bu nedenle, çekirdeğin yeterli miktarda boş bellek bulundurması zorunludur.
Bu ücretsiz sayfa listesiyle ilişkili olarak , sayfalamaya başlamak için bir eşiği
temsil eden lotsfree parametresi bulunur. lotfree parametresi tipik olarak
fiziksel belleğin boyutunun 1 64'üne ayarlanır . Çekirdek, saniyede dört kez,
boş bellek miktarının lotfree'den az olup olmadığını kontrol eder. sayısı ise
Machine Translated by Google
ücretsiz sayfalar lotfree'nin altına düşer, sayfa çıkışı olarak bilinen bir süreç başlar .
Sayfa çıkışı işlemi, sayfaları tararken tek el yerine iki el kullanması dışında, Bölüm
10.4.2'de açıklanan ikinci şans algoritmasına benzer.
Sayfa çıkışı işlemi şu şekilde çalışır: Saatin ön ibresi bellekteki tüm sayfaları
tarar ve referans bitini 0'a ayarlar. Daha sonra, saatin arka ibresi bellekteki sayfalar
için referans bitini inceler ve referans biti olan her sayfayı ekler. hala ücretsiz listeye
0'a ayarlandı ve içeriği değiştirilmişse içeriğini ikincil depolamaya yazıyor. Solaris
ayrıca, başka bir işleme yeniden atanmadan önce sayfaya erişilirse, bir sürecin
ücretsiz listeden bir sayfayı geri almasına izin vererek küçük sayfa hatalarını da
yönetir.
Sayfa çıkışı algoritması, sayfaların taranma hızını (tarama hızı olarak bilinir )
kontrol etmek için birkaç parametre kullanır. Tarama hızı, saniyede sayfa olarak
ifade edilir ve yavaş taramadan hızlı taramaya kadar değişir. Boş bellek lotboşun
altına düştüğünde, tarama saniyede yavaş tarama sayfalarında gerçekleşir ve
kullanılabilir boş bellek miktarına bağlı olarak hızlı taramaya ilerler.
Yavaş taramanın varsayılan değeri saniyede 100 sayfadır. Hızlı tarama tipik olarak
(toplam fiziksel sayfalar)/2 sayfa/saniye, maksimum 8.192 sayfa/saniye değerine
ayarlanır. Bu, Şekil 10.30'da gösterilmektedir ( hızlı tarama maksimuma ayarlanmış
olarak).
Saatin akrep ve yelkovanı arasındaki mesafe (sayfa olarak), bir sistem parametresi
olan el yayılımı tarafından belirlenir. Ön elin biraz temizlemesi ile arka elin değerini
araştırması arasındaki süre, tarama hızına ve el yayılımına bağlıdır . Tarama hızı
saniyede 100 sayfa ve el dağılımı 1.024 sayfa ise, bir bitin ön el tarafından
ayarlandığı zaman ile arka el tarafından kontrol edildiği zaman arasında 10 saniye
geçebilir. Ancak, bellek sistemine yapılan talepler nedeniyle, birkaç binlik bir tarama
oranı nadir değildir. Bu, temizleme ve biraz araştırma arasındaki sürenin genellikle
birkaç saniye olduğu anlamına gelir.
8192
hızlı tarama
100
yavaş tarama
Sayfa tarama algoritması, tarayıcı tarafından talep edilmeye uygun olsalar bile,
birkaç işlem tarafından paylaşılan kitaplıklara ait sayfaları atlar. Algoritma ayrıca
işlemlere tahsis edilen sayfalar ile normal veri dosyalarına tahsis edilen sayfalar
arasında ayrım yapar. Bu, öncelikli çağrı olarak bilinir ve Bölüm 14.6.2'de ele alınmıştır.
10.11 Özet
• Sanal bellek, fiziksel belleği son derece geniş tek biçimli bir depolama dizisine
soyutlar. • Sanal belleğin faydaları şunları içerir: (1) bir program fiziksel bellekten
daha büyük olabilir, (2) bir programın tamamen bellekte olması gerekmez, (3) işlemler
belleği paylaşabilir ve (4) işlemler daha verimli bir şekilde oluşturulabilir. • Talep
sayfalama, sayfaların yalnızca program yürütme sırasında talep edildiğinde
yüklendiği bir tekniktir. Asla talep edilmeyen sayfalar bu nedenle asla belleğe
yüklenmez. • Halihazırda bellekte olmayan bir sayfaya erişildiğinde bir sayfa hatası
oluşur. Sayfa, destek deposundan bellekte uygun bir sayfa çerçevesine
getirilmelidir.
• Yazma üzerine kopyalama, bir alt işlemin ebeveyni ile aynı adres alanını paylaşmasına
izin verir. Alt süreç veya üst süreç bir sayfayı yazarsa (değiştirirse), sayfanın bir
kopyası yapılır.
• Kullanılabilir bellek azaldığında, bir sayfa değiştirme algoritması, yeni bir sayfayla
değiştirmek için bellekteki mevcut bir sayfayı seçer. Sayfa değiştirme
algoritmaları FIFO, optimal ve LRU'yu içerir. Saf LRU algoritmalarının uygulanması
pratik değildir ve çoğu sistem bunun yerine LRU yaklaşımı algoritmalarını
kullanır.
daha fazla zaman harcadığında meydana gelir. • Bir yer, birlikte aktif olarak kullanılan
bir dizi sayfayı temsil eder. Bir süreç yürütülürken yerellikten yerelliğe doğru
hareket eder. Bir çalışma kümesi, yerelliğe dayalıdır ve bir işlem tarafından şu
anda kullanımda olan sayfalar kümesi olarak tanımlanır.
Alıştırmalar 441
Machine Translated by Google
• Bellek sıkıştırma, birkaç sayfayı tek bir sayfaya sıkıştıran bir bellek yönetimi tekniğidir.
Sıkıştırılmış bellek, sayfalamaya bir alternatiftir ve sayfalamayı desteklemeyen mobil
sistemlerde kullanılır.
• Çekirdek belleği, kullanıcı modu işlemlerinden farklı şekilde tahsis edilir; değişen
boyutlarda bitişik parçalar halinde tahsis edilmiştir. Çekirdek belleği tahsis
etmek için iki yaygın teknik şunlardır: (1) buddy sistemi ve (2) levha tahsisi. • TLB
erişimi, TLB'den erişilebilen bellek miktarını ifade eder ve TLB'deki giriş sayısının
sayfa boyutuyla çarpımına eşittir. TLB erişimini artırmaya yönelik bir teknik ,
sayfaların boyutunu artırmaktır. • Linux, Windows ve Solaris, diğer özelliklerin
yanı sıra isteğe bağlı sayfalama ve yazma üzerine kopyalamayı kullanarak sanal
belleği benzer şekilde yönetir. Her sistem ayrıca , saat algoritması olarak bilinen
bir LRU yaklaşımı varyasyonu kullanır .
Alıştırmalar
10.1 Hangi durumlarda sayfa hataları oluşur? Bir sayfa hatası oluştuğunda işletim
sistemi tarafından gerçekleştirilen eylemleri açıklayın.
10.2 m çerçeveli (başlangıçta tamamı boş) bir işlem için bir sayfa referans dizginiz
olduğunu varsayın . Sayfa referans dizesinin uzunluğu p'dir ve içinde n
farklı sayfa numarası bulunur. Herhangi bir sayfa değiştirme algoritması
için şu soruları yanıtlayın: a. Sayfa hatası sayısının alt sınırı nedir? b. Sayfa
hatası sayısının üst sınırı nedir?
c. Optimum değiştirme
d. İkinci şans değiştirme
10.4 Bir işletim sistemi, disk belleğine alınmış bir sanal belleği destekler. Merkezi
işlemcinin çevrim süresi 1 mikrosaniyedir. Mevcut sayfadan farklı bir sayfaya
erişmek için ek 1 mikrosaniye maliyeti vardır. Sayfalar 1.000 kelimeye sahiptir
ve çağrı cihazı dakikada 3.000 devirde dönen ve saniyede 1 milyon kelime
aktaran bir tamburdur. Sistemden aşağıdaki istatistiksel ölçümler elde
edildi:
• Yürütülen tüm talimatların yüzde biri, aşağıdakilerden başka bir sayfaya erişti:
geçerli sayfa.
• Başka bir sayfaya erişen talimatların yüzde 80'i zaten bellekte bulunan bir
sayfaya erişti.
442 Bölüm
Machine Translated by Google 10 Sanal Bellek
• Yeni bir sayfa gerektiğinde değiştirilen sayfa değiştirildi
Zamanın yüzde 50'si.
10.5 12-bit sanal ve fiziksel adresleri ve 256-byte sayfaları olan bir sistem için sayfa
tablosunu düşünün.
0 -
1 2
2 C
3 A
4 -
5 4
6 3
7 -
8 B
9 0
• 9EF
• 111
• 700
• 0FF
burada A[0][0], sayfa boyutu 200 olan bir disk belleği sisteminde 200
konumundadır. Matrisi yöneten küçük bir işlem, sayfa 0'da bulunur (0 ila 199
konumları). Böylece, her talimat getirme, sayfa 0'dan olacaktır.
Üç sayfa çerçevesi için, aşağıdaki dizi başlatma döngüleri tarafından kaç
sayfa hatası üretilir? LRU değiştirmeyi kullanın ve
Alıştırmalar 443
Machine Translated by Google
1, 2, 3, 4, 2, 1, 5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6.
Aşağıdaki değiştirme algoritmaları için bir, iki, üç, dört, beş, altı ve yedi
çerçeve varsayıldığında kaç sayfa hatası oluşur?
Tüm çerçevelerin başlangıçta boş olduğunu unutmayın, bu nedenle ilk benzersiz
sayfalarınızın her biri bir hataya mal olur.
değişimi • Optimum
değişim
7, 2, 3, 1, 2, 5, 3, 4, 6, 7, 7, 1, 0, 5, 4, 6, 2, 3, 0 , 1.
değişimi • Optimum
değişim
10.10 Bir referans biti gerektiren (ikinci şans değiştirme veya çalışma seti modeli
gibi) bir çağrı algoritması kullanmak istediğinizi, ancak donanımın bir tane
sağlamadığını varsayalım. Donanım tarafından sağlanmasa bile bir referans
bitini nasıl simüle edebileceğinizi çizin veya bunun neden mümkün
olmadığını açıklayın. Mümkünse, maliyetin ne olacağını hesaplayın.
10.14 Taban ve limit kayıtlarını kullanan bir makine için bir işletim sistemimiz var,
ancak makineyi bir sayfa tablosu sağlayacak şekilde değiştirdik.
Sayfa tablosu, taban ve limit kayıtlarını simüle etmek için ayarlanabilir mi?
Nasıl olabilir veya neden olamaz?
bibliyografya
[Carr ve Hennessy (1981)] WR Carr ve JL Hennessy, “WSClock—Sanal Bellek Yönetimi için Basit
ve Etkili Algoritma”, İşletim Sistemleri İlkeleri Üzerine ACM Sempozyumu Bildirileri (1981),
sayfa 87–95.
[Denning (1968)] PJ Denning, “TheWorking Set Model for Program Behavior”, Communications
of the ACM, Cilt 11, Sayı 5 (1968), sayfa 323-333.
[McDougall ve Mauro (2007)] R. McDougall ve J. Mauro, Solaris Internals, İkinci Baskı, Prentice
Hall (2007).
Machine Translated by Google
bibliyografya 445
[McKusick et al. (2015)] MK McKusick, GV Neville-Neil ve RNM Wat son, FreeBSD UNIX
İşletim Sisteminin Tasarımı ve Uygulanması –İkinci
Baskı, Pearson (2015).
10.15 Bir programın sanal bellekte bir adrese başvurduğunu varsayın. Aşağıdakilerin her birinin
meydana gelebileceği bir senaryo tanımlayın. (Böyle bir senaryo oluşamıyorsa, nedenini
açıklayın.) • Sayfa hatası olmadan TLB eksik • Sayfa hatasıyla TLB eksik • Sayfa hatası
10.16 Bir iş parçacığının hazır olduğu ve programlanmayı beklediği, işlemcide çalıştığı veya
engellendiği (örneğin, G/Ç'yi bekliyor) olduğu iş parçacığı durumlarının basitleştirilmiş
bir görünümü hazır, çalışıyor ve engellendi .
hazır
engellendi koşma
a. Bir sayfa hatasına neden olursa iş parçacığı durumu değiştirir mi? Eğer öyleyse,
hangi duruma değişecek?
b. Sayfa tablosunda çözülen bir TLB hatası oluşturursa iş parçacığı durumu değiştirir
mi? Eğer öyleyse, hangi duruma değişecek?
c. Sayfa tablosunda bir adres referansı çözülürse iş parçacığı durumu değişir mi?
Eğer öyleyse, hangi duruma değişecek?
a. Bir süreç yürütmeye ilk başladığında, sayfa hatası oranını nasıl tanımlarsınız?
10.18 Aşağıda, 12 bit sanal ve fiziksel adresleri ve 256 baytlık sayfaları olan bir sistem için bir
sayfa tablosu yer almaktadır. Boş sayfa çerçeveleri 9, F, D sırasına göre tahsis edilecektir .
Bir sayfa çerçevesi için tire işareti, sayfanın bellekte olmadığını gösterir.
Egzersizler EX-36
Machine Translated by Google
0 0x4
1 0xB
2 0xA
3 -
4 -
5 0x2
6 -
7 0x0
8 0xC
9 0x1
• 0x2A1
• 0x4E6
• 0x94A
• 0x316
10.20 Belirli bir bilgisayar, kullanıcılarına 232 baytlık bir sanal bellek alanı sağlar.
Bilgisayarın 222 bayt fiziksel belleği vardır. Sanal bellek, sayfalama yoluyla
uygulanır ve sayfa boyutu 4.096 bayttır.
Bir kullanıcı işlemi sanal 11123456 adresini oluşturur. Sistemin ilgili fiziksel
konumu nasıl oluşturduğunu açıklayın. Yazılım ve donanım işlemlerini ayırt
eder.
10.21 İsteğe bağlı bir belleğimiz olduğunu varsayalım. Sayfa tablosu kayıtlarda
tutulur. Boş bir çerçeve varsa veya değiştirilen sayfa değiştirilmezse bir
sayfa hatasına hizmet vermek 8 milisaniye, değiştirilen sayfa değiştirilirse
20 milisaniye sürer. Bellek erişim süresi 100 nanosaniyedir.
10.22 16 bit sanal ve fiziksel adresleri ve 4.096 bayt sayfaları olan bir sistem için sayfa
tablosunu düşünün.
EX-37
Machine Translated by Google
0 9 0
1 - 0
2 10 0
3 15 0
4 6 0
5 13 0
6 8 0
7 12 0
8 7 0
9 - 0
10 5 0
11 4 0
12 1 0
13 0 0
14 - 0
15 2 0
Sayfa referans alındığında, bir sayfanın referans biti 1'e ayarlanır. Periyodik
olarak, bir iş parçacığı referans bitinin tüm değerlerini sıfırlar. Sayfa çerçevesi
için kısa çizgi, sayfanın bellekte olmadığını gösterir.
Sayfa değiştirme algoritması yerelleştirilmiş LRU'dur ve tüm sayılar ondalık
olarak verilmiştir.
• 0x621C
• 0xF0A3
• 0xBC1A
• 0x5BAA
• 0x0BA1
10.23 Bir sayfa hatası oluştuğunda, sayfanın diskten fiziksel belleğe alınmasını beklerken
sayfayı isteyen işlem bloke etmelidir. Beş kullanıcı düzeyinde iş parçacığına
sahip bir işlem olduğunu ve kullanıcı iş parçacıklarının çekirdek iş parçacıklarına
eşlenmesinin bire bir olduğunu varsayalım. Eğer
Egzersizler EX-38
Machine Translated by Google
bir kullanıcı iş parçacığı yığınına erişirken bir sayfa hatasına neden olur, aynı
işleme ait diğer kullanıcı iş parçacıkları da sayfa hatasından etkilenir mi -
yani, hata veren sayfanın belleğe alınmasını da beklemeleri gerekir mi?
Açıklamak.
10.24 Aşağıdaki sayfa referans dizileri için (1) FIFO, (2) LRU ve (3) optimal (OPT)
değiştirme algoritmalarını uygulayın:
• 2, 6, 9, 2, 4, 2, 1, 7, 3, 0, 5, 2, 1, 2, 9, 5, 7, 3, 8, 5
• 0, 6, 3, 0, 2, 6, 3, 5, 2, 4, 1, 3, 0, 6, 1, 4, 2, 3, 5, 7
• 3, 1, 4, 2, 5, 4, 1, 3, 5, 2, 0, 1, 1, 0, 2, 3, 4, 5, 0, 1
• 4, 2, 1, 7, 9, 8, 3, 5, 2, 6, 8, 1, 0, 7, 2, 4, 1, 3, 5, 8
• 0, 1, 2, 3, 4, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 4, 3, 2, 1, 0
Üç çerçeveli talep çağrısını varsayan her algoritma için sayfa hatası sayısını
belirtin.
10.27 En sık kullanılan (MFU) sayfa değiştirme algoritmasının, en son kullanılan (LRU)
sayfa değiştirme algoritmasından daha az sayfa hatası ürettiği durumları
tartışın . Bunun tersinin hangi koşullar altında geçerli olduğunu da tartışın.
10.28 KHIE ("k-hi" olarak telaffuz edilir) işletim sistemi, yerleşik sayfalar için bir FIFO
değiştirme algoritması ve son kullanılan sayfalardan oluşan bir serbest
çerçeve havuzu kullanır. Serbest çerçeve havuzunun LRU değiştirme ilkesi
kullanılarak yönetildiğini varsayın . Aşağıdaki soruları cevaplayın:
a. Bir sayfa hatası oluşursa ve sayfa serbest çerçeve havuzunda yoksa, yeni
istenen sayfa için boş alan nasıl oluşturulur?
c. Yerleşik sayfa sayısı bire ayarlanırsa sistem neye göre dejenere olur?
10.29 Aşağıdaki zaman ölçümlü kullanımlara sahip bir talep çağrı sistemi düşünün:
Aşağıdakilerin her biri için CPU kullanımını iyileştirip iyileştirmeyeceğini (veya artırma
olasılığının yüksek olduğunu) belirtin. Cevaplarınızı açıklayın.
f. Birden çok denetleyiciyle daha hızlı bir sabit disk veya birden çok denetleyici kurun
sabit diskler.
10.30 Küçük sayfa hatalarının çözülmesinin neden ana sayfa hatalarından daha az zaman aldığını açıklayın
hatalar.
10.31 Mobil cihazlar için işletim sistemlerinde sıkıştırılmış belleğin neden kullanıldığını açıklayın.
10.32 Bir makinenin, tek seviyeli dolaylı adresleme şemasını kullanarak bellek konumlarına
erişebilen talimatlar sağladığını varsayalım. Bir programın tüm sayfaları o anda yerleşik
olmadığında ve programın ilk talimatı dolaylı bir bellek yükleme işlemi olduğunda hangi
sayfa hataları dizisi oluşur? İşletim sistemi işlem başına çerçeve ayırma tekniğini
kullandığında ve bu işleme yalnızca iki sayfa ayrıldığında ne olur?
34
32
30
28
26
24
22
20
18
(X)
uygulama vakti
EX-41
b. Dört sayfa çerçeveli aşağıdaki referans dizesi için algoritmanız için kaç
sayfa hatası oluşuyor?
1, 2, 3, 4, 5, 3, 4, 1, 6, 7, 8, 7, 8, 9, 7, 8, 9, 5, 4, 5, 4, 2.
10.36 Ortalama erişim ve aktarım süresi 20 milisaniye olan bir çağrı diskine sahip bir
talep çağrı sistemi düşünün. Adresler, bellek erişimi başına 1 mikrosaniye
erişim süresiyle ana bellekteki bir sayfa tablosu aracılığıyla çevrilir. Böylece,
sayfa tablosu aracılığıyla her bir bellek referansı iki erişim alır. Bu süreyi
iyileştirmek için, sayfa tablosu girişi ilişkisel bellekteyse, erişim süresini bir
bellek referansına indiren bir ilişkisel bellek ekledik.
10.38 Bir işlemin, biri verileri, diğeri kodu temsil eden iki çalışma kümesine sahip olması
mümkün müdür? Açıklamak.
10.39 Çalışma kümesi modelinde çalışma kümesi penceresini tanımlamak için kullanılan
Δ parametresini göz önünde bulundurun. Δ düşük bir değere ayarlandığında,
sayfa hatası sıklığı ve sistemde o anda yürütülmekte olan etkin (askıya
alınmamış) işlemlerin sayısı üzerindeki etkisi nedir? Δ çok yüksek bir değere
ayarlandığında etkisi nedir?
10.40 1.024 KB'lık bir segmentte, bellek, arkadaş sistemi kullanılarak tahsis edilir.
Şekil 10.26'yı kılavuz olarak kullanarak, aşağıdaki bellek isteklerinin nasıl tahsis
edildiğini gösteren bir ağaç çizin:
• 5 KB isteyin •
135 KB isteyin. • 14
KB isteyin . • 3 KB
isteyin .
Egzersizler EX-42
Machine Translated by Google
• 12 KB isteyin .
• 5 KB bırakın .
• 14 KB yayınlayın.
• 12 KB yayınlayın.
10.41 Bir sistem, kullanıcı düzeyinde ve çekirdek düzeyinde iş parçacıkları için destek
sağlar. Bu sistemdeki eşleme bire birdir (her kullanıcı iş parçacığı için karşılık
gelen bir çekirdek iş parçacığı vardır). Çok iş parçacıklı bir süreç (a) tüm süreç
için bir çalışma kümesinden mi yoksa (b) her bir iş parçacığı için bir çalışma
kümesinden mi oluşur? Açıklamak
10.42 Döşeme tahsisi algoritması, her farklı nesne türü için ayrı bir önbellek kullanır. Nesne
türü başına bir önbellek olduğunu varsayarak, bu şemanın neden birden çok
CPU ile iyi ölçeklenmediğini açıklayın. Bu ölçeklenebilirlik sorununu çözmek için
ne yapılabilir?
10.43 Farklı boyutlardaki sayfaları süreçlerine tahsis eden bir sistem düşünün.
Böyle bir sayfalama düzeninin avantajları nelerdir? Bu işlevselliği sağlamak için
sanal bellek sisteminde hangi değişikliklere ihtiyaç duyulur?
Machine Translated by Google
Programlama Sorunları
10.44 Bölüm 10.4'te sunulan FIFO, LRU ve optimal (OPT) sayfa değiştirme
algoritmalarını uygulayan bir program yazın . Programınızın başlangıçta
sayfa numaralarının 0 ile 9 arasında olduğu rastgele bir sayfa referansı
dizisi oluşturmasını sağlayın. Rastgele sayfa referansını her algoritmaya
uygulayın ve her algoritmanın neden olduğu sayfa hatalarının sayısını
kaydedin. Başlangıçta programa sayfa çerçevesi sayısını iletin.
Bu programı istediğiniz herhangi bir programlama dilinde uygulayabilirsiniz.
( Sanal bellek yöneticisi programlama projesinde yardımcı olması için FIFO
veya LRU uygulamanızı bulabilirsiniz .)
Programlama Projeleri
Özel
Programınız, mantıksal adresleri temsil eden birkaç 32 bit tam sayı içeren bir
dosyayı okuyacaktır. Ancak, yalnızca 16 bitlik adreslerle ilgilenmeniz gerekir, bu
nedenle her mantıksal adresin en sağdaki 16 bitini maskelemelisiniz.
Bu 16 bit (1) 8 bitlik bir sayfa numarasına ve (2) 8 bitlik bir sayfa kaymasına bölünür.
Bu nedenle, adresler aşağıdaki gibi yapılandırılmıştır:
sayfa
telafi etmek
numarası
31 1516 78 0
• 65.536 baytlık fiziksel bellek (256 çerçeve × 256 bayt çerçeve boyutu)
Machine Translated by Google
Programınız, Bölüm 9.3'te belirtildiği gibi bir TLB ve sayfa tablosu kullanarak
mantıksal adresleri fiziksel adreslere çevirecektir . İlk olarak mantıksal adresten
sayfa numarası çıkarılır ve TLB'ye başvurulur. TLB isabeti durumunda çerçeve
numarası TLB'den alınır . TLB ıskalanması durumunda sayfa tablosuna başvurulmalıdır.
İkinci durumda, ya sayfa tablosundan çerçeve numarası alınır ya da bir sayfa hatası
oluşur. Adres çeviri sürecinin görsel bir temsili:
sayfa
telafi etmek
numarası
sayfa çerçeve
numarası numarası
0
. 0 çerçeve 0
. TLB isabeti 1 çerçeve 1
. 2 çerçeve 2
.
15 çerçeve .
sayı
telafi etmek
.
TLB .
.
.
.
TLB özledim
.
.
sayfa
tablosu
BACKING STORE.bin dosyasını rastgele erişimli bir dosya olarak ele almanız
gerekecek, böylece dosyanın belirli konumlarını okumak için rastgele arayabilirsiniz. G/Ç
gerçekleştirmek için fopen(), fread(), fseek() ve fclose() dahil olmak üzere standart C
kitaplığı işlevlerini kullanmanızı öneririz .
Fiziksel belleğin boyutu, sanal adres alanının boyutuyla aynıdır—65,536 bayt—bu
nedenle bir sayfa hatası sırasında sayfa değiştirme konusunda endişelenmenize gerek
yoktur. Daha sonra, daha az miktarda fiziksel bellek kullanarak bu projede yapılan bir
değişikliği açıklayacağız; bu noktada, bir sayfa değiştirme stratejisi gerekecektir.
Test Dosyası
0 ile 65535 (sanal adres alanının boyutu) arasında değişen mantıksal adresleri temsil
eden tamsayı değerlerini içeren address.txt dosyasını sağlıyoruz. Programınız bu
dosyayı açacak, her bir mantıksal adresi okuyacak ve onu karşılık gelen fiziksel adresine
çevirecek ve fiziksel adreste imzalı baytın değerini çıkaracaktır.
Nasıl Başlanır?
İlk olarak, sayfa numarası ve ofset tabanlı olarak ayıklayan basit bir program yazın.
üzerinde:
sayfa
telafi etmek
numarası
31 1516 78 0
Belki de bunu yapmanın en kolay yolu, bit maskeleme ve bit kaydırma için operatörleri
kullanmaktır. Sayfa numarasını ve bir tamsayıdan ofseti doğru bir şekilde belirledikten
sonra, başlamaya hazırsınız demektir.
Başlangıçta TLB'yi atlamanızı ve yalnızca bir sayfa tablosu kullanmanızı öneririz .
Sayfa tablonuz düzgün çalıştığında TLB'yi entegre edebilirsiniz . Adres çevirisinin TLB
olmadan da çalışabileceğini unutmayın ; TLB sadece daha hızlı hale getirir. TLB'yi
uygulamaya hazır olduğunuzda, yalnızca on altı girişi olduğunu hatırlayın, bu nedenle
tam bir TLB'yi güncellediğinizde bir değiştirme stratejisi kullanmanız gerekecektir .
TLB'nizi güncellemek için bir FIFO veya bir LRU politikası kullanabilirsiniz .
./a.out adresleri.txt
Programınız 0'dan 65535'e kadar 1000 mantıksal adres içeren address.txt dosyasını
okuyacaktır. Programınız, her mantıksal adresi fiziksel bir adrese çevirecek ve doğru
fiziksel adreste saklanan imzalı baytın içeriğini belirleyecektir . (C dilinde char veri
türünün bir bayt depolama alanı kapladığını hatırlayın, bu nedenle char değerlerini
kullanmanızı öneririz .)
P-54 Bölüm
Machine Translated by Google 10 Sanal Bellek
Programınız aşağıdaki değerlerin çıktısını almaktır:
Sayfa Değiştirme
Şimdiye kadar, bu proje fiziksel belleğin sanal adres alanı ile aynı boyutta olduğunu
varsaymıştır. Pratikte, fiziksel bellek tipik olarak bir sanal adres alanından çok daha
küçüktür. Projenin bu aşaması artık 256 yerine 128 sayfa çerçeveli daha küçük bir
fiziksel adres alanı kullanıldığını varsayar. Bu değişiklik, programınızı, boş sayfa
çerçevelerini takip edecek şekilde değiştirmeyi ve ayrıca FIFO veya Boş bellek
olmadığında sayfa hatalarını çözmek için LRU (Bölüm 10.4).
Machine Translated by Google
Machine Translated by Google
Beşinci Bölüm
Depolamak
Yönetmek
Bilgisayar sistemleri, dosyaları ve verileri kalıcı olarak depolamak için yığın depolama
sağlamalıdır. Modern bilgisayarlar, hem sabit diskleri hem de kalıcı bellek aygıtlarını kullanarak
yığın depolamayı ikincil depolama olarak uygular.
İkincil depolama aygıtları birçok açıdan farklılık gösterir. Bazıları bir seferde bir karakter,
bazıları ise bir karakter bloğu aktarır. Bazılarına yalnızca sırayla, bazılarına ise rastgele
erişilebilir. Bazıları verileri senkronize olarak, bazıları ise asenkron olarak aktarır. Bazıları
adanmış, bazıları ortak. Salt okunur veya okuma-yazma olabilirler. Hızları büyük ölçüde farklılık
gösterse de, birçok yönden bilgisayarın en yavaş ana bileşenidir.
11 BÖLÜM
Yığın Bellek
Yapı
Bu bölümde, bir bilgisayarın kalıcı depolama sistemi olan yığın depolamanın nasıl
yapılandırıldığını tartışacağız. Modern bilgisayarlardaki ana yığın depolama
sistemi, genellikle sabit disk sürücüleri (HDD) ve kalıcı bellek (NVM) aygıtları
tarafından sağlanan ikincil depolamadır. Bazı sistemler ayrıca genellikle manyetik
bant, optik diskler ve hatta bulut depolamadan oluşan daha yavaş, daha büyük,
üçüncül depolamaya sahiptir.
Modern bilgisayar sistemlerinde en yaygın ve önemli depolama aygıtları
HDD'ler ve NVM aygıtları olduğundan, bu bölümün büyük kısmı bu iki depolama
türünü tartışmaya ayrılmıştır. Önce fiziksel yapılarını tanımlıyoruz. Ardından,
performansı en üst düzeye çıkarmak için G/Ç'lerin sırasını programlayan zamanlama
algoritmalarını ele alıyoruz . Ardından, aygıt biçimlendirmesini ve önyükleme
bloklarının, hasarlı blokların ve takas alanının yönetimini tartışacağız. Son olarak,
RAID sistemlerinin yapısını inceliyoruz .
Birçok yığın depolama türü vardır ve tartışma tüm türleri içerdiğinde, genel
geçici olmayan depolama (NVS) terimini kullanırız veya depolama "sürücüleri"
hakkında konuşuruz. HDD'ler ve NVM cihazları gibi belirli cihazlar uygun şekilde
belirtilir.
BÖLÜM HEDEFLERİ
Modern bilgisayarlar için ikincil depolamanın büyük kısmı, sabit disk sürücüleri
(HDD'ler) ve kalıcı bellek (NVM) aygıtları tarafından sağlanır. Bu bölümde,
449
Machine Translated by Google
t izle mil
kol montajı
sektör s
okuma-yazma
silindir c
kafası
servis tabağı
kol
rotasyon
Kavramsal olarak, HDD'ler nispeten basittir (Şekil 11.1). Her disk tabağı , CD gibi
düz dairesel bir şekle sahiptir . Ortak plaka çapları 1,8 ila 3,5 inç arasında
değişir. Bir tabağın iki yüzeyi manyetik bir malzeme ile kaplanmıştır.
Bilgileri manyetik olarak plakalara kaydederek depolarız ve plakalardaki manyetik
deseni algılayarak bilgileri okuruz.
Her tabağın her yüzeyinin hemen üzerinde bir okuma-yazma kafası “uçar”.
Kafalar, tüm kafaları bir birim olarak hareket ettiren bir disk koluna bağlanmıştır .
Bir tabağın yüzeyi mantıksal olarak sektörlere ayrılan dairesel parçalara
bölünmüştür . Belirli bir kol pozisyonundaki palet seti bir silindiri oluşturur. Bir
disk sürücüsünde binlerce eş merkezli silindir olabilir ve her iz yüzlerce sektör
içerebilir. Her sektörün sabit bir boyutu vardır ve en küçük aktarım birimidir.
Sektör boyutu, 2010 yılına kadar genellikle 512 bayttı.
Bu noktada birçok üretici 4KB sektörlerine geçiş yapmaya başlıyor. Ortak disk
sürücülerinin depolama kapasitesi gigabayt ve terabayt cinsinden ölçülür.
Kapağı çıkarılmış bir disk sürücüsü Şekil 11.2'de gösterilmiştir.
Bir disk sürücü motoru onu yüksek hızda döndürür. Çoğu sürücü, dakikada
dönüş sayısı (RPM) cinsinden belirtilen saniyede 60 ila 250 kez döner . Ortak
sürücüler 5.400, 7.200, 10.000 ve 15.000 RPM'de döner. Bazı sürücüler
kullanılmadığında kapanır ve bir G/Ç isteği alındığında açılır . Dönme hızı,
aktarım hızlarıyla ilgilidir. Aktarım hızı , sürücü ile bilgisayar arasındaki veri
akışının hızıdır. Diğer bir performans yönü, konumlandırma süresi veya rastgele
erişim süresi, iki bölümden oluşur: disk kolunu istenen silindire hareket ettirmek
için gerekli süre, arama süresi olarak adlandırılır ve bunun için gerekli süre.
Machine Translated by Google
451
11.1 Yığın Depolama Yapısına Genel Bakış
disk kafasına dönmesi istenen sektör, dönme gecikmesi olarak adlandırılır. Tipik
diskler saniyede onlarca ila yüzlerce megabayt veri aktarabilir ve arama süreleri ve
birkaç milisaniyelik dönme gecikmeleri vardır. Sürücü denetleyicisinde DRAM
arabelleklerine sahip olarak performansı artırırlar .
Disk kafası, hava veya helyum gibi başka bir gazdan oluşan son derece ince bir
yastık (mikron olarak ölçülür) üzerinde uçar ve kafanın disk yüzeyiyle temas etme
tehlikesi vardır. Disk plakaları ince bir koruyucu tabaka ile kaplansa da, kafa bazen
manyetik yüzeye zarar verir. Bu kazaya kafa çarpması denir . Bir kafa çarpması
normalde tamir edilemez; diskin tamamı değiştirilmelidir ve diskteki veriler başka bir
depolama birimine yedeklenmedikçe veya RAID korumalı değilse kaybolur. (RAID ,
Bölüm 11.8'de tartışılmaktadır.)
HDD'ler kapalı birimlerdir ve HDD'leri tutan bazı kasalar , sistemi veya depolama
kasasını kapatmadan bunların çıkarılmasına izin verir. Bu, bir sistemin belirli bir
zamanda bağlanabileceğinden daha fazla depolamaya ihtiyacı olduğunda veya
bozuk bir sürücüyü çalışan bir sürücüyle değiştirmek gerektiğinde yararlıdır. CD'ler,
DVD'ler ve Blu-ray diskler dahil olmak üzere diğer depolama ortamı türleri de çıkarılabilir .
Bilgi işlemin birçok yönüyle olduğu gibi, diskler için yayınlanan performans numaraları,
gerçek dünyadaki performans sayılarıyla aynı değildir. Örneğin , belirtilen transfer oranları
her zaman efektif transfer oranlarından daha yüksektir . Aktarım hızı, disk kafası tarafından
manyetik ortamdan bitlerin okunabileceği hız olabilir, ancak bu, blokların işletim sistemine
teslim edilme oranından farklıdır.
Machine Translated by Google
Kalıcı bellek (NVM) cihazlarının önemi artıyor. Basitçe tarif edildiğinde, NVM cihazları
mekanik olmaktan çok elektriklidir. En yaygın olarak, böyle bir cihaz, verileri
depolamak için kullanılan bir denetleyici ve flash NAND kalıp yarı iletken
yongalarından oluşur. İçeriğini kaybetmemesi için pil destekli DRAM gibi başka
NVM teknolojileri ve 3D XPoint gibi diğer yarı iletken teknolojileri vardır, ancak
bunlar çok daha az yaygındır ve bu nedenle bu kitapta tartışılmamaktadır.
tabanlı NVM , disk sürücüsü benzeri bir kapta sıklıkla kullanılır ve bu durumda buna
katı hal diski (SSD) denir (Şekil 11.3). Diğer durumlarda, bir USB sürücüsü (parmak
sürücü veya flash sürücü olarak da bilinir) veya bir DRAM çubuğu şeklini alır. Ayrıca
akıllı telefonlar gibi cihazlarda ana depolama olarak anakartlara yüzeye monte edilir.
Tüm formlarda, aynı şekilde hareket eder ve tedavi edilebilir. NVM cihazlarıyla ilgili
tartışmamız bu teknolojiye odaklanıyor.
NVM cihazları, hareketli parçaları olmadığı için HDD'lerden daha güvenilir olabilir ve
arama süresi veya dönme gecikmesi olmadığı için daha hızlı olabilir.
Ayrıca daha az güç tüketirler. Olumsuz tarafı, geleneksel sabit disklerden megabayt
başına daha pahalıdırlar ve daha büyük sabit disklerden daha az kapasiteye
sahiptirler. Ancak zamanla, NVM cihazlarının kapasitesi HDD kapasitesinden daha
hızlı arttı ve fiyatları daha hızlı düştü, bu nedenle kullanımları çarpıcı biçimde artıyor.
Aslında, SSD'ler ve benzeri cihazlar artık bazı dizüstü bilgisayarlarda onları daha
küçük, daha hızlı ve daha enerji verimli hale getirmek için kullanılmaktadır.
NVM aygıtları sabit disk sürücülerinden çok daha hızlı olabildiğinden, standart
veri yolu arabirimleri iş hacminde büyük bir sınırlamaya neden olabilir . Bazı NVM
cihazları, doğrudan sistem veri yoluna ( örneğin PCIe ) bağlanmak üzere
tasarlanmıştır. Bu teknoloji, bilgisayar tasarımının diğer geleneksel yönlerini de değiştiriyor.
Bazı sistemler bunu disk sürücülerinin doğrudan yerine geçmek için kullanırken, diğerleri
performansı optimize etmek için verileri manyetik diskler, NVM ve ana bellek arasında taşıyan
yeni bir önbellek katmanı olarak kullanır.
NAND yarı iletkenleri, kendi depolama ve güvenilirlik zorluklarını ortaya koyan bazı
özelliklere sahiptir. Örneğin, bir "sayfa" artışıyla (bir sektöre benzer) okunabilir ve yazılabilirler,
ancak verilerin üzerine yazılamaz - bunun yerine, önce NAND hücrelerinin silinmesi gerekir.
Birkaç sayfa boyutunda bir "blok" artışında meydana gelen silme, okumadan (en hızlı işlem) veya
yazmadan (okumaktan daha yavaş, ancak silmekten çok daha hızlı) çok daha fazla zaman alır.
Bu duruma yardımcı olan şey, NVM flash cihazlarının her kalıpta birçok veri yolu bulunan birçok
kalıptan oluşmasıdır, bu nedenle işlemler paralel olarak gerçekleşebilir (her biri bir veri yolu
kullanır). NAND yarı iletkenleri ayrıca her silme döngüsünde bozulur ve yaklaşık 100.000 program
silme döngüsünden sonra (belirli sayı ortama bağlı olarak değişir), hücreler artık verileri
tutmaz. Yazma aşınması ve hareketli parça olmaması nedeniyle NAND NVM'nin kullanım ömrü
yıl olarak değil, Günlük Sürücü Yazma Sayısı (DWPD) ile ölçülür.
Bu ölçü, sürücü arızalanmadan önce sürücü kapasitesinin günde kaç kez yazılabileceğidir.
Örneğin, 5 DWPD derecesine sahip 1 TB NAND sürücüsüne , garanti süresi boyunca hatasız
olarak günde 5 TB yazılması beklenir .
Bu sınırlamalar, birkaç iyileştirme algoritmasına yol açmıştır. Neyse ki, bunlar genellikle
NVM aygıt denetleyicisinde uygulanır ve işletim sistemiyle ilgili değildir. İşletim sistemi
mantıksal blokları okur ve yazar ve cihaz bunun nasıl yapıldığını yönetir. (Mantıksal bloklar
Bölüm 11.1.5'te daha ayrıntılı olarak tartışılmaktadır.) Bununla birlikte, NVM cihazlarının
çalışma algoritmalarına dayalı performans varyasyonları vardır, bu nedenle kontrolörün ne
yaptığına dair kısa bir tartışma garanti edilir.
fiziksel blok durumunu izler - yani hangi bloklar yalnızca geçersiz sayfalar içerir ve
bu nedenle silinebilir.
Şimdi bekleyen bir yazma isteği olan tam bir SSD düşünün. SSD dolu
olduğundan , tüm sayfalar yazılmıştır, ancak geçerli veri içermeyen bir blok olabilir.
Bu durumda, yazma işlemi silme işleminin gerçekleşmesini bekleyebilir ve ardından
yazma işlemi gerçekleşebilir. Ama ya ücretsiz blok yoksa? Tek tek sayfalar geçersiz
veriler içeriyorsa, yine de biraz boşluk olabilir. Bu durumda, çöp toplama meydana
gelebilir - iyi veriler diğer konumlara kopyalanabilir, silinebilecek blokları serbest
bırakabilir ve daha sonra yazmaları alabilir. Ancak, çöp toplama iyi verileri nerede
saklar? Bu sorunu çözmek ve yazma performansını iyileştirmek için NVM cihazı aşırı
provizyon kullanır. Cihaz, her zaman yazılabilecek bir alan olarak birkaç sayfa
(genellikle toplamın yüzde 20'si) olarak ayırır. Çöp toplama veya verilerin eski
sürümlerini geçersiz kılan yazma işlemleri tarafından tamamen geçersiz olan bloklar,
cihaz doluysa veya boş havuza geri döndürülürse silinir ve aşırı sağlama alanına
yerleştirilir.
Aşırı tedarik alanı, aşınma dengelemeye de yardımcı olabilir. Bazı bloklar tekrar
tekrar silinirse, diğerleri silinmezse, sık silinen bloklar diğerlerinden daha hızlı
yıpranır ve tüm cihazın ömrü, tüm blokların aynı anda yıpranmasına göre daha kısa
olur. Denetleyici, verileri daha az silinen bloklara yerleştirmek için çeşitli algoritmalar
kullanarak bundan kaçınmaya çalışır, böylece sonraki silmeler, daha fazla silinen
bloklar yerine bu bloklarda gerçekleşir ve tüm cihaz boyunca aşınmayı dengeler.
Veri koruma açısından, HDD'ler gibi, NVM cihazları, hataları tespit etmek ve mümkünse
düzeltmek için yazma sırasında verilerle birlikte hesaplanan ve saklanan ve verilerle birlikte
okunan hata düzeltme kodları sağlar.
(Hata düzeltme kodları Bölüm 11.5.1'de anlatılmıştır.) Bir sayfada sıklıkla düzeltilebilir
hatalar varsa, sayfa bozuk olarak işaretlenebilir ve sonraki yazmalarda kullanılmayabilir.
Genel olarak, HDD gibi tek bir NVM cihazı, okuma veya yazma isteklerini bozduğu
veya yanıtlayamadığı feci bir arızaya sahip olabilir. Bu durumlarda verilerin
kurtarılabilmesini sağlamak için RAID koruması kullanılır.
Yığın depolama yapısıyla ilgili bir bölümde geçici belleği tartışmak tuhaf görünebilir,
ancak DRAM sıklıkla bir yığın depolama aygıtı olarak kullanıldığı için haklıdır.
Spesifik olarak, RAM sürücüleri ( RAM diskleri de dahil olmak üzere birçok adla bilinir )
ikincil depolama gibi davranır ancak sistemin DRAM'inin bir bölümünü oluşturan ve
onu bir depolama alanıymış gibi sistemin geri kalanına sunan aygıt sürücüleri
tarafından oluşturulur. cihaz. Bu "sürücüler" ham blok aygıtları olarak kullanılabilir,
ancak daha yaygın olarak, standart dosya işlemleri için üzerlerinde dosya sistemleri
oluşturulur.
Bilgisayarlarda zaten ara belleğe alma ve önbelleğe alma vardır, bu nedenle
geçici veri depolama için DRAM'in başka bir kullanımının amacı nedir? Sonuçta,
DRAM geçicidir ve bir RAM sürücüsündeki veriler bir sistem çökmesine, kapanmasına
veya kapanmasına dayanmaz. Önbellekler ve arabellekler, programcı veya işletim
sistemi tarafından tahsis edilirken, RAM sürücüleri, kullanıcının (aynı zamanda programcının)
Machine Translated by Google
455
11.1 Yığın Depolama Yapısına Genel Bakış
MANYETİK BANTLAR
Manyetik bant , erken bir ikincil depolama ortamı olarak kullanıldı. Kalıcı olmasına ve büyük
miktarda veri tutabilmesine rağmen, erişim süresi ana bellek ve sürücülere kıyasla daha
yavaştır. Ayrıca, manyetik teybe rastgele erişim, HDD'lere rastgele erişimden yaklaşık bin kat
daha yavaştır ve SSD'lere rastgele erişimden yaklaşık yüz bin kat daha yavaştır, bu nedenle
bantlar ikincil depolama için pek kullanışlı değildir. Bantlar esas olarak yedekleme, seyrek
olarak kullanılan bilgilerin saklanması ve bir sistemden diğerine bilgi aktarımı için bir araç
olarak kullanılır.
Bir bant bir makarada tutulur ve bir okuma-yazma kafasının üzerinden sarılır veya geri
sarılır. Bir teyp üzerinde doğru noktaya hareket etmek dakikalar alabilir, ancak bir kez
yerleştirildiğinde, teyp sürücüleri HDD'lerle karşılaştırılabilir hızlarda veri okuyabilir ve yazabilir .
Teyp kapasiteleri, belirli bir teyp sürücüsü türüne bağlı olarak büyük ölçüde değişir ve
mevcut kapasiteler birkaç terabaytı aşar. Bazı teypler, etkin depolamayı iki katından daha
fazla artırabilen yerleşik sıkıştırmaya sahiptir. Bantlar ve sürücüleri genellikle 4, 8 ve 19
milimetre ve 1/4 ve 1/2 inç dahil olmak üzere genişliğe göre sınıflandırılır. Bazıları teknolojiye
göre isimlendirilir, örneğin LTO-6 (Şekil 11.5) ve SDLT.
standart dosya işlemlerini kullanarak geçici koruma için bellekteki veriler. Aslında, RAM
sürücüsü işlevi, bu tür sürücülerin tüm büyük işletim sistemlerinde bulunması için
yeterince kullanışlıdır. Linux'ta /dev/ram vardır, macOS'ta diskutil komutu bunları
oluşturur, Windows bunları üçüncü taraf araçlar aracılığıyla alır ve Solaris ve Linux
önyükleme sırasında bir RAM sürücüsü olan “tmpfs” türünde /tmp oluşturur.
RAM sürücüleri, yüksek hızlı geçici depolama alanı olarak kullanışlıdır. NVM cihazları
hızlı olmasına rağmen , DRAM çok daha hızlıdır ve RAM sürücülerine yapılan G/Ç
işlemleri , dosyaları ve içeriklerini oluşturmanın, okumanın, yazmanın ve silmenin en hızlı yoludur.
Birçok program, geçici dosyaları depolamak için RAM sürücüleri kullanır (veya bundan
faydalanabilir) . Örneğin, programlar bir RAM sürücüsünden dosya yazıp okuyarak
verileri kolayca paylaşabilir. Başka bir örnek için, Linux önyükleme sırasında , işletim
sisteminin depolama aygıtlarını anlayan bölümleri yüklenmeden önce sistemin diğer
bölümlerinin bir kök dosya sistemine ve içeriğine erişmesine izin veren geçici bir kök
dosya sistemi (initrd) oluşturur.
Machine Translated by Google
İkincil bir depolama aygıtı, bir bilgisayara sistem veri yolu veya bir G/Ç veri yolu ile bağlanır .
Gelişmiş teknoloji eki (ATA), seri ATA (SATA), eSATA, seri bağlı SCSI (SAS), evrensel seri veri yolu
(USB) ve fiber kanalı (FC) dahil olmak üzere çeşitli veri yolları mevcuttur . En yaygın bağlantı
yöntemi SATA'dır. NVM cihazları HDD'lerden çok daha hızlı olduğu için endüstri, NVM ekspres
(NVMe) adı verilen NVM cihazları için özel, hızlı bir arayüz oluşturdu .
NVMe , aygıtı doğrudan sistem PCI veri yoluna bağlayarak, diğer bağlantı yöntemlerine
kıyasla verimi artırır ve gecikmeyi azaltır.
Bir veri yolu üzerindeki veri aktarımları, denetleyiciler (veya ana bilgisayar veriyolu
adaptörleri (HBA) adı verilen özel elektronik işlemciler tarafından gerçekleştirilir ). Ana
bilgisayar denetleyicisi , veri yolunun bilgisayar ucundaki denetleyicidir. Her depolama
aygıtına bir aygıt denetleyicisi yerleştirilmiştir. Bir yığın depolama G/Ç işlemi gerçekleştirmek
için bilgisayar , Bölüm 12.2.1'de açıklandığı gibi , tipik olarak bellek eşlemeli G/Ç bağlantı
noktalarını kullanarak ana bilgisayar denetleyicisine bir komut yerleştirir. Ana bilgisayar
denetleyicisi daha sonra komutları mesajlar yoluyla aygıt denetleyicisine gönderir ve
denetleyici komutu gerçekleştirmek için sürücü donanımını çalıştırır. Aygıt denetleyicilerinde
genellikle yerleşik bir önbellek bulunur. Sürücüdeki veri aktarımı, önbellek ve depolama
ortamı arasında gerçekleşir ve ana bilgisayara yüksek elektronik hızlarda veri aktarımı,
DMA yoluyla önbellek ana bilgisayarı DRAM'ı arasında gerçekleşir.
Depolama aygıtları , mantıksal bloğun en küçük aktarım birimi olduğu büyük tek boyutlu
mantıksal blok dizileri olarak adreslenir. Her mantıksal blok, bir fiziksel sektör veya yarı
iletken sayfayla eşlenir. Tek boyutlu mantıksal blok dizisi, aygıtın sektörlerine veya
sayfalarına eşlenir. Sektör 0, örneğin , bir HDD'deki en dış silindirdeki ilk parçanın ilk
sektörü olabilir . Haritalama, sırayla bu iz boyunca, sonra o silindir üzerindeki diğer izler
boyunca ve daha sonra silindirlerin geri kalanı boyunca, en dıştan en içe doğru ilerler.
NVM için eşleme, çip, blok ve sayfanın bir demetinden (sonlu sıralı liste) bir dizi mantıksal
bloka kadardır. Mantıksal blok adresi (LBA) , algoritmalar için sektör, silindir, başlık demeti
veya çip, blok, sayfa demetinden daha kolaydır.
Bu eşlemeyi bir HDD'de kullanarak, en azından teoride, mantıksal bir blok numarasını
bir silindir numarasından, o silindir içindeki bir parça numarasından ve bu yoldaki bir
sektör numarasından oluşan eski tarz bir disk adresine dönüştürebiliriz. Pratikte bu çeviriyi
yapmak üç nedenden dolayı zordur.
İlk olarak, çoğu sürücüde bazı kusurlu sektörler bulunur, ancak eşleme, sürücünün
başka yerlerindeki yedek sektörleri değiştirerek bunu gizler. Mantıksal blok adresi sıralı
kalır, ancak fiziksel sektör konumu değişir. İkincisi, iz başına sektör sayısı bazı sürücülerde
sabit değildir. Üçüncüsü, disk üreticileri LBA'yı fiziksel adres eşlemesini dahili olarak
yönetir, bu nedenle mevcut sürücülerde LBA ve fiziksel sektörler arasında çok az ilişki
vardır . Bu fiziksel adres değişkenlerine rağmen, HDD'lerle ilgilenen algoritmalar,
mantıksal adreslerin nispeten fiziksel adreslerle ilişkili olduğunu varsayma eğilimindedir.
Yani, artan mantıksal adresler, artan fiziksel adres anlamına gelme eğilimindedir.
İkinci nedene daha yakından bakalım. Sabit doğrusal hız (CLV) kullanan ortamlarda,
iz başına bit yoğunluğu tekdüzedir. Bir iz diskin merkezinden ne kadar uzaksa, uzunluğu
o kadar büyük olur, dolayısıyla o kadar çok sektör olabilir.
Machine Translated by Google
tutmak. Dış bölgelerden iç bölgelere doğru hareket ettikçe iz başına sektör sayısı
azalır. En dıştaki bölgedeki izler, en içteki bölgedeki izlerden tipik olarak yüzde 40
daha fazla sektör tutar. Sürücü, kafanın altında hareket eden aynı veri hızını korumak
için kafa dıştan iç raylara hareket ettikçe dönüş hızını arttırır. Bu yöntem CD-ROM
ve DVD-ROM sürücülerinde kullanılır. Alternatif olarak, disk dönüş hızı sabit kalabilir;
bu durumda, veri hızını sabit (ve verilerin sürücüde nerede olursa olsun performansı
nispeten aynı) tutmak için bitlerin yoğunluğu iç izlerden dış izlere doğru azalır. Bu
yöntem sabit disklerde kullanılır ve sabit açısal hız (CAV) olarak bilinir.
Disk teknolojisi geliştikçe iz başına sektör sayısı artmaktadır ve bir diskin dış
bölgesi genellikle iz başına birkaç yüz sektöre sahiptir. Benzer şekilde, disk başına
silindir sayısı da artmaktadır; büyük disklerde on binlerce silindir bulunur.
Bir işletim sistemleri metninde ele alınması makul olandan daha fazla depolama
aygıtı türü olduğunu unutmayın. Örneğin, ana akım HDD'lerden daha yüksek
yoğunluğa ancak daha kötü performansa sahip "shingled manyetik kayıt" sabit
diskleri vardır (bkz. http://www.tomsitpro.com/articles/shingled-magnetic-recoding-
smr-101-basics,2- 933.html). Ayrıca NVM ve HDD teknolojisini içeren kombinasyon
cihazları veya NVM ve HDD cihazlarını HDD'den daha hızlı ancak NVM'den daha
düşük maliyetli bir depolama biriminde birleştirebilen birim yöneticileri (bkz. Bölüm
11.5) vardır . Bu aygıtlar, daha yaygın aygıtlardan farklı özelliklere sahiptir ve
performansı en üst düzeye çıkarmak için farklı önbelleğe alma ve zamanlama
algoritmalarına ihtiyaç duyabilir.
Bir işlem sürücüye veya sürücüden G/Ç'ye ihtiyaç duyduğunda , bir sistem çağrısı yapar
işletim sistemine. İstek, birkaç bilgi parçasını belirtir:
İstenen sürücü ve kontrolör mevcutsa, talep anında servise alınabilir. Sürücü veya
denetleyici meşgulse, yeni hizmet talepleri, o sürücü için bekleyen istekler kuyruğuna
yerleştirilir. Birçok işlemi olan bir çok programlı ming sistemi için, cihaz kuyruğunda çoğu
zaman bekleyen birkaç istek olabilir.
Baş aramalardan kaçınarak performansını optimize edebilen bir aygıta yönelik bir istek
kuyruğunun varlığı, aygıt sürücülerine sıra sıralaması yoluyla performansı artırma şansı
verir.
Geçmişte, HDD arabirimleri, ana bilgisayarın hangi parçayı ve hangi başlığı
kullanacağını belirlemesini gerektiriyordu ve disk zamanlama algoritmaları için çok çaba harcanıyordu.
Yüzyılın başından daha yeni sürücüler, yalnızca bu kontrolleri ana bilgisayara ifşa etmekle
kalmaz, aynı zamanda LBA'yı sürücü kontrolü altındaki fiziksel adreslerle eşler. Disk
zamanlamanın mevcut hedefleri arasında adalet, zamanlılık ve sürücüler sıralı G/Ç ile en iyi
performansı gösterdiğinden, sırayla görünen okumaları veya yazmaları gruplama gibi
optimizasyonlar yer alır . Bu nedenle, bazı zamanlama çabası hala yararlıdır. Birkaç disk
zamanlama algoritmasından herhangi biri kullanılabilir ve bunları daha sonra tartışacağız.
Modern sürücülerde kafa konumu ve fiziksel blok/silindir konumlarının mutlak bilgisinin
genellikle mümkün olmadığını unutmayın. Ancak kabaca bir tahmin olarak, algoritmalar
artan LBA'ların artan fiziksel adresler anlamına geldiğini ve birbirine yakın LBA'ların fiziksel
blok yakınlığına eşit olduğunu varsayabilir .
bu sırayla. Disk kafası başlangıçta silindir 53'teyse, toplam 640 silindir kafa hareketi için önce
53'ten 98'e, ardından 183, 37, 122, 14, 124, 65'e ve son olarak 67'ye hareket edecektir. Bu
çizelge Şekil 11.6'da gösterilmiştir.
122'den 14'e ve ardından 124'e vahşi salınım, bu programdaki sorunu göstermektedir.
37 ve 14 numaralı silindirlere yönelik taleplere birlikte, 122 ve 124'e yönelik taleplerden önce
veya sonra hizmet verilebilirse, toplam kafa hareketi önemli ölçüde azaltılabilir ve böylece
performans geliştirilebilir.
Örneklemek için örneğimize dönelim. 98, 183, 37, 122, 14, 124, 65 ve 67 silindirlerindeki
istekleri programlamak için SCAN uygulamadan önce şunu bilmemiz gerekir:
Machine Translated by Google
Dairesel SCAN (C-SCAN) zamanlaması , daha düzgün bir bekleme süresi sağlamak için
tasarlanmış bir SCAN çeşididir . SCAN gibi , C-SCAN da kafayı diskin bir ucundan diğer
ucuna hareket ettirerek yol boyunca taleplere hizmet eder. Ancak kafa diğer uca
ulaştığında, dönüş yolculuğunda herhangi bir istekte bulunmadan hemen diskin başına
döner.
Örneklemek için örneğimize dönelim. 98, 183, 37, 122, 14, 124, 65 ve 67
silindirlerindeki istekleri programlamak için C-SCAN uygulamadan önce , isteklerin
programlandığı kafa hareketinin yönünü bilmemiz gerekir.
İsteklerin, disk kolu 0'dan 199'a hareket ederken programlandığı ve ilk kafa pozisyonunun
tekrar 53 olduğu varsayıldığında, istek Şekil 11.8'de gösterildiği gibi sunulacaktır. C-
SCAN çizelgeleme algoritması , esasen silindirleri, son silindirden ilk silindire kadar saran
dairesel bir liste olarak ele alır.
Nadiren kullanıldıkları için bu kapsama dahil olmayan birçok disk zamanlama algoritması vardır.
Ancak işletim sistemi tasarımcıları hangisinin uygulanacağına nasıl karar verir ve dağıtımcılar
en iyi kullanmayı nasıl seçer? Herhangi bir özel istek listesi için, optimal bir geri alma sırası
tanımlayabiliriz, ancak optimal bir program bulmak için gereken hesaplama, SCAN'a göre
tasarrufları haklı çıkarmayabilir .
Bununla birlikte, herhangi bir zamanlama algoritmasında performans, büyük ölçüde
isteklerin sayısına ve türlerine bağlıdır. Örneğin, kuyruğun genellikle yalnızca bir
bekleyen isteği olduğunu varsayalım. Ardından, tüm zamanlama algoritmaları aynı
şekilde davranır, çünkü disk kafasını nereye taşıyacakları konusunda yalnızca bir
seçeneğe sahiptirler: hepsi FCFS zamanlaması gibi davranır.
SCAN ve C-SCAN , diske ağır yük yerleştiren sistemler için daha iyi performans
gösterir, çünkü aç kalma sorununa neden olma olasılıkları daha düşüktür. Yine de,
Linux'u son tarih zamanlayıcısını oluşturmaya iten açlık olabilir . Bu zamanlayıcı, ayrı
okuma ve yazma kuyrukları tutar ve işlemlerin okuma sırasında yazmadan daha büyük
olasılıkla bloke olması nedeniyle okuma önceliği verir. sıralar
LBA sırasına göre sıralanır , esasen C-SCAN uygulanır. Tüm G/Ç istekleri, bu LBA
siparişinde toplu olarak gönderilir. Son teslim tarihi dört sıra tutar: biri LBA'ya ve
diğeri FCFS'ye göre sıralanmış iki okuma ve iki yazma . Her gruptan sonra, FCFS
kuyruklarında yapılandırılmış bir yaştan daha eski istekler olup olmadığını kontrol
eder (varsayılan olarak 500 ms). Bu durumda , bir sonraki G/Ç grubu için bu isteği
içeren LBA kuyruğu (okuma veya yazma) seçilir.
Son G/Ç zamanlayıcısı, Linux RedHat 7 dağıtımında varsayılandır, ancak RHEL 7
ayrıca iki tane daha içerir. NOOP , NVM cihazları gibi hızlı depolama kullanan CPU'ya
bağlı sistemler için tercih edilir ve Tamamen Adil Kuyruk zamanlayıcısı (CFQ) SATA
sürücüleri için varsayılandır . CFQ üç sıra tutar (bunları LBA düzeninde sıralanmış
halde tutmak için eklemeli sıralama ile ): gerçek zamanlı, en iyi çaba (varsayılan) ve
boşta. Her birinin diğerlerine göre özel önceliği vardır, bu sırayla, açlıktan ölme
olasılığı vardır. Bir işlemin yakında daha fazla G/Ç isteği yayınlayıp yayınlamayacağını
tahmin ederek geçmiş verileri kullanır. Bunu belirlerse, sıradaki diğer istekleri yok
sayarak yeni G/Ç'yi beklerken boşta kalır. Bu, işlem başına depolama G/Ç isteklerinin
referans konumunu varsayarak arama süresini en aza indirmek içindir . Bu
programlayıcıların ayrıntıları https://access.redhat.com/site/documentation/en-US/
Red Hat Enterprise Linux/7/html/Performance Tuning Guide/index.html adresinde bulunabilir .
NVM cihazları, HDD kafa aramalarının en aza indirildiği ve ortama veri okuma
ve yazmanın vurgulandığı ham sıralı geçiş için çok daha az avantaj sunar. Bu
durumlarda, okumalar için, iki tür cihazın performansı, NVM cihazları için eşdeğerden
bir büyüklük sırasına kadar değişebilir . NVM'ye yazmak okumaktan daha yavaştır, bu
da avantajı azaltır. Ayrıca, HDD'ler için yazma performansı cihazın ömrü boyunca
tutarlıyken, NVM cihazları için yazma performansı, cihazın ne kadar dolu olduğuna
(çöp toplama ve aşırı provizyon ihtiyacını hatırlayın) ve ne kadar "yıprandığına" bağlı
olarak değişir. Birçok silme döngüsü nedeniyle ömrünün sonuna yaklaşan bir NVM
cihazı, genellikle yeni bir cihazdan çok daha kötü performansa sahiptir.
Machine Translated by Google
Hata düzeltme kodu ( ECC) yalnızca sorunu algılamakla kalmaz, aynı zamanda
düzeltir. Düzeltme, algoritmalar ve ekstra depolama miktarları kullanılarak yapılır.
Kodlar, ne kadar ekstra depolama alanına ihtiyaç duyduklarına ve kaç tane hatayı
düzeltebileceklerine bağlı olarak değişir. Örneğin, disk sürücüleri sektör başına ECC kullanır ve
Machine Translated by Google
sayfa başına flash sürücüler ECC. Normal G/Ç sırasında denetleyici bir sektör/sayfa
veri yazdığında , ECC , yazılan verilerdeki tüm baytlardan hesaplanan bir değerle
yazılır. Sektör/sayfa okunduğunda, ECC yeniden hesaplanır ve saklanan değerle
karşılaştırılır. Depolanan ve hesaplanan sayılar farklıysa, bu uyumsuzluk verilerin
bozulduğunu ve depolama ortamının bozuk olabileceğini gösterir (Bölüm 11.5.3).
ECC hata düzeltiyor çünkü sadece birkaç bit veri bozulmuşsa, denetleyicinin hangi
bitlerin değiştiğini belirlemesini ve doğru değerlerinin ne olması gerektiğini
hesaplamasını sağlamak için yeterli bilgi içeriyor . Daha sonra kurtarılabilir bir
yazılım hatası bildirir. Çok fazla değişiklik meydana gelirse ve ECC hatayı düzeltemezse,
düzeltilemez bir sabit hata sinyali verilir. Denetleyici, bir sektör veya sayfa
okunduğunda veya yazıldığında ECC işlemini otomatik olarak yapar .
Yeni bir depolama aygıtı boş bir levhadır: sadece bir manyetik kayıt malzemesi tabağı
veya bir dizi başlatılmamış yarı iletken depolama hücresidir. Bir depolama aygıtının
verileri depolamadan önce, denetleyicinin okuyabileceği ve yazabileceği sektörlere
bölünmesi gerekir. NVM sayfaları başlatılmalı ve FTL oluşturulmalıdır. Bu işleme
düşük seviyeli biçimlendirme veya fiziksel biçimlendirme denir . Düşük seviyeli
biçimlendirme, cihazı her depolama konumu için özel bir veri yapısıyla doldurur. Bir
sektör veya sayfanın veri yapısı tipik olarak bir başlık, bir veri alanı ve bir fragmandan
oluşur. Başlık ve fragman, sektör/sayfa numarası ve hata algılama veya düzeltme
kodu gibi denetleyici tarafından kullanılan bilgileri içerir.
Çoğu sürücü, üretim sürecinin bir parçası olarak fabrikada düşük düzeyde
biçimlendirilir. Bu biçimlendirme, üreticinin cihazı test etmesine ve mantıksal blok
numaralarından ortamdaki hatasız sektörlere veya sayfalara eşleştirmeyi başlatmasına
olanak tanır. Genellikle 512 bayt ve 4KB gibi birkaç sektör boyutu arasından seçim
yapmak mümkündür. Daha büyük bir sektör boyutuna sahip bir diski biçimlendirmek,
her ize daha az sektör sığabileceği anlamına gelir, ancak aynı zamanda her ize daha
az başlık ve fragman yazılması ve kullanıcı verileri için daha fazla alan olması anlamına gelir.
Bazı işletim sistemleri yalnızca belirli bir sektör boyutunu işleyebilir.
Dosyaları tutmak için bir sürücü kullanmadan önce, işletim sisteminin yine de
kendi veri yapılarını cihaza kaydeder. Bunu üç adımda yapar.
İlk adım, cihazı bir veya daha fazla blok veya sayfa grubuna ayırmaktır. İşletim
sistemi, her bölüme ayrı bir aygıtmış gibi davranabilir. Örneğin, bir bölüm, işletim
sisteminin yürütülebilir kodunun bir kopyasını içeren bir dosya sistemini, bir başkası
takas alanını ve bir diğeri, kullanıcı dosyalarını içeren bir dosya sistemini tutabilir.
Bazı işletim sistemleri ve dosya sistemleri, bir aygıtın tamamı oluşturulduğunda
bölümlemeyi otomatik olarak gerçekleştirir.
Machine Translated by Google
dosya sistemi tarafından yönetilmelidir. Bölüm bilgileri, depolama aygıtında sabit bir konuma
sabit bir biçimde yazılır. Linux'ta fdisk komutu, depolama aygıtlarındaki bölümleri yönetmek için
kullanılır. Aygıt, işletim sistemi tarafından tanındığında, bölüm bilgilerini okur ve işletim sistemi,
bölümler için aygıt girişleri oluşturur ( Linux'ta /dev'de ). Buradan, /etc/fstab gibi bir yapılandırma
dosyası, işletim sistemine bir dosya sistemi içeren her bölümü belirli bir konuma bağlamasını ve
salt okunur gibi bağlama seçeneklerini kullanmasını söyler. Bir dosya sistemini monte etmek,
dosya sistemini sistem ve kullanıcıları tarafından kullanılabilir hale getirmektir.
İkinci adım, hacim oluşturma ve yönetimidir. Bazen, bir dosya sistemi doğrudan bir
bölümün içine yerleştirildiğinde olduğu gibi, bu adım örtüktür.
Bu hacim daha sonra monte edilmeye ve kullanılmaya hazırdır. Diğer zamanlarda, birim
oluşturma ve yönetimi açıktır - örneğin birden fazla bölüm veya cihaz bir RAID seti olarak (bkz.
Bölüm 11.8) cihazlara yayılmış bir veya daha fazla dosya sistemiyle birlikte kullanılacaksa. Linux
birim yöneticisi lvm2 , Linux ve diğer işletim sistemleri için ticari üçüncü taraf araçlar gibi bu
özellikleri sağlayabilir. ZFS , hem birim yönetimi hem de tek bir komut ve özellik kümesine
entegre edilmiş bir dosya sistemi sağlar. ("Birim"in, CD görüntüsü gibi bir dosya sistemi içeren
bir dosya bile dahil olmak üzere, herhangi bir monte edilebilir dosya sistemi anlamına
gelebileceğini unutmayın .)
Bölüm bilgileri, bir bölümün önyüklenebilir bir dosya sistemi (işletim sistemini içeren) içerip
içermediğini de gösterir. Önyükleme için etiketlenen bölüm, dosya sisteminin kökünü oluşturmak
için kullanılır. Monte edildikten sonra, diğer tüm cihazlar ve bunların bölümleri için cihaz
bağlantıları oluşturulabilir. Genel olarak, bir bilgisayarın "dosya sistemi" tüm bağlı birimlerden
oluşur. Windows'ta bunlar ayrı ayrı bir harf (C:, D:, E:) ile adlandırılır. Linux gibi diğer sistemlerde,
önyükleme sırasında önyükleme dosya sistemi monte edilir ve diğer dosya sistemleri bu ağaç
yapısı içinde monte edilebilir (Bölüm 13.3'te tartışıldığı gibi). Windows'ta, dosya sistemi arayüzü,
belirli bir cihazın ne zaman kullanıldığını netleştirirken, Linux'ta tek bir dosya erişimi, istenen
dosya sisteminde (bir birim içinde) istenen dosyaya erişilmeden önce birçok cihazı geçebilir. Şekil
11.9, üç birimi (C:, E: ve F:) gösteren Windows 7 Disk Yönetimi aracını gösterir. E: ve F: öğelerinin
her birinin "Disk 1" aygıtının bir bölümünde olduğunu ve bu aygıtta daha fazla bölüm için
ayrılmamış alan olduğunu (muhtemelen dosya sistemlerini içeren) unutmayın.
Verimliliği artırmak için çoğu dosya sistemi blokları, sıklıkla kümeler olarak adlandırılan
daha büyük parçalar halinde gruplandırır. Cihaz G/Ç'si bloklar aracılığıyla yapılır, ancak dosya
sistemi G/ Ç'si kümeler aracılığıyla yapılır ve G/Ç'nin daha fazla sıralı erişime ve daha az rastgele
erişim özelliğine sahip olmasını etkin bir şekilde sağlar. Dosya sistemleri , örneğin bir dosya
üzerinde çalışırken HDD kafa aramalarını azaltarak, dosya içeriklerini meta verilerinin yakınında
da gruplandırmaya çalışır .
Bazı işletim sistemleri, özel programlara, herhangi bir dosya sistemi veri yapısı olmaksızın,
büyük bir ardışık mantıksal blok dizisi olarak bir bölümü kullanma yeteneği verir. Bu diziye bazen
ham disk denir ve bu diziye G/Ç , ham G/Ç olarak adlandırılır. Örneğin, takas alanı için kullanılabilir
(bkz. Bölüm 11.6.2) ve bazı veritabanı sistemleri , kontrol etmelerini sağladığı için ham G/Ç'yi
tercih eder.
Machine Translated by Google
Şekil 11.9 Aygıtları, bölümleri, birimleri ve dosya sistemlerini gösteren Windows 7 Disk
Yönetimi aracı.
her bir veritabanı kaydının depolandığı tam konum. Ham G/Ç , arabellek önbelleği,
dosya kilitleme, önceden getirme, alan ayırma, dosya adları ve dizinler gibi tüm
dosya sistemi hizmetlerini atlar. Bazı uygulamaları ham bir bölüm üzerinde kendi
özel amaçlı depolama hizmetlerini uygulamalarına izin vererek daha verimli hale
getirebiliriz, ancak çoğu uygulama verileri yönetmek yerine sağlanan bir dosya
sistemini kullanır. Linux'un genellikle ham G/Ç'yi desteklemediğini, ancak open()
sistem çağrısına DIRECT bayrağını kullanarak benzer erişim sağlayabildiğini
unutmayın.
bölüm 1 bölme
tablosu
bölüm 2
önyükleme bölümü
bölüm 3
bölüm 4
kayıt veya MBR. Önyükleme, sistemin belleniminde bulunan kodu çalıştırarak başlar. Bu
kod, sistemi MBR'den önyükleme kodunu okumaya yönlendirir ve depolama denetleyicisi
ve depolama aygıtı hakkında ondan bir sektör yüklemek için yeterince bilgi sahibi olur.
Önyükleme kodunu içermeye ek olarak, MBR , Şekil 11.10'da gösterildiği gibi, sürücü için
bölümleri listeleyen bir tablo ve sistemin hangi bölümden önyükleneceğini gösteren bir
bayrak içerir. Sistem önyükleme bölümünü tanımladıktan sonra, o bölümden ( önyükleme
sektörü olarak adlandırılır) ilk sektörü/sayfayı okur ve bu onu çekirdeğe yönlendirir.
Ardından, çeşitli alt sistemlerin ve sistem hizmetlerinin yüklenmesini içeren önyükleme
işleminin geri kalanıyla devam eder.
Disklerin hareketli parçaları ve küçük toleransları olduğundan (disk kafasının disk yüzeyinin
hemen üzerinde uçtuğunu hatırlayın), bozulmaya eğilimlidirler. Bazen başarısızlık
tamamlanır; bu durumda diskin değiştirilmesi ve içeriğinin yedekleme ortamından yeni
diske geri yüklenmesi gerekir. Daha sık olarak, bir veya daha fazla sektör kusurlu hale gelir.
Hatta çoğu disk fabrikadan bozuk bloklarla gelir. Kullanılan diske ve denetleyiciye bağlı
olarak, bu bloklar çeşitli şekillerde işlenir.
IDE denetleyicileri olan bazı diskler gibi eski disklerde bozuk bloklar manuel olarak
işlenir. Bir strateji, disk biçimlendirilirken bozuk blokları bulmak için diski taramaktır.
Bulunan tüm bozuk bloklar, dosya sisteminin bunları ayırmaması için kullanılamaz olarak
işaretlenir. Normal çalışma sırasında bloklar bozulursa , bozuk blokları aramak ve onları
kilitlemek için özel bir program (Linux badblocks komutu gibi) manuel olarak çalıştırılmalıdır.
Bozuk bloklarda bulunan veriler genellikle kaybolur.
Daha karmaşık diskler, bozuk blok kurtarma konusunda daha akıllıdır. Denetleyici,
diskteki bozuk blokların bir listesini tutar. Liste, fabrikada düşük düzeyli biçimlendirme
sırasında başlatılır ve diskin ömrü boyunca güncellenir.
Düşük seviyeli biçimlendirme, işletim sistemi tarafından görülmeyen yedek sektörleri de
bir kenara bırakır. Denetleyiciye, her bozuk sektörü mantıksal olarak yedek sektörlerden
biriyle değiştirmesi söylenebilir. Bu şema, sektör yedekleme veya yönlendirme olarak bilinir .
Tipik bir kötü sektör işlemi aşağıdaki gibi olabilir:
sonra, sistem mantıksal blok 87'yi her talep ettiğinde, talep kontrolör tarafından
değiştirme sektörünün adresine çevrilir.
Takas alanı yönetimi , işletim sisteminin bir başka düşük seviyeli görevidir. Sanal
bellek, ana belleğin bir uzantısı olarak ikincil depolama alanını kullanır. Sürücü erişimi,
bellek erişiminden çok daha yavaş olduğundan, takas kullanarak
468 Bölüm 11 Yığın Depolama Yapısı
Machine Translated by Google
Linux dahil olmak üzere bazı işletim sistemleri, hem dosyalar hem de özel takas
bölümleri dahil olmak üzere birden çok takas alanının kullanımına izin verir. Bu
takas alanları genellikle ayrı depolama aygıtlarına yerleştirilir, böylece sayfalama ve
takas yoluyla G/Ç sistemine yüklenen yük, sistemin G/Ç bant genişliğine yayılabilir .
yerden birinde bulunabilir: normal dosya sisteminden oyulabilir veya ayrı bir
bölümde olabilir. Takas alanı dosya sistemi içindeki büyük bir dosyaysa, onu
oluşturmak, adlandırmak ve alanını tahsis etmek için normal dosya sistemi rutinleri
kullanılabilir.
Alternatif olarak, takas alanı ayrı bir ham bölümde oluşturulabilir. Bu alana
hiçbir dosya sistemi veya dizin yapısı yerleştirilmemiştir. Bunun yerine, ham
bölümden blokları tahsis etmek ve serbest bırakmak için ayrı bir takas alanı
depolama yöneticisi kullanılır. Bu yönetici, depolama verimliliği yerine hız için
optimize edilmiş algoritmalar kullanır, çünkü takas alanına, kullanıldığında dosya
sistemlerinden çok daha sık erişilir (takas alanının takas ve sayfalama için
kullanıldığını hatırlayın). Dahili parçalanma artabilir, ancak bu takas kabul edilebilir
çünkü takas alanındaki verilerin ömrü genellikle dosya sistemindeki dosyalardan
çok daha kısadır. Takas alanı önyükleme sırasında yeniden başlatıldığından,
herhangi bir parçalanma kısa ömürlüdür. Ham bölüm yaklaşımı, disk bölümleme
sırasında sabit miktarda takas alanı oluşturur. Daha fazla takas alanı eklemek,
aygıtın yeniden bölümlenmesini gerektirir (bu,
Machine Translated by Google
diğer dosya sistemi bölümleri veya onları yok etme ve yedekten geri yükleme) veya başka
bir yere başka bir takas alanı ekleme.
Bazı işletim sistemleri esnektir ve hem ham bölümlerde hem de dosya sistemi
alanında yer değiştirebilir. Linux bir örnektir: ilke ve uygulama ayrıdır ve makinenin
yöneticisinin hangi tür takasın kullanılacağına karar vermesine olanak tanır. Takas, dosya
sisteminde tahsis ve yönetim kolaylığı ile ham bölümlerde takas performansı arasındadır.
Bilgisayarlar ikincil depolamaya üç şekilde erişir: ana bilgisayara bağlı depolama, ağa
bağlı depolama ve bulut depolama yoluyla.
Machine Translated by Google
takas alanı
sayfa
yuvası
takas bölümü
veya takas dosyası
Bilgisayara bağlı depolama , yerel G/Ç bağlantı noktaları aracılığıyla erişilen depolamadır . Bu
bağlantı noktaları, daha önce belirtildiği gibi en yaygın olanı SATA olan çeşitli teknolojiler kullanır.
Tipik bir sistemde bir veya birkaç SATA bağlantı noktası bulunur.
Bir sistemin daha fazla depolama alanına erişmesine izin vermek için, tek bir depolama
aygıtı, kasadaki bir cihaz veya kasadaki birden çok sürücü USB FireWire veya Thunderbolt
bağlantı noktaları ve kabloları aracılığıyla bağlanabilir.
Üst düzey iş istasyonları ve sunucular genellikle daha fazla depolamaya ihtiyaç duyar veya
depolamayı paylaşmaya ihtiyaç duyar, bu nedenle fiber kanal (FC) gibi daha karmaşık G/Ç
mimarileri, fiber optik veya dört üzerinden çalışabilen yüksek hızlı bir seri mimari kullanın.
iletken bakır kablo. Geniş adres alanı ve iletişimin anahtarlamalı yapısı nedeniyle, birden çok
ana bilgisayar ve depolama aygıtı yapıya eklenebilir ve bu da G/Ç iletişiminde büyük esneklik
sağlar .
Ana bilgisayara bağlı depolama olarak kullanım için çok çeşitli depolama cihazları
uygundur. Bunların arasında HDD'ler; NVM cihazları; CD, DVD, Blu-ray ve teyp sürücüleri; ve
depolama alanı ağları (SAN'lar) (Bölüm 11.7.4'te ele alınmıştır). Ana bilgisayara bağlı bir
depolama aygıtına veri aktarımlarını başlatan G/Ç komutları, özel olarak tanımlanmış depolama
birimlerine (veri yolu kimliği veya hedef mantıksal birim gibi) yönelik mantıksal veri bloklarının
okuma ve yazma işlemleridir.
(NAS) (Şekil 11.12), bir ağ üzerinden depolamaya erişim sağlar. Bir NAS cihazı, özel amaçlı bir
depolama sistemi veya depolamasını ağdaki diğer ana bilgisayarlara sağlayan genel bir
bilgisayar sistemi olabilir. İstemciler, UNIX ve Linux sistemleri için NFS veya Windows
makineleri için CIFS gibi bir uzaktan prosedür çağrı arabirimi aracılığıyla ağa bağlı
depolamaya erişir . Uzaktan yordam çağrıları (RPC'ler) , bir IP ağı üzerinden TCP veya UDP
aracılığıyla taşınır - genellikle tüm veri trafiğini istemcilere taşıyan aynı yerel alan ağı (LAN) .
Ağa bağlı depolama birimi, genellikle RPC arabirimini uygulayan yazılıma sahip bir depolama
dizisi olarak uygulanır .
CIFS ve NFS , çeşitli kilitleme özellikleri sağlayarak, bu protokollerle bir NAS'a erişen ana
bilgisayarlar arasında dosya paylaşımına izin verir . Örneğin, birden fazla NAS istemcisinde
oturum açmış bir kullanıcı , aynı anda tüm bu istemcilerden kendi ana dizinine erişebilir.
Machine Translated by Google
müşteri
NAS
LAN/WAN müşteri
NAS
müşteri
Ağa bağlı depolama, bir LAN üzerindeki tüm bilgisayarların, yerel ana bilgisayara
bağlı depolama ile aynı adlandırma ve erişim kolaylığıyla bir depolama havuzunu
paylaşması için uygun bir yol sağlar. Ancak, bazı doğrudan bağlı depolama
seçeneklerinden daha az verimli ve daha düşük performansa sahip olma eğilimindedir.
iSCSI , ağa bağlı en yeni depolama protokolüdür. Özünde, SCSI protokolünü taşımak
için IP ağ protokolünü kullanır . Bu nedenle, SCSI kabloları yerine ağlar, ana bilgisayarlar
ve depolamaları arasındaki ara bağlantı olarak kullanılabilir.
Sonuç olarak, ana bilgisayarlar, depolama ana bilgisayardan uzakta olsa bile, depolamalarına
doğrudan bağlıymış gibi davranabilir. NFS ve CIFS bir dosya sistemi sunarken ve
dosyaların bölümlerini ağ üzerinden gönderirken, iSCSI ağ üzerinden mantıksal bloklar
gönderir ve blokları doğrudan kullanmasını veya onlarla bir dosya sistemi oluşturmasını
istemciye bırakır.
müşteri
sunucu
müşteri
depolama LAN/WAN
dizisi sunucu
müşteri
depolama SAN
dizisi veri işleme merkezi
Depolama alanı ağı (SAN) , Şekil 11.13'te gösterildiği gibi sunucuları ve depolama
birimlerini birbirine bağlayan (ağ protokolleri yerine depolama protokollerini kullanan)
özel bir ağdır. Bir SAN'ın gücü , esnekliğinde yatar. Aynı SAN'a birden çok ana bilgisayar
ve birden çok depolama dizisi eklenebilir ve depolama, ana bilgisayarlara dinamik olarak
ayrılabilir. Depolama dizileri, RAID korumalı veya korumasız sürücüler olabilir (Sadece Bir
Grup Disk (JBOD)). Bir SAN anahtarı, ana bilgisayarlar ve depolama arasında erişime izin
verir veya erişimi engeller. Örnek olarak, bir ana bilgisayarın disk alanı azalıyorsa, SAN ,
o ana bilgisayara daha fazla depolama tahsis edecek şekilde yapılandırılabilir. SAN'lar ,
sunucu kümelerinin aynı depolamayı paylaşmasını ve depolama dizilerinin birden çok
doğrudan ana bilgisayar bağlantısı içermesini mümkün kılar.
SAN'lar genellikle depolama dizilerinden daha fazla bağlantı noktasına sahiptir ve maliyeti daha
yüksektir. SAN bağlantısı kısa mesafelerdedir ve tipik olarak yönlendirmesi yoktur, bu nedenle bir
NAS , bir SAN'dan çok daha fazla bağlı ana bilgisayara sahip olabilir .
Depolama dizisi, SAN bağlantı noktalarını, ağ bağlantı noktalarını veya her ikisini
birden içeren amaca yönelik oluşturulmuş bir aygıttır (bkz. Şekil 11.14) . Ayrıca, verileri
depolamak için sürücüler ve depolamayı yönetmek ve ağlar üzerinden depolamaya
erişime izin vermek için bir denetleyici (veya yedekli denetleyiciler kümesi) içerir.
Denetleyiciler, ağ protokollerini, kullanıcı arabirimlerini, RAID korumasını, anlık
görüntüleri, çoğaltmayı, sıkıştırmayı, veri tekilleştirmeyi ve şifrelemeyi içerebilen dizinin
özelliklerini uygulayan CPU'lar, bellek ve yazılımdan oluşur. Bu işlevlerden bazıları Bölüm
14'te tartışılmaktadır.
Bazı depolama dizileri SSD'leri içerir. Bir dizi yalnızca SSD'leri içerebilir , bu da
maksimum performans ancak daha küçük kapasite ile sonuçlanır veya dizi yazılımının
(veya yöneticinin) belirli bir kullanım için en iyi ortamı seçmesi veya SSD'leri önbellek
olarak kullanması ile birlikte SSD'ler ve HDD'lerin bir karışımını içerebilir. ve toplu
depolama olarak HDD'ler .
11.8 RAID Yapısı 473
Machine Translated by Google
Depolama aygıtları küçülmeye ve ucuzlamaya devam etti, bu nedenle artık birçok sürücüyü
bir bilgisayar sistemine bağlamak ekonomik olarak mümkün. sahip olmak
Bir sistemdeki çok sayıda sürücü, iyileştirme için fırsatlar sunar.
Sürücüler paralel olarak çalıştırılırsa, verilerin okunabileceği veya yazılabileceği hız. Ayrıca,
bu kurulum güvenilirliği artırma potansiyeli sunar
veri depolama, çünkü fazlalık bilgiler birden çok yerde saklanabilir
sürücüler. Bu nedenle, bir sürücünün arızalanması veri kaybına yol açmaz. Çeşitli
Toplu olarak bağımsız disklerin yedekli dizileri (RAID'ler) olarak adlandırılan disk düzenleme
teknikleri, performansı ele almak için yaygın olarak kullanılır ve
güvenilirlik sorunları.
Geçmişte, küçük, ucuz disklerden oluşan RAID'ler , büyük ve pahalı disklere uygun
maliyetli bir alternatif olarak görülüyordu. Bugün, RAID'ler amaçları için kullanılmaktadır.
ekonomik nedenlerden ziyade daha yüksek güvenilirlik ve daha yüksek veri aktarım hızı. Bu
nedenle, bir zamanlar "ucuz" anlamına gelen RAID'deki I , şimdi
"bağımsız."
YAPILANDIRMA RAID
diskler 100.000/100 = 1.000 saat veya 41.66 gün olacak, ki bu hiç de uzun değil!
Verilerin yalnızca bir kopyasını saklarsak, her disk arızası önemli miktarda veri
kaybına neden olur ve bu kadar yüksek bir veri kaybı oranı kabul edilemez.
Güvenilirlik sorununun çözümü artıklık getirmektir; normalde ihtiyaç
duyulmayan ancak disk arızası durumunda kayıp bilgileri yeniden oluşturmak için
kullanılabilecek ek bilgileri depolarız. Böylece bir disk arızalansa bile veriler
kaybolmaz. RAID , NVM cihazlarına da uygulanabilir , ancak NVM cihazlarının
hareketli parçaları yoktur ve bu nedenle HDD'lere göre arızalanma olasılığı daha düşük
Artıklık sağlamanın en basit (ama en pahalı) yaklaşımı, her sürücüyü
çoğaltmaktır. Bu tekniğe yansıtma denir . Yansıtma ile mantıksal disk iki fiziksel
sürücüden oluşur ve her yazma işlemi her iki sürücüde de gerçekleştirilir. Sonuç,
yansıtılmış birim olarak adlandırılır. Birimdeki sürücülerden biri arızalanırsa, veriler
diğerinden okunabilir. Veriler, yalnızca ilk arızalı sürücü değiştirilmeden önce
ikinci sürücü arızalanırsa kaybolur.
Yansıtılmış bir birimin MTBF'si (burada hata, veri kaybıdır) iki faktöre bağlıdır.
Biri, bireysel sürücülerin MTBF'sidir. Diğeri, ortalama onarım süresidir; bu, arızalı
bir sürücüyü değiştirmek ve üzerindeki verileri geri yüklemek için (ortalama
olarak) geçen süredir. İki sürücünün arızalarının bağımsız olduğunu varsayalım;
yani birinin başarısızlığı diğerinin başarısızlığına bağlı değildir. Ardından, tek
bir sürücünün MTBF'si 100.000 saat ve ortalama onarım süresi 10 saat ise,
yansıtılmış bir sürücü sisteminin ortalama veri kaybı süresi 100.0002 (2 10) =
500 106 saat veya 57.000 yıl!
Sürücü arızalarının bağımsız olacağını gerçekten varsayamayacağımızı
bilmelisiniz. Elektrik kesintileri ve deprem, yangın ve sel gibi doğal afetler, aynı
anda her iki sürücüde de hasara neden olabilir. Ayrıca, bir grup sürücüdeki üretim
hataları, ilişkili arızalara neden olabilir. Sürücüler yaşlandıkça, arıza olasılığı artar
ve birincisi onarılırken ikinci bir sürücünün arızalanma şansı artar. Bununla birlikte,
tüm bu hususlara rağmen, aynalı tahrik sistemleri, tek tahrikli sistemlere göre
çok daha yüksek güvenilirlik sunar.
Elektrik kesintileri, doğal afetlerden çok daha sık meydana geldikleri için özel
bir endişe kaynağıdır. Sürücülerin ikizlenmesinde bile, her iki sürücüde de aynı
bloğa yazma işlemi devam ediyorsa ve her iki blok tamamen yazılmadan önce
güç kesilirse, iki blok tutarsız bir durumda olabilir. Bu soruna bir çözüm, önce bir
kopya, sonra bir kopya yazmaktır. Diğeri, RAID dizisine katı hal kalıcı bir önbellek
eklemektir . Bu geri yazma önbelleği
Machine Translated by Google
elektrik kesintileri sırasında veri kaybından korunur, bu nedenle, önbelleğin ECC veya ikizleme
gibi bir tür hata koruması ve düzeltmesi olduğu varsayılarak, yazma işleminin bu noktada
tamamlanmış olduğu kabul edilebilir .
11.8.2 Paralellik Yoluyla Performansta İyileştirme Şimdi, birden çok sürücüye paralel
erişimin performansı nasıl geliştirdiğini ele alalım. Yansıtma ile, okuma isteklerinin işlenme hızı iki
katına çıkar, çünkü okuma istekleri her iki sürücüye de gönderilebilir (neredeyse her zaman olduğu
gibi, her ikisi de bir çiftte işlevsel olduğu sürece). Her okumanın aktarım hızı, tek sürücülü sistemdekiyle
aynıdır, ancak birim zaman başına okuma sayısı iki katına çıkmıştır.
Birden fazla sürücüyle, verileri sürücüler arasında şeritleyerek (veya bunun yerine)
aktarım hızını da iyileştirebiliriz. En basit biçiminde, veri şeritleme , her bir baytın bitlerini
birden çok sürücüye bölmekten oluşur; bu tür şeritleme, bit düzeyinde şeritleme olarak
adlandırılır. Örneğin, sekiz sürücüden oluşan bir dizimiz varsa, i sürücüsüne her baytın i bitini
yazarız . Sekiz sürücü dizisi, normal boyutun sekiz katı ve daha da önemlisi erişim hızının sekiz
katı olan sektörlere sahip tek bir sürücü olarak ele alınabilir. Her sürücü, her erişime katılır
(okuma veya yazma); yani saniyede işlenebilen erişim sayısı, tek bir sürücüdekiyle yaklaşık
olarak aynıdır, ancak her erişim, aynı anda tek bir sürücüdekinden sekiz kat daha fazla veri
okuyabilir.
Bit düzeyinde şeritleme, 8'in katı olan veya 8'i bölen bir dizi sürücüyü içerecek şekilde
genelleştirilebilir. Örneğin, dört sürücüden oluşan bir dizi kullanırsak, her baytın i ve 4+i
bitleri i sürücüsüne gider . Ayrıca, şeritlemenin bit seviyesinde gerçekleşmesi gerekmez.
Örneğin blok düzeyinde şeritlemede, bir dosyanın blokları birden çok sürücü arasında
şeritlenir; n sürücüde , bir dosyanın i bloğu (i mod n)+1 sürücüsüne gider .
Bir sektörün baytları veya bir bloğun sektörleri gibi diğer şeritleme seviyeleri de mümkündür.
Blok düzeyinde şeritleme, yaygın olarak kullanılabilen tek şeritlemedir.
Bir depolama sistemindeki paralellik, şeritleme yoluyla elde edildiği gibi, iki ana hedefe
sahiptir:
Yansıtma yüksek güvenilirlik sağlar, ancak pahalıdır. Şeritleme, yüksek veri aktarım hızları
sağlar, ancak güvenilirliği artırmaz. “Parite” bitleriyle (kısaca anlatacağımız) birleştirilmiş
disk şeritlemeyi kullanarak daha düşük maliyetle artıklık sağlamak için çok sayıda şema
önerilmiştir. Bu şemaların farklı maliyet-performans dengeleri vardır ve RAID seviyeleri adı
verilen seviyelere göre sınıflandırılır. Burada yalnızca en yaygın seviyeleri açıklıyoruz; Şekil
11.15 bunları resimli olarak gösterir (şekilde P , hata düzeltme bitlerini ve C verilerin ikinci bir
kopyasını gösterir). Şekilde gösterilen tüm durumlarda, dört sürücü değerinde veri depolanır
ve fazladan sürücüler, arıza kurtarma için gereksiz bilgileri depolamak için kullanılır.
Machine Translated by Google
• RAID düzeyi 0. RAID düzeyi 0, Şekil 11.15(a)'da gösterildiği gibi, blok düzeyinde şeritlemeli
ancak herhangi bir fazlalık (yansıtma veya eşlik bitleri gibi) olmayan sürücü dizilerini ifade
eder.
• RAID düzeyi 1. RAID düzeyi 1, sürücü ikizleme anlamına gelir. Şekil 11.15(b) şunları gösterir:
yansıyan bir organizasyon.
• RAID düzeyi 4. RAID düzeyi 4, bellek stili hata düzeltme olarak da bilinir.
kod (ECC) organizasyonu. ECC , RAID 5 ve 6'da da kullanılır .
ECC fikri, sürücüler arasında blokların şeritlenmesi yoluyla doğrudan depolama
dizilerinde kullanılabilir. Örneğin, bir yazma dizisinin birinci veri bloğu sürücü 1'de, ikinci
blok sürücü 2'de saklanabilir ve N'inci blok N sürücüsünde depolanana kadar bu böyle
devam edebilir ; bu blokların hata düzeltme hesaplama sonucu, N + 1 sürücüsünde
depolanır. Bu şema, P etiketli sürücünün hata düzeltme bloğunu sakladığı Şekil
11.15(c)'de gösterilmektedir . Sürücülerden biri arızalanırsa, hata düzeltme kodunun
yeniden hesaplanması bunu algılar ve