هل يمكن نقل صفحة الذاكرة عن طريق تعديل جدول الصفحة؟

StackOverflow https://stackoverflow.com/questions/2679065

  •  30-09-2019
  •  | 
  •  

سؤال

هل من الممكن (على أي نظام تشغيل معقول ، ويفضل أن يكون Linux) تبديل محتويات صفحتين للذاكرة عن طريق تعديل جدول الصفحة فقط وعدم نقل أي بيانات بالفعل؟

الدافع هو مصفوفة كثيفة transpose. إذا تم حظر البيانات حسب حجم الصفحة ، فسيكون من الممكن تحويل البيانات داخل صفحة (يناسب ذاكرة التخزين المؤقت) ، ثم تبديل الصفحات لتحريك الكتل إلى مكانها النهائي. ستحصل مصفوفة كبيرة على العديد من الصفحات ، لذلك نأمل أن يسبب التغلب على TLB مشكلة.

هل كانت مفيدة؟

المحلول

أعتقد أن الملفات المعينة للذاكرة قد تقوم بالخدعة ، لكنني أعتقد أنني لم أجرب هذا بنفسي أبدًا. يستخدم mmap مع map_anynowous لخريطة خريطة على العنوان الظاهري الخالص (لا يوجد دعم ملف فعلي). بعد ذلك ، يمكنك إعادة تجديد "ملفك" إلى مجالات مختلفة من VA التي تحصل عليها في تأثير دلالات نسخة صفر. في Windows كنت تستخدمه MapViewoffile مع مقبض رسم خرائط الملفات الذي تم إنشاؤه باستخدام CreateMapoffile (invalid_handle_value ، ...) ، ولكن ملاحظة أكثر من NT لا يمكنك التحكم في استهداف من إعادة تعيينك (أي. عنوان VA المعين حديثًا هو انتاج من استدعاء الوظيفة) ، وعلى Linux يتم أخذ العنوان المطلوب كملف ملحوظة.

إذا لم ينجح هذا ، فربما تحتاج إلى إنشاء وحدة مدير ذاكرة في kernel ، وهو أمر غير ممكن لأي مشروع عملي.

نصائح أخرى

#include <stdio.h>
#include <string.h>

#define __USE_GNU
#include <unistd.h>
#include <sys/mman.h>

int main() {
    int PAGE_SIZE = getpagesize();
    char* m = NULL;
    void* temp;

    printf("page size = %d\n", PAGE_SIZE);

    m = (char*)mmap(0, PAGE_SIZE*3, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    temp = m+PAGE_SIZE*2;

    memset(m, '0', PAGE_SIZE);
    memset(m+PAGE_SIZE, '1', PAGE_SIZE);

    printf("before %c %c\n", m[0], m[PAGE_SIZE]);

    mremap(m + PAGE_SIZE, PAGE_SIZE, PAGE_SIZE, MREMAP_FIXED | MREMAP_MAYMOVE, temp); 
    mremap(m, PAGE_SIZE, PAGE_SIZE, MREMAP_FIXED | MREMAP_MAYMOVE, m+PAGE_SIZE); 
    mremap(temp, PAGE_SIZE, PAGE_SIZE, MREMAP_FIXED | MREMAP_MAYMOVE, m); 


    printf("after %c %c\n", m[0], m[PAGE_SIZE]);
    return 0;
}

من الناحية النظرية بالتأكيد. في الممارسة العملية ، أنا فكر في يمكنك استخدام MMAP () لنقل كتل الذاكرة المشتركة على طراز V-Style بهذه الطريقة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top