في الواقع ، يبدو أن الأشخاص الذين يكتبون جافا لا علاقة لهم بوحدة المعالجة المركزية. على الأكثر ، له علاقة بكيفية تشغيل وحدة المعالجة المركزية وكيفية تعيين عدد المواضيع التي ذكرناها سابقًا. ومع ذلك ، فإن هذه الخوارزمية هي مجرد مرجع. تتطلب العديد من السيناريوهات المختلفة وسائل عملية لحلها. علاوة على ذلك ، بعد تشغيل وحدة المعالجة المركزية ، سنفكر أيضًا في كيفية جعل وحدة المعالجة المركزية ليست ممتلئة. هاها ، البشر ، هذا كل شيء. هاها ، حسنًا ، هذا المقال يدور حول أشياء أخرى. ربما لا تكابة عن رمز في جافا. انتبه إلى وحدة المعالجة المركزية ، لأن إرضاء العمل هو أول شيء مهم. إذا كنت ترغب في تحقيق مستوى الإطار وتزويد الإطار بالعديد من ذاكرة التخزين المؤقت للبيانات المشتركة ، فيجب أن يكون هناك العديد من مشاكل طلب البيانات في الوسط. بالطبع ، توفر Java العديد من فئات الحزم المتزامنة ، ويمكنك استخدامها ، ولكن كيف يتم ذلك داخليًا ، يجب عليك فهم التفاصيل لاستخدامها بشكل أفضل ، وإلا من الأفضل عدم استخدامه. قد لا تشرح هذه المقالة هذه المحتويات على أنها التركيز ، لأنه مثل حزب العنوان: نريد التحدث عن وحدة المعالجة المركزية ، هاها.
يقال الشيء نفسه ، يبدو أن جافا لا علاقة لها بوحدة المعالجة المركزية ، لذلك دعونا نتحدث عما يحدث الآن ؛
1. عند مواجهة عنصر مشترك ، فإن فكرتنا الأولى هي ضمان عمليات القراءة المتسقة من خلال متقلبة ، أي الرؤية المطلقة. تعني ما يسمى الرؤية أنه في كل مرة تريد استخدام هذه البيانات ، لن تستخدم وحدة المعالجة المركزية أي محتوى ذاكرة التخزين المؤقت وسوف تحصل على بيانات من الذاكرة. لا تزال هذه العملية صالحة لعمليات وحدات المعالجة المركزية المتعددة ، مما يعني أن وحدة المعالجة المركزية والذاكرة تتم مزامنتها في هذا الوقت. ستقوم وحدة المعالجة المركزية بإصدار تعليمات تجميع مماثلة لـ Lock Addl مثل الحافلة ، +0 ولكن لن تفعل أي شيء بالنسبة إلى أي شيء. ومع ذلك ، بمجرد اكتمال التعليمات ، لن تؤثر العمليات اللاحقة على وصول مؤشرات الترابط الأخرى لهذا العنصر ، وهي الرؤية المطلقة التي يمكن أن تحققها ، ولكن لا يمكنها تنفيذ عمليات متسقة. وهذا يعني ، ما لا يمكن أن تحققه المتقلبة هو اتساق العمليات مثل I ++ (التزامن تحت مؤشرات ترابط متعددة) ، لأن عمليات i ++ تتحلل إلى:
int tmp = i ؛ tmp = tmp + 1 ؛ i = tmp ؛
يتم الانتهاء من هذه الخطوات الثلاث. من هذه النقطة ، يمكنك أيضًا أن ترى لماذا يمكن لـ i ++ القيام بأشياء أخرى أولاً ثم إضافة 1 إلى نفسها ، لأنه يتم تعيين القيمة لمتغير آخر.
2. إذا كنا نريد استخدام اتساق التزامن متعدد الخيوط ، فنحن بحاجة إلى استخدام آلية القفل. في الوقت الحاضر ، يمكن لأشياء مثل الذرية* تلبية هذه المتطلبات بشكل أساسي. يتم توفير العديد من طرق الطبقة غير الآمنة داخليًا. من خلال مقارنة بيانات الرؤية المطلقة باستمرار ، يمكننا التأكد من أن البيانات المكتسبة محدثة ؛ بعد ذلك سنستمر في الحديث عن مسائل وحدة المعالجة المركزية الأخرى.
3. في الماضي ، لم نتمكن من تشغيل وحدة المعالجة المركزية من أجل ملئها ، لكننا لم نكن راضين بغض النظر عن كيفية تجاهلنا للتأخير بين الذاكرة ووحدة المعالجة المركزية. منذ أن ذكرنا ذلك اليوم ، سنتحدث بإيجاز عن التأخير. بشكل عام ، تحتوي وحدة المعالجة المركزية الحالية على ذاكرة التخزين المؤقت من ثلاثة مستويات ، وتختلف التأخيرات في أعمار مختلفة ، وبالتالي يمكن أن يكون الرقم المحدد فقط تقريبًا. تتأخر وحدات المعالجة المركزية اليوم بشكل عام عن 1-2Ns ، وذاكرة التخزين المؤقت من المستوى الثاني تكون عمومًا بضعة NS إلى حوالي عشرة NS ، وتكون ذاكرة التخزين المؤقت من المستوى الثالث عمومًا ما بين 30Ns و 50ns ، وسيصل الوصول إلى الذاكرة عمومًا إلى 70Ns أو حتى أكثر (يتم تطوير الكمبيوتر بسرعة كبيرة ، وهذه القيمة هي فقط للبيانات الموجودة على CPU ، للحصول على مرجع نطاق) ؛ على الرغم من أن هذا التأخير صغير جدًا ، إلا أنه على مستوى النانو ثانية ، ستجد أنه عندما يتم تقسيم البرنامج إلى عمليات تعليمية ، سيكون هناك الكثير من تفاعلات وحدة المعالجة المركزية. إذا كان تأخير كل تفاعل كبيرًا جدًا ، فسيتغير أداء النظام في هذا الوقت ؛
4. العودة إلى المتقلبة المذكورة الآن. في كل مرة تحصل على بيانات من الذاكرة ، فإنه يتخلى عن ذاكرة التخزين المؤقت. بالطبع ، إذا أصبحت أبطأ في بعض العمليات ذات الخيوط الواحدة ، فسيصبح أبطأ. في بعض الأحيان علينا القيام بذلك. حتى عمليات القراءة والكتابة تتطلب الاتساق ، وحتى كتلة البيانات بأكملها تتم مزامنتها. لا يمكننا إلا تقليل حبيبات القفل إلى حد ما ، لكن لا يمكننا الحصول على أقفال على الإطلاق. حتى مستوى وحدة المعالجة المركزية نفسها سيكون لها قيود على مستوى التعليمات.
5. العمليات الذرية على مستوى وحدة المعالجة المركزية تسمى بشكل عام الحواجز ، مع حواجز القراءة ، وحواجز الكتابة ، إلخ. يتم تشغيلها عمومًا بنقطة واحدة. عند إرسال تعليمات متعددة للبرنامج إلى وحدة المعالجة المركزية ، لا يجوز تنفيذ بعض التعليمات بترتيب البرنامج ، ويجب تنفيذ بعضها بترتيب البرنامج ، طالما أنه يمكن ضمان أن تكون متسقة في الترتيب النهائي للبرنامج. فيما يتعلق بالفرز ، سيتغير JIT أثناء وقت التشغيل ، وسيتغير مستوى تعليمات وحدة المعالجة المركزية أيضًا. السبب الرئيسي هو تحسين تعليمات وقت التشغيل لجعل البرنامج يعمل بشكل أسرع.
6. سيعمل مستوى وحدة المعالجة المركزية خط ذاكرة التخزين المؤقت على الذاكرة. سيقوم خط ذاكرة التخزين المؤقت المزعوم بقراءة قطعة من الذاكرة بشكل مستمر ، والذي يرتبط عمومًا بنموذج وحدة المعالجة المركزية والهندسة المعمارية. في الوقت الحاضر ، ستقرأ العديد من وحدات المعالجة المركزية الذاكرة المستمرة عمومًا في كل مرة ، وستكون المبكرة 32Byte ، لذلك سيكون أسرع عند عبور بعض المصفوفات (إنها بطيئة جدًا استنادًا إلى اجتياز العمود) ، ولكن هذا غير صحيح تمامًا. ما يلي سوف يقارن بعض المواقف المعاكسة.
7. إذا غيرت وحدة المعالجة المركزية البيانات ، فيجب علينا التحدث عن حالة وحدة المعالجة المركزية التي تعدل البيانات. إذا تمت قراءة جميع البيانات ، فيمكن قراءتها بالتوازي بواسطة مؤشرات ترابط متعددة ضمن وحدات المعالجة المركزية المتعددة. عند كتابة العمليات على كتل البيانات ، يكون الأمر مختلفًا. ستحتوي كتل البيانات على الحالات الحصرية والمعدلة والإبطال والمواد الأخرى ، وستفشل البيانات بشكل طبيعي بعد التعديل. عندما تقوم مؤشرات ترابط متعددة بتعديل كتلة البيانات نفسها ضمن وحدات المعالجة المركزية المتعددة ، ستحدث نسخة بيانات الناقل (QPI) بين وحدات المعالجة المركزية. بالطبع ، إذا قمنا بتعديلها إلى نفس البيانات ، فليس لدينا خيار ، ولكن عندما نعود إلى خط ذاكرة التخزين المؤقت في النقطة 6 ، تكون المشكلة أكثر إثارة للقلق. إذا كانت البيانات على نفس الصفيف ، وسيتم تخزين العناصر الموجودة في الصفيف إلى وحدة المعالجة المركزية في نفس الوقت ، فسيكون QPI من الخيوط المتعددة متكررة للغاية. في بعض الأحيان ستحدث هذه المشكلة حتى إذا تم تجميع الكائنات التي تم تجميعها على الصفيف ، مثل:
class inputInteTeger {private int value ؛ public inputInteger (int i) {this.value = i ؛}} inputInteTeger [] في هذا الوقت ، يمكنك أن ترى أن كل شيء في الأعداد الصحيحة هو كائنات ، ولا توجد سوى إشارات إلى الأشياء الموجودة على الصفيف ، لكن ترتيب الكائنات مستقل نظريًا ولن يتم تخزينه بشكل مستمر. ومع ذلك ، عندما يخصص Java ذاكرة الكائن ، غالبًا ما يتم تخصيصها بشكل مستمر في منطقة عدن. عندما تكون في الحلقة ، إذا لم يتم الوصول إلى مؤشرات ترابط أخرى ، فسيتم تخزين هذه الكائنات معًا. حتى لو كانت GC في المنطقة القديمة ، فمن المحتمل جدًا أن يتم تجميعها معًا. لذلك ، فإن طريقة تعديل المجموعة بأكملها من خلال الاعتماد على كائنات بسيطة لحل خط ذاكرة التخزين المؤقت تبدو غير موثوقة ، لأنها هي 4 بايت. إذا كان هذا الحجم هو 24 بايت في 64 بايت (يتم ملء 4Bytes) ، وضغط المؤشر هو 16 بايت ؛ وهذا يعني أن وحدة المعالجة المركزية يمكن أن تتطابق مع 3-4 كائنات في كل مرة. كيفية صنع ذاكرة التخزين المؤقت لوحدة المعالجة المركزية ، لكنها لا تؤثر على QPI للنظام. لا تفكر في إكمالها عن طريق فصل الكائنات ، لأن عملية نسخ ذاكرة GC من المحتمل أن يتم نسخها معًا. أفضل طريقة هي ملءها. على الرغم من أنها هي بعض نفايات الذاكرة ، إلا أن هذه هي الطريقة الأكثر موثوقية ، والتي تتمثل في ملء الكائن إلى 64 بايت. إذا لم يتم تمكين ضغط المؤشر ، فهناك 24Bytes ، وهناك 40 بايت في هذا الوقت. تحتاج فقط إلى إضافة 5 طويلة داخل الكائن.
الفئة inputInteger {public int value ؛ private long a1 ، a2 ، a3 ، a4 ، a5 ؛} هاها ، هذه الطريقة ريفية للغاية ، لكنها تعمل بشكل جيد للغاية. في بعض الأحيان ، عندما يتم تجميع JVM ، يجد أن هذه المعلمات لم يتم ذلك ، لذلك يتم قتلها مباشرة من أجلك. التحسين غير صالح. الطريقة بالإضافة إلى الطريقة هي ببساطة تشغيل هذه المعلمات الخمسة في هيئة الطريقة (تستخدمها جميعًا) ، لكن هذه الطريقة لن تسميها أبدًا.
8. على مستوى وحدة المعالجة المركزية ، في بعض الأحيان قد لا يكون من الممكن فعل أول شيء يجب القيام به. إنه الملك. في تشغيل AtomicIntegerfieldupdater ، إذا اتصلت بـ Getanteset (صواب) في موضوع واحد ، فستجد أنه يعمل بسرعة كبيرة ، ويبدأ في التباطؤ تحت وحدة المعالجة المركزية متعددة النواة. لماذا يقال بوضوح أعلاه؟ نظرًا لأن GetAndets يتم تعديلها ومقارنتها ، ثم قم بتغييرها أولاً ، سيكون QPI مرتفعًا جدًا ، لذلك في هذا الوقت ، من الأفضل الحصول على العمليات أولاً ثم تعديلها ؛ وهي أيضًا طريقة جيدة للحصول عليها مرة واحدة. إذا كان لا يمكن الحصول عليها ، استسلم ودع المواضيع الأخرى تفعل أشياء أخرى ؛
9. في بعض الأحيان ، من أجل حل مشكلة بعض وحدة المعالجة المركزية مشغولة وغير مشغولة ، سيكون هناك العديد من الخوارزميات التي يجب حلها. على سبيل المثال ، Numa هو أحد الحلول. ومع ذلك ، بغض النظر عن الهندسة المعمارية أكثر فائدة في سيناريوهات معينة ، فقد لا تكون فعالة لجميع السيناريوهات. هناك آلية لقفل قائمة انتظار لإكمال إدارة حالة وحدة المعالجة المركزية ، ولكن هذا لديه أيضًا مشكلة خط ذاكرة التخزين المؤقت ، لأن الحالة تتغير بشكل متكرر ، وستنتج النوى من مختلف التطبيقات أيضًا بعض الخوارزميات التي يجب القيام بها من أجل التعاون مع وحدة المعالجة المركزية ، بحيث يمكن استخدام وحدة المعالجة المركزية بشكل أكثر فعالية ، مثل انتظار CLH.
هناك العديد من التفاصيل حول هذا الموضوع ، مثل تراكب الحلقات المتغيرة العادية ، ونوع متطاير ، وسلسلة ذرية* ، والتي تختلف تمامًا ؛ حلقات الصفيف متعددة الأبعاد ، والحلقات في ترتيب متخلف في خطوط عرض مختلفة ، وهناك العديد من التفاصيل ، وأنا أفهم سبب الإلهام في عملية التحسين الفعلية ؛ تفاصيل الأقفال رفيعة للغاية ودوار ، وفي المستوى السفلي من النظام ، هناك دائمًا بعض العمليات الذرية الخفيفة الوزن. بغض النظر عن من يقول أن رمزه لا يتطلب القفل ، يمكن أن يكون أفضل ما يمكن أن يكون بسيطًا مثل وحدة المعالجة المركزية فقط تنفيذ تعليمات واحدة في كل لحظة. سيكون لدى وحدات المعالجة المركزية متعددة النواة أيضًا مساحة مشتركة للتحكم في بعض المحتوى على مستوى الحافلة ، بما في ذلك مستوى القراءة ، ومستوى الكتابة ، ومستوى الذاكرة ، وما إلى ذلك في سيناريوهات مختلفة ، يتم تقليل تفاصيل القفل قدر الإمكان. أداء النظام بديهي ، وهو نتيجة طبيعية.