2012-08-30 6 views
5

मैं 64-बिट .NET प्रक्रिया के लिए MinWorkingSet और MaxWorking सेट कैसे सेट करूं?64-बिट .NET प्रक्रिया में MinWorkingSet और MaxWorkingSet को कैसे सेट करें?

पेज। इस प्रकार मैं, एक 32-बिट प्रक्रिया के लिए MinWorkingSet और MaxWorking सेट सेट कर सकते हैं:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize); 

[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern IntPtr MyGetCurrentProcess(); 

// In main(): 
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, int.MaxValue, int.MaxValue); 
+1

कोई भी कारण आप प्रबंधित एपीआई का उपयोग नहीं करते हैं? http://msdn.microsoft.com/en-us/library/system.diagnostics.process.minworkingset(v=vs.110) – rene

+0

सामान्य रूप से, यह एक बुरा विचार है क्योंकि ढांचा कार्य सेट आकार को अनुकूलित करेगा। आपकी आवश्यकता क्या है? – Maciej

+0

@Maciej हमने कार्यक्रम पर गहरे विलंबता विश्लेषण के 3 सप्ताह चलाए हैं, और हम मुलायम पृष्ठ दोषों के कारण कार्यक्रम में 250us ब्लिप देख रहे हैं। हम सॉफ्ट पेज दोषों की मात्रा को कम करने के लिए कार्य सेट आकार को बढ़ाने का प्रयास कर रहे हैं। – Contango

उत्तर

5

सभी तुम इतनी तरह अपने घोषणा बदल करना है:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, 
    long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize); 

कारण की वजह से है definition of the SetProcessWorkingSetSize function:

BOOL WINAPI SetProcessWorkingSetSize(
    _In_ HANDLE hProcess, 
    _In_ SIZE_T dwMinimumWorkingSetSize, 
    _In_ SIZE_T dwMaximumWorkingSetSize 
); 

ध्यान दें कि यह एक DWORD (के रूप में 32-बिट पूर्णांक) का उपयोग नहीं करता है, लेकिन एक SIZE_T, जो is defined as:

अधिकतम बाइट्स जो पॉइंटर इंगित कर सकता है। गिनती के लिए उपयोग करें जो एक पॉइंटर की पूरी श्रृंखला को फैलाएगा। इस प्रकार का BaseTsd.h में घोषित किया जाता है इस प्रकार है:

typedef ULONG_PTR SIZE_T; 

इसका मतलब यह है कि यह एक 64-बिट मूल्य एक long को बदल सकते हैं और 64-बिट सिस्टम पर समारोह काम करने की क्षमता है, इसलिए। इसके अलावा, MSDN की धारा "Common Visual C++ 64-bit Migration Issues" शीर्षक से:

size_t, टाइम_टी, और ptrdiff_t 64-बिट विंडोज ऑपरेटिंग सिस्टम पर 64-बिट मान हैं।

हालांकि, यह एक दुविधा का थोड़ा सा प्रस्तुत करता है, जिसमें आप मंच-विशिष्ट असेंबली संकलित नहीं करना चाहते हैं (यह एक पिटा होगा)। आप इस के आसपास DllImportAttribute class पर EntryPoint field (जो आप पहले से ही कर रहे हैं) का लाभ लेने दो विधि घोषणाओं के लिए प्राप्त कर सकते हैं:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize32(IntPtr pProcess, 
    int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize); 

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize64(IntPtr pProcess, 
    long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize); 

अब आप दो अलग-अलग हस्ताक्षर किया है। हालांकि, को जानने के लिए कॉल करने के लिए हस्ताक्षर अभी भी एक मुद्दा है। आप हर जगह सशर्त चेक नहीं रखना चाहते हैं। इसके लिए, मैं एक ऐसी विधि बनाने की अनुशंसा करता हूं जो आपके लिए चेक करता है और उसे कॉल करता है।

आप इस दृढ़ संकल्प के लिए Environment class पर Is64BitProcess property का उपयोग करना चाहेंगे। Is64BitOperatingSystem property का उपयोग न करें। आप पूर्व चाहते हैं क्योंकि 32-बिट प्रक्रिया 64-बिट ऑपरेटिंग सिस्टम पर चल सकती है, और आप यह सुनिश्चित करना चाहते हैं कि आपका कोड उस के लिए लचीला है; सिर्फ यह देखने के लिए जांचें कि ऑपरेटिंग सिस्टम 64 बिट आपको पूरी तस्वीर नहीं देता है।

+2

या आप केवल 'UIntPtr' का उपयोग कर सकते हैं और इसे पास कर सकते हैं। – Mehrdad

5

इसे पिन न करें, बस Process.CurrentProcess.MinWorkingSet संपत्ति का उपयोग करें।

बहुत अधिक बाधाएं इससे कोई फर्क नहीं पड़ता। नरम पेजिंग दोष पूरी तरह से सामान्य होते हैं और मशीन के पास पर्याप्त रैम होने पर बहुत जल्दी हल हो जाता है। मेरे लैपटॉप पर ~ 0.7 माइक्रोसॉन्ड लेता है।आप उनसे नहीं बच सकते हैं, यह care_paged वर्चुअल मेमोरी ऑपरेटिंग सिस्टम जैसे विंडोज का व्यवहार है। बहुत सस्ते, जब तक a free page readily available है।

लेकिन यदि यह आपको प्रोग्राम प्रदर्शन "ब्लिप" करता है तो आपको संभावना पर विचार करना होगा कि यह आसानी से उपलब्ध नहीं है और किसी अन्य प्रक्रिया में हार्ड पेज गलती को ट्रिगर किया गया है। पेजिंग गलती महंगा हो जाती है यदि रैम पेज को किसी अन्य प्रक्रिया से चोरी किया जाना चाहिए, इसकी सामग्री को पेजिंग फ़ाइल में संग्रहीत किया जाना है और इसे पहले शून्य पर रीसेट करना होगा। यह जल्दी से जोड़ सकता है, सैकड़ों माइक्रोसॉन्ड असामान्य नहीं है।

"कोई मुफ्त लंच नहीं है" का मूल कानून, आपको कम प्रक्रियाओं को चलाने या अधिक रैम खरीदने की आवश्यकता है। बाद के विकल्प के साथ शेन विकल्प, 8 गीगाबाइट्स आपको आज लगभग 75 रुपये वापस सेट करता है। पूरा चोरी

+0

यह एक बिल्कुल शानदार जवाब है, विशेष रूप से टिप जो पहली तत्व पहुंच है वह सॉफ्ट पेज गलती की यात्रा करता है। हम पहले शब्दकोश पर 250us सॉफ्ट पेज गलती देख रहे थे। TryAdd() कमांड। – Contango

+0

असुविधाजनक रूप से, MinWorkingSet को सेट करना .NET gen2 कचरा संग्रह को वापस नंगे हड्डियों तक ट्रिम करने से रोकता है (मेरे अपडेट किए गए उत्तर में उपरोक्त आरेख देखें)। – Contango

+0

मुझे लगता है कि मुझे यह काम करने के लिए SE_INC_WORKING_SET_NAME और/या SE_INC_BASE_PRIORITY_NAME सेट करना पड़ सकता है, क्योंकि GC.Collect() वैसे भी काम सेट को ट्रिम करता है। चूंकि प्रश्न का दायरा बदल गया है, मैंने http://stackoverflow.com/questions/12221541/is-there-a-way-to-expand-the-current-workingset-of-a पर एक नया प्रश्न पोस्ट किया है -process करने वाली 1GB। मुलायम पेजिंग दोषों के कारण आपको आपकी युक्तियों के लिए धन्यवाद देना चाहता हूं। – Contango

संबंधित मुद्दे