2011-12-23 17 views
5

memcpy/memmove (verileri kopyalayın) kaynağından hedefe kopyalayın. Kaynak verilerin bayt kopyasıyla gerçek bir bayt yapmadan sayfaları bir sanal adresten diğerine taşımak için herhangi bir şey var mı? Bana tamamen mümkün görünüyor, ama herhangi bir işletim sistemi buna gerçekten izin veriyor mu? Dinamik dizilerin bu kadar yaygın ve popüler bir kavram olduğu, ancak fiziksel olarak kopyalayarak bunları büyütmenin böylesine savurgan bir işlem olduğu bana tuhaf geliyor. Eğer (örneğin 200GB diziye 100GB dizi büyüyen düşünün. Bu artık < $ 10K aralığında sunucularda tamamen mümkün bir sorun.Herhangi bir işletim sistemi, belleği fiziksel olarak kopyalamadan bir adresten diğerine taşımaya izin veriyor mu?

void* very_large_buffer = VirtualAlloc(NULL, 2GB, MEM_COMMIT); 
// Populate very_large_buffer, run out of space. 
// Allocate buffer twice as large, but don't actually allocate 
// physical memory, just reserve the address space. 
void* even_bigger_buffer = VirtualAlloc(NULL, 4GB, MEM_RESERVE); 
// Remap the physical memory from very_large_buffer to even_bigger_buffer without copying 
// (i.e. don't copy 2GB of data, just copy the mapping of virtual pages to physical pages) 
// Does any OS provide support for an operation like this?  
MoveMemory(very_large_buffer, even_bigger_buffer, 2GB) 
// Now very_large_buffer no longer has any physical memory pages associated with it 
VirtualFree(very_large_buffer) 

cevap

6

farklı görünümlerini eşleyerek süreci arasındaki bellek kopyalama oluyor, bunu yapabilirsiniz Linux'ta mremap ile. oyunlarını diyoruz

eğer sıfır fotokopisi ise. Her durumda mümkün değildir (adres boşluklarının parçalanması ve sadece mevcut diğer haritaların varlığı bir sorundur).

mremap() sanal adresleri ve bellek sayfaları arasında eşleme değiştirir:

adam sayfası aslında bu diyor. Bu çok verimli bir realloc uygulamak için kullanılabilir (3).

+0

Bu, tam olarak aradığım şey gibi görünüyor. Bunu linux ve her yerde standart bir aptal hafıza üzerinde kullanabilirim. – Eloff

+1

Veya bir realloc ve umarım kaputun altında benzer bir yöntem kullanır. :) – onitake

2
gigabayt cinsinden dizi boyutları hakkında konuşmaya başladığınızda Sadece ölçeklendirme değil

Evet bu bellek yaygın kullanımı 'hareket' dosyaları eşlenen ya da bazı ölçüde dosyanın

0

Yani, bir sonraki 100 GB'de hiçbir aktif bellek olmayacağını kesinlikle garanti edemezsiniz, bu yüzden onu bitişik hale getiremeyebilirsiniz.

Diğer yandan, dizilerin birbirinin yanında (veya aynı boyutta) olması gerekmeyen düzleştirilmiş bir dizi (dizi dizisi) kullanabilirsiniz. Dinamik dizilerin avantajlarının çoğu 100GB alanına ölçeklendirilemez.

+1

Anladığım kadarıyla, gerçek fiziksel RAM sayfalarının bitişik olmaması gerekir, bu sanal adresleme noktasıdır. Ancak 200 GB'lık parçalanmamış sanal adres alanına ihtiyacınız olacaktır (şu anda 64bit işlem modern işletim sistemlerinde 8TB adres alanına sahiptir, bu yüzden bu bir sorun olmamalıdır.) – Eloff

1

Her POSIX sistemi bunu yapabilir. Bir dosya tanıtıcısıyla mmap kullanırsanız (open veya shm_open tarafından elde edilir) ve anonim olarak kullanmazsanız, bunu kesebilir, sonra da kırpabilir (küçültebilir veya büyüyebilir) ve daha sonra yeniden eşleştirebilirsiniz. Aynı sayfalar için genellikle farklı bir sanal adres alabilirsiniz.

+0

Yanılıyorsam düzeltin, ancak unmapping tüm pislikleri yazabilir Bu dosyaya geri sayfalar (tembel mi?) Bu yüzden yeniden haritalandırdığınızda, sayfalara erişme, onları dosyadan geri okumak isteyebilir. Orada bir sürü uygulama detayı var, ancak disk IO'suna neden olarak bellek kopyalarından kaçınmak bir kazanma ihtimali değil. Merak ediyorum, mmap genellikle süreçler arasında bellek paylaşmak için kullanıldığından, ilk eşleştirmeyi kapatmadan aynı dosyanın ikinci bir eşlemesini oluşturmak ve dosyayı büyütmek (küçültmek) mümkün olmamalı mıdır? Bu sanırım sıfır bir hareket kopyası olurdu. – Eloff

+0

İlk olarak, shm_open işlevini kullanırsanız, dosya yoktur, bu yüzden herhangi bir şey yazılmaz. Ve hatta 'açık' için bile, unmapping'in sayfaları geri yazacağını düşünmüyorum, sadece dosya tanıtıcısını kapatmak bunu zorlayacaktı. –

+0

Sanırım shm_open durumunda, içeriğini unmapped çünkü ilginç değil, içeriğini kaybedersiniz. Ve haklısın, sanırım kirli sayfaları, haritayı kapattığınız için yazılmayacaktı, yine de sistem yazım arabelleğinde olmalı. – Eloff

İlgili konular