هل تعمل NVIDIA RDMA GPUDIRECT دائمًا على العناوين المادية فقط (في مساحة العنوان المادي في وحدة المعالجة المركزية)؟

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

سؤال

كما نعلم: http://en.wikipedia.org/wiki/iommu#advantages

يمكن دعم ترحيل الذاكرة المحيطية بواسطة iommu. يمكن أن يكتشف امتداد صفحات طلبات Transform (ATS) الطرفية باستخدام امتداد لخدمات Transform (ATS) للخدمات (PRI) للخدمات (PRI) للإشارة إلى الحاجة إلى خدمات مدير الذاكرة.

enter image description here

ولكن عندما نستخدم NVIDIA GPU مع CUDA> = 5.0 ، يمكننا استخدام RDMA gpudirect ، ومعرفة ذلك:

http://docs.nvidia.com/cuda/gpudirect-rdma/index.html#how-gpudirect-rdma-works

تقليديًا ، يتم تعيين موارد مثل Windows إلى مساحة عنوان المستخدم أو kernel باستخدام MMU CPU كعناوين I/O (MMIO) المعينة. ومع ذلك ، لأن لا تملك أنظمة التشغيل الحالية آليات كافية لتبادل مناطق MMIO بين السائقين, يعمل صادرات برنامج تشغيل NVIDIA kernel على تنفيذ ترجمات العنوان والتعيينات اللازمة.

http://docs.nvidia.com/cuda/gpudirect-rdma/index.html#supported-systems

تعتمد RDMA لـ Gpudirect حاليًا على جميع العناوين الماديةكونها هي نفسها من وجهة نظر أجهزة PCI. هذا يجعل الأمر غير متوافق مع Iommus ، وبالتالي يجب تعطيله لـ RDMA حتى يعمل Gpudirect.

وإذا قمنا بتخصيص ورسم خرائط CPU-RAM إلى UVA ، كما هو الحال هنا:

#include <iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

int main() {
    // Can Host map memory
    cudaSetDeviceFlags(cudaDeviceMapHost);  

    // Allocate memory
    unsigned char *host_src_ptr = NULL;
    cudaHostAlloc(&host_src_ptr, 1024*1024, cudaHostAllocMapped);
    std::cout << "host_src_ptr = " << (size_t)host_src_ptr << std::endl;

    // Get UVA-pointer
    unsigned int *uva_src_ptr = NULL;
    cudaHostGetDevicePointer(&uva_src_ptr, host_src_ptr, 0);
    std::cout << "uva_src_ptr  = " << (size_t)uva_src_ptr << std::endl;

    int b;  std::cin >> b;
    return 0;
}

نحصل على مؤشرات متساوية في Windwos7x64 ، وهذا يعني ذلك cudaHostGetDevicePointer() لا تفعل شيئا:

Host_src_ptr = 68719476736

UVA_SRC_PTR = 68719476736

ما الذي يعنيه "آليات كافية لتبادل مناطق MMIO بين برامج التشغيل" ، ما هي الآلية التي تعنيها هنا ، ولماذا لا يمكنني استخدام IOMMU باستخدام العنوان الافتراضي للوصول عبر PCI ؟

وهل هذا يعني أن RDMA gpudirect لا تدير دائمًا عناوين مادية فقط (في مساحة العنوان المادي في وحدة المعالجة المركزية) ، ولكن لماذا نرسل إلى وظيفة kernel uva_src_ptr الذي يساوي host_src_ptr - مؤشر بسيط في مساحة العنوان الافتراضي لوحدة المعالجة المركزية؟

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

المحلول

يعد IOMMU مفيدًا جدًا من حيث أنه يوفر مجموعة من سجلات التعيين. يمكن أن يظهر أي ذاكرة فعلية في نطاق العنوان الذي يمكن الوصول إليه بواسطة جهاز ، ويمكن أن يتسبب في أن تبدو مخازن المؤقتة المبعثرة جسديًا متجاورة للأجهزة أيضًا. هذا ليس جيدًا لبطاقات PCI/PCI-Express الثالثة أو الآلات البعيدة التي تحاول الوصول إلى الإزاحة المادية الخام ل GPU NVIDIA ، لأن هذا قد لا يؤدي إلى لا في الحقيقة الوصول إلى المناطق المقصودة للذاكرة أو تثبيط/تقييد هذه الوصول على أساس لكل بطاقة بواسطة وحدة IOMMU. يجب أن يكون هذا معاقًا ، إذن ، لأن

"RDMA لـ gpudirect تعتمد حاليًا على جميع العناوين المادية هي نفسها من وجهة نظر أجهزة PCI."

-نفيديا ، اعتبارات تصميم RDMA و GPUDIRECT

عندما تحاول برامج التشغيل استخدام مناطق MMU ومجهزة CPU الخاصة بالذاكرة المعينة I/O (MMIO) للاستخدام داخل مساحة kernel ، فإنها عادة ما تحتفظ بالعنوان الذي تم إرجاعه من رسم خرائط الذاكرة إلى أنفسهم. نظرًا لأن كل سائق يعمل ضمن سياقه أو مساحة الاسم الخاصة به ، فإن تبادل هذه التعيينات بين سائقي (سائقو) NVIDIA وسائقي بائعين من الطرف الثالث الذين يرغبون -خاص إذا تختلف برامج التشغيل بشكل كبير بين المنتجات من الطرف الثالث). أيضًا ، لا تملك أنظمة التشغيل اليوم حاليًا أي حل جيد لتبادل تعيينات MMIO بين السائقين ، وبالتالي تصدر NVIDIA العديد من الوظائف التي تتيح لبرامج تشغيل الطرف الثالث الوصول بسهولة إلى هذه المعلومات من داخل مساحة kernel ، نفسها.

تفرض Nvidia استخدام "العنونة المادية" للوصول إلى كل بطاقة عبر RDMA لـ GPUDIRECT. هذا يبسط بشكل كبير عملية نقل البيانات من جهاز كمبيوتر إلى ناقل PCI-Express لنظام عن بُعد باستخدام مخطط العنوان الفعلي لهذا الجهاز دون الحاجة إلى القلق بشأن المشكلات المتعلقة بالعناوين الافتراضية (مثل حل العناوين الافتراضية على العناوين المادية). كل بطاقة لها عنوان فعلي يقيم فيه ويمكن الوصول إليه في هذا الإزاحة ؛ يجب إضافة جزء صغير من المنطق فقط إلى سائق الطرف الثالث الذي يحاول إجراء عمليات RDMA. وأيضًا ، تعد سجلات العناوين الأساسية 32 أو 64 بت جزءًا من مساحة تكوين PCI القياسية ، وبالتالي يمكن بسهولة الحصول على العنوان الفعلي للبطاقة بمجرد القراءة من شريطه بدلاً من الاضطرار إلى الحصول على عنوان معين تم الحصول عليه من برنامج تشغيل NVIDIA عند إرفاق البطاقة. العنوان الافتراضي العالمي لـ NVIDIA (UVA) يعتني بتعيينات العنوان المادي المذكور أعلاه إلى منطقة ذاكرة تبدو مضمنة على ما يبدو مساحة المستخدم التطبيقات ، مثل ذلك:

CUDA Virtual Address Space

تنقسم مناطق الذاكرة هذه إلى ثلاثة أنواع: وحدة المعالجة المركزية و GPU و Free ، والتي تم توثيقها جميعًا هنا.

العودة إلى حالة الاستخدام الخاصة بك ، على الرغم من ذلك: بما أنك في مساحة المستخدم, ، ليس لديك وصول مباشر إلى مساحة العنوان الفعلي للنظام ، وربما تكون العناوين التي تستخدمها عناوين افتراضية توفرها لك UVA من NVIDIA. على افتراض عدم وجود تخصيصات سابقة ، يجب أن يكون تخصيص الذاكرة الخاص بك موجودًا عند الإزاحة +0x00000000 ، مما سيؤدي إلى رؤية نفس إزاحة وحدة معالجة الرسومات ، نفسها. إذا كنت تريد تخصيص مخزن مؤقت ثانٍ ، أتصور أنك سترى هذا المخزن المؤقت يبدأ مباشرة بعد نهاية المخزن المؤقت الأول (عند الإزاحة +0x00100000 من القاعدة العنوان الافتراضي من وحدة معالجة الرسومات في حالتك من تخصيص 1 ميغابايت).

لو كنت في kernel-space, ، ومع ذلك ، وكانت تكتب سائقًا لبطاقة شركتك لاستخدام RDMA لـ GPUDIRECT ، يمكنك استخدام العناوين المادية 32 أو 64 بت تم تعيينها في وحدة معالجة الرسومات من قبل BIOS و/OR للنظام إلى RDMA مباشرة من وإلى GPU ، نفسها.

بالإضافة إلى ذلك ، قد يكون من المفيد الإشارة إلى أن جميع محركات DMA لا تدعم في الواقع عناوين افتراضية للتحويلات - في الواقع ، يتطلب معظمها عناوين مادية ، مثل التعامل مع العناوين الافتراضية من محرك DMA يمكن أن تصبح معقدة (صفحة 7) ، وبالتالي فإن العديد من محركات DMA تفتقر إلى الدعم لهذا.

للإجابة على السؤال من عنوان المنشور الخاص بك ، على الرغم من: NVIDIA حاليًا تدعم فقط العنونة المادية لـ RDMA+GPUDIRECT في مساحة kernel. إلى عن على مساحة المستخدم التطبيقات ، ستستخدم دائمًا العنوان الظاهري ل GPU المقدمة لك من قبل UVA من NVIDIA ، والتي هي في مساحة العنوان الظاهري لوحدة المعالجة المركزية.


فيما يتعلق بتطبيقك ، إليك تفاصيل مبسطة للعملية التي يمكنك القيام بها لعمليات RDMA:

  1. لك مساحة المستخدم يقوم التطبيق بإنشاء مخازن مؤقتة ، والتي تقع في نطاق مساحة العنوان الافتراضية الموحدة التي توفرها NVIDIA (العناوين الظاهرية).
  2. إجراء مكالمة إلى cuPointerGetAttribute(...) للحصول على الرموز الرموز P2P ؛ هذه الرموز تتعلق بالذاكرة داخل سياق CUDA.
  3. أرسل كل هذه المعلومات إلى kernel-space بطريقة ما (مثل IOCTL ، اقرأ/اكتب إلى برنامج التشغيل الخاص بك ، إلخ). على الأقل ، ستحتاج إلى هذه الأشياء الثلاثة في النهاية kernel-space سائق:
    • تم إرجاع الرمز المميز لـ P2P بواسطة cuPointerGetAttribute(...)
    • العنوان الافتراضي UVA (ES) من المخزن المؤقت (s)
    • حجم المخزن المؤقت (ق)
  4. قم الآن بترجمة تلك العناوين الافتراضية إلى عناوينها المادية المقابلة عن طريق استدعاء وظائف مساحة kernel kernel ، حيث يتم الاحتفاظ بهذه العناوين في جداول صفحات NVIDIA ويمكن الوصول إليها مع تصدير NVIDIA من Function ، مثل: nvidia_p2p_get_pages(...), nvidia_p2p_put_pages(...), ، و nvidia_p2p_free_page_table(...).
  5. استخدم هذه العناوين المادية التي تم الحصول عليها في الخطوة السابقة لتهيئة محرك DMA الخاص بك والتي ستتعامل مع تلك المخازن المؤقتة.

يمكن العثور على تفسير أكثر تعمقا لهذه العملية هنا.

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