2013-06-07 25 views
13

Çok işlemcili her çekirdek kendi değişkenlerine sahip olabilir. Aynı adreste ve aynı isimde olmasına rağmen farklı adreslerde farklı değişkenler olduğunu düşündüm.Linux çekirdeğinde percpu işaretçiler nasıl uygulanır?

Ama merak ediyorum, nasıl çekirdek bu uyguluyor mu? Tüm percpu işaretleyicilerini depolamak için bir bellek parçasını dağıtıyor mu ve işaretçiyi vardiyalı bir şeyle belirli adrese her yönlendirdiğinde?

cevap

20

Normal global değişkenler CPU'ya göre değildir. Otomatik değişkenler yığındadır ve farklı CPU'lar farklı yığın kullanırlar, dolayısıyla doğal olarak ayrı değişkenler alırlar.

Sana Linux'un başına CPU değişken altyapıya kastediyorsunuz sanırım.
büyü çoğu (asm-generic/percpu.h) burada: (bakılmaksızın işaretçi türden) bayt bir ofsetini tarafından

extern unsigned long __per_cpu_offset[NR_CPUS]; 

#define per_cpu_offset(x) (__per_cpu_offset[x]) 

/* Separate out the type, so (int[3], foo) works. */ 
#define DEFINE_PER_CPU(type, name) \ 
    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name 

/* var is in discarded region: offset to particular copy we want */ 
#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu])) 
#define __get_cpu_var(var) per_cpu(var, smp_processor_id()) 

makro RELOC_HIDE(ptr, offset) basitçe ptr ilerler.

Ne yapar?

  1. DEFINE_PER_CPU(int, x) tanımlayan bir tam sayı __per_cpu_x Özel .data.percpu bölümünde oluşturulur. Çekirdek yüklendiğinde
  2. , bu bölüm, birden çok kez yüklenir - CPU başına (sihirli bir kısmı yukarıdaki kodu değildir) bir kez.
  3. __per_cpu_offset dizisi, kopyalar arasındaki mesafelerle doldurulur. CPU verisi başına 1000 bayt kullanıldığında, __per_cpu_offset[n]1000*n içerir.
  4. sembol per_cpu__x CPU 0 en per_cpu__x için, yükleme sırasında, taşınacaktır. CPU 3 çalışırken
  5. __get_cpu_var(x)
  6. , *RELOC_HIDE(&per_cpu__x, __per_cpu_offset[3]) çevirmek olacaktır. Bu, CPU 0'ın x ile başlar, CPU 0'ın verileri ile CPU 3'leri arasındaki ofseti ekler ve sonuçta elde edilen işaretçiyi alır. senin ansser için
+0

Teşekkürler ama hala bazı smp için yeni sorular, bu yüzden, Fikrinizde hiçbir suç var. Birincisi, aynı işlemin aynı yığına sahip olması gerektiğini düşündüm, burada POSIX'de iş parçacığı tanımı var ... ve otomatik değişkenler aynı süreçteki tüm iş parçacıklarına erişebilir. Otomatik değişken iş parçacıkları tarafından paylaşılır. Farklı işlemci farklı yığın segmenti kaydına sahip olabilir, ancak içerik aynı olmalıdır. İkincisi, istersek diğer cpu değişkenine de erişebileceğimizi söyleyebilir miyiz, percpu tarafından elde edilen ofseti geri almamız yeterli midir? – dspjm

+0

İki iş parçacığı, 'x' otomatik bir değişkeni olan foo' işlevini çağırdığında, iki yığın ve iki kez x' vardır. Her birinin farklı bir adresi vardır ve her iki ileti de adrese sahipse her ikisine de erişebilir. Linux'un cpu değişkenleriyle, 'per_cpu (var, cpu) ', herhangi bir cpu'nun değişkenlerine erişmenizi sağlar. – ugoren

+0

.data.percpu bölümü, percpu değişkeninin yığın veya yığın üzerinde bildirilip bildirilmediğini nasıl belirler? – user31986

İlgili konular