Bilgisayarımda 192GB RAM yüklü, 4GB üzerinde (donanım adresi 0x100000000'de) önyükleme sırasında Linux çekirdeği tarafından ayrılmış 188GB RAM var (mem = 4G memmap = 188 g $ 4G). Bir veri toplama çekirdeği modülü, DMA kullanılarak bir halka tamponu olarak kullanılan bu geniş alana veri biriktirir. Bir kullanıcı alanı uygulaması mmap bu halka arabelleğini kullanıcı boşluğuna yerleştirir, sonra hazır olduktan sonra işlemek için mevcut konumdaki halka arabelleği bloklarını kopyalar.Linux'taki mmap'ed fiziksel belleği için kullanıcı alanında yetersiz performans
Bu 16 MB'lık blokların memcpy kullanılarak mmap'ed alanından kopyalanması beklediğim gibi performans göstermiyor. Performansın, önyükleme zamanında ayrılmış olan belleğin boyutuna bağlı olduğu (ve daha sonra kullanıcı alanına mmap'ed) olduğu anlaşılmaktadır. (Kontrol çıkarılmış) esas olarak yapar
module_param(resmem_hwaddr, ulong, S_IRUSR);
module_param(resmem_length, ulong, S_IRUSR);
//...
static int resmem_mmap(struct file *filp, struct vm_area_struct *vma) {
remap_pfn_range(vma, vma->vm_start,
resmem_hwaddr >> PAGE_SHIFT,
resmem_length, vma->vm_page_prot);
return 0;
}
ve bir test uygulaması,:
#define BLOCKSIZE ((size_t)16*1024*1024)
int resMemFd = ::open(RESMEM_DEV, O_RDWR | O_SYNC);
unsigned long resMemLength = 0;
::ioctl(resMemFd, RESMEM_IOC_LENGTH, &resMemLength);
void* resMemBase = ::mmap(0, resMemLength, PROT_READ | PROT_WRITE, MAP_SHARED, resMemFd, 4096);
char* source = ((char*)resMemBase) + RESMEM_HEADER_SIZE;
char* destination = new char[BLOCKSIZE];
struct timeval start, end;
gettimeofday(&start, NULL);
memcpy(destination, source, BLOCKSIZE);
gettimeofday(&end, NULL);
float time = (end.tv_sec - start.tv_sec)*1000.0f + (end.tv_usec - start.tv_usec)/1000.0f;
std::cout << "memcpy from mmap'ed to malloc'ed: " << time << "ms (" << BLOCKSIZE/1000.0f/time << "MB/s)" << std::endl;
I taşıdı http://www.wurmsdobler.org/files/resmem.zip yapan bir çekirdek modülü için kaynak kodu mmap dosyası işlem uygular içerir
| | 1GB | 4GB | 16GB | 64GB | 128GB | 188GB
|run 1 | 9.274ms (1809.06MB/s) | 11.503ms (1458.51MB/s) | 11.333ms (1480.39MB/s) | 9.326ms (1798.97MB/s) | 213.892ms ( 78.43MB/s) | 206.476ms ( 81.25MB/s)
|run 2 | 4.255ms (3942.94MB/s) | 4.249ms (3948.51MB/s) | 4.257ms (3941.09MB/s) | 4.298ms (3903.49MB/s) | 208.269ms ( 80.55MB/s) | 200.627ms ( 83.62MB/s)
012: bir SuperMicro 1026GT-tf-FM109 Ubuntu 10.04.4, Linux 2.6.32 ile ayrılmış RAM (resmem_length) farklı boyutları için bir 16MB veri bloğunun memcpy testler üzerindengözlemlerim şunlardır: malloc'ed için mmap ikinci vadede, memcpy İlk gelen
içeriği zaten bir yere önbelleğe olabileceğini fayda görülmektedir.
Hem 64 GB değerinde, hem de bir memcpy kullanırken dikkat edilmesi gereken önemli bir performans düşüşü var.
Bunun nedenini anlamak isterim. Belki Linux çekirdek geliştiricileri grup düşüncede birileri: 64GB (? Bu birşey hatırlatıyor mu)
Saygılarımızla peter kimse için yeterli olmalıdır
CPU muhtemelen onunla başa çıkmak için yeterli önbelleğe sahip olmayan
Merhaba Ignacio, doğru olabilir. Bilgisayar iki adet Intel Xeon E5620 2 ile donatılmıştır.12MB L3 önbellek ve 1066MHz bellek hızı ile 4GHz dört çekirdekli. – PeterW
Basit görünümüm, ilk okuma işlemi için RAM'deki içeriğin önbelleğe alınacağı ve miktarın önbellekte sığdığı sürece ikinci isteğin doğrudan önbellekten sunulacağıdır. Aktarılan veri miktarının memnum üzerinde bir etkisi olacağını düşünürdüm, benim durumumda <12MB, fakat takılı belleklerin toplam büyüklüğü değil, ya da RAM'de veri var. – PeterW
Diğer testler, aynı performans düşüşünün daha küçük veri blokları için, ör. 1MB. Sadece önyükleme zamanında ayrılmış olan bellek miktarına bağlıyım, yani daha fazla değil 64GB. – PeterW