Parallelu Luau

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

ด้วยโมเดลการเขียนโปรแกรม Parallelu Luau คุณสามารถรันโค้ดบนหลายเธรดพร้อมกัน ซึ่งสามารถปรับปรุงประสิทธิภาพของประสบการณ์ของคุณได้ เมื่อคุณขยายประสบการณ์ของคุณด้วยเนื้อหามากขึ้น คุณสามารถนำโมเดลนี้มาใช้เพื่อช่วยรักษาประสิทธิภาพและความปลอดภัยของสคริปต์ Luau ของคุณ

โมเดลการเขียนโปรแกรมขนาน

โดยค่าเริ่มต้น สคริปต์จะถูกประมวลผลตามลำดับ หากประสบการณ์ของคุณมีตรรกะหรือเนื้อหาที่ซับซ้อน เช่น ตัวละครที่ไม่ใช่ผู้เล่น (NPCs), การตรวจสอบความถูกต้องของเรย์แคสติ้ง และการสร้างแบบอัตโนมัติ การประมวลผลตามลำดับอาจทำให้เกิดความล่าช้าสำหรับผู้ใช้ของคุณ ด้วยโมเดลการเขียนโปรแกรมขนาน คุณสามารถ แบ่งงานออกเป็นสคริปต์หลาย ๆ ตัว และรันพร้อมกันได้ ซึ่งทำให้โค้ดของคุณรันได้เร็วขึ้น ซึ่งช่วยปรับปรุงประสบการณ์ของผู้ใช้

โมเดลการเขียนโปรแกรมขนานยังเพิ่มข้อดีด้านความปลอดภัยให้กับโค้ดของคุณ โดยการแบ่งโค้ดออกเป็นหลายเธรด เมื่อคุณแก้ไขโค้ดในเธรดหนึ่ง มันจะไม่กระทบต่อโค้ดอื่น ๆ ที่หมุนอยู่ในขนาน สิ่งนี้ช่วยลดความเสี่ยงในการมีบั๊กหนึ่งในโค้ดของคุณทำให้ประสบการณ์ทั้งหมดเสียหาย และลดเวลาล่าช้าสำหรับผู้ใช้ในเซิร์ฟเวอร์สดเมื่อคุณกดอัปเดต

การนำโมเดลการเขียนโปรแกรมแบบขนานมาประยุกต์ใช้ไม่ได้หมายความว่าคุณต้องใส่ทุกอย่างลงในหลายเธรด ตัวอย่างเช่น การตรวจสอบความถูกต้องของเรย์แคสติ้ง ฝั่งเซิร์ฟเวอร์ จะตั้งค่าผู้ใช้แต่ละคนเป็นเหตุการณ์ระยะไกลในขนาน แต่ยังคงต้องการให้โค้ดเริ่มต้นทำงานเรียงโดยเพื่อเปลี่ยนแปลงคุณสมบัติทั่วโลก ซึ่งเป็นรูปแบบที่พบได้ทั่วไปในการประมวลผลแบบขนาน

ส่วนใหญ่คุณต้องรวมระยะเวลาการประมวลผลแบบเรียงและแบบขนานเพื่อนำไปสู่ผลลัพธ์ที่ต้องการ เนื่องจากปัจจุบันมีบางการดำเนินการที่ไม่รองรับการทำงานขนานซึ่งอาจทำให้สคริปต์ไม่สามารถทำงานได้ เช่น การแก้ไขอินสแตนซ์ในระยะเวลาขนาน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับระดับการใช้งานของ API ในโหมดขนาน ดูที่ ความปลอดภัยของเธรด.

แบ่งโค้ดออกเป็นหลายเธรด

หากต้องการรันสคริปต์ของประสบการณ์ของคุณในหลายเธรดพร้อมกัน คุณต้องแบ่งเป็นชิ้นส่วนที่มีเหตุผลภายใต้ นักแสดง ต่าง ๆ ใน โมเดลข้อมูล นักแสดงจะแสดงโดยอินสแตนซ์ Actor ที่สืบทอดมาจาก DataModel พวกเขาทำหน้าที่เป็นหน่วยของการแยกการประมวลผลที่แจกจ่ายภาระไปยังหลายคอร์ที่ทำงานในเวลาเดียวกัน

วางอินสแตนซ์นักแสดง

คุณสามารถวางนักแสดงในภาชนะที่เหมาะสมหรือใช้พวกเขาเพื่อแทนที่ประเภทอินสแตนซ์ระดับบนสุดของเอนทิตี 3D ของคุณ เช่น NPCs และเรย์แคสเตอร์ จากนั้นเพิ่มสคริปต์ที่สอดคล้องกัน

ตัวอย่างของสคริปต์ภายใต้ดาราราศี

ในสถานการณ์ส่วนใหญ่ คุณไม่ควรวางนักแสดงเป็นบุตรของนักแสดงตัวอื่นในโมเดลข้อมูล อย่างไรก็ตาม หากคุณตัดสินใจที่จะวางสคริปต์ซึ่งซ้อนอยู่ภายในนักแสดงหลายตัวตามกรณีการใช้งานเฉพาะของคุณ สคริปต์จะถูกเป็นเจ้าของโดยนักแสดงบรรพบุรุษที่ใกล้ที่สุด

ต้นไม้ของนักแสดงและสคริปต์ที่แสดงว่าสคริปต์นั้นเป็นเจ้าของโดยนักแสดงที่ใกล้ที่สุด

ปรับเวลาเธรด

แม้ว่าการวางสคริปต์ภายใต้นักแสดงจะทำให้พวกเขามีความสามารถในการประมวลผลขนาน แต่ด้วยค่าเริ่มต้น โค้ดยังคงทำงานบนเธรดเดียวเรียงตามลำดับ ซึ่งไม่ช่วยปรับปรุงประสิทธิภาพการทำงานของรันไทม์ คุณต้องเรียกใช้ task.desynchronize() ซึ่งเป็นฟังก์ชันที่สามารถหยุดชะงักได้ที่ระงับการดำเนินการของโครูทีนปัจจุบันเพื่อเรียกใช้โค้ดในรูปแบบขนานและกลับมาทำงานต่อในโอกาสการทำงานในรูปแบบขนานครั้งถัดไป เพื่อเปลี่ยนสคริปต์กลับไปยังการประมวลผลแบบเรียงลำดับ ให้เรียกใช้ task.synchronize().

ซึ่งคุณสามารถใช้ RBXScriptSignal:ConnectParallel() เมื่อต้องการกำหนดเวลาสัญญาณเพื่อเรียกใช้โค้ดของคุณในรูปแบบขนานทันทีเมื่อมีการทริกเกอร์ คุณไม่จำเป็นต้องเรียกใช้ task.desynchronize() ข้างในสัญญาณ Callback.

ปรับเวลาเธรด

local RunService = game:GetService("RunService")
RunService.Heartbeat:ConnectParallel(function()
... -- โค้ดพร้อมขนานซึ่งคำนวณการอัปเดตสถานะ
task.synchronize()
... -- โค้ดเรียงที่เปลี่ยนแปลงสถานะของอินสแตนซ์
end)

สคริปต์ที่เป็นส่วนหนึ่งของนักแสดงเดียวกันจะทำงานเรียงตามลำดับเมื่อเปรียบเทียบกัน ดังนั้นคุณต้องมีนักแสดงหลายคน ตัวอย่างเช่น หากคุณใส่สคริปต์ที่เปิดใช้งานขนานทั้งหมดสำหรับ NPC ของคุณในนักแสดงตัวเดียว พวกเขายังคงทำงานเรียงตามลำดับในเธรดเดียว แต่ถ้าคุณมีนักแสดงหลายตัวสำหรับตรรกะ NPC ที่แตกต่างกัน แต่ละตัวจะทำงานในขนานในเธรดของตนเอง สำหรับข้อมูลเพิ่มเติม ดูที่ แนวทางปฏิบัติที่ดีที่สุด.

โค้ดขนานในนักแสดงที่ทำงานเรียงตามลำดับในเธรดเดียว
โค้ดขนานในนักแสดงที่ทำงานพร้อมกันในหลายเธรด

ความปลอดภัยของเธรด

ระหว่างการประมวลผลขนาน คุณสามารถเข้าถึงอินสแตนซ์ส่วนใหญ่ของลำดับ DataModel ตามปกติ แต่คุณสมบัติและฟังก์ชันบางอย่างของ API ไม่ปลอดภัยในการอ่านหรือเขียน หากคุณใช้พวกเขาในโค้ดขนานของคุณ เอนจิ้น Roblox สามารถตรวจจับและป้องกันการเข้าถึงเหล่านี้ได้โดยอัตโนมัติ

สมาชิก API มีระดับความปลอดภัยของเธรดที่บ่งบอกว่าคุณสามารถใช้พวกเขาในโค้ดขนานของคุณได้หรือไม่และอย่างไร ตามตารางต่อไปนี้:

ระดับความปลอดภัยสำหรับคุณสมบัติสำหรับฟังก์ชัน
ไม่ปลอดภัยไม่สามารถอ่านหรือเขียนในขนานได้ไม่สามารถเรียกใช้ในขนานได้
อ่านขนานสามารถอ่านได้แต่ไม่สามารถเขียนในขนานได้N/A
ปลอดภัยในท้องถิ่นสามารถใช้ภายในนักแสดงเดียวกัน; สามารถอ่านได้แต่ไม่สามารถเขียนโดย Actors อื่น ๆ ในลักษณะขนานได้สามารถเรียกใช้ภายในนักแสดงเดียวกัน; ไม่สามารถเรียกใช้โดย Actors อื่น ๆ ในลักษณะขนานได้
ปลอดภัยสามารถอ่านและเขียนได้สามารถเรียกใช้ได้

คุณสามารถหาตราสัญลักษณ์ความปลอดภัยของเธรดสำหรับสมาชิก API ได้ใน API reference เมื่อใช้งานพวกเขาคุณยังควรพิจารณาว่าการเรียก API หรือการเปลี่ยนแปลงสถานะอาจมีปฏิสัมพันธ์ระหว่างเธรดขนาน โดยทั่วไปมันปลอดภัยสำหรับนักแสดงหลายตัวที่จะอ่านข้อมูลเดียวกันจากนักแสดงอื่น แต่ไม่เปลี่ยนแปลงสถานะของนักแสดงอื่น

การสื่อสารข้ามเธรด

ในบริบทหลายเธรด คุณยังสามารถอนุญาตให้สคริปต์ในนักแสดงที่แตกต่างกันสื่อสารกันเพื่อแลกเปลี่ยนข้อมูล ประสานงานงาน และซิงโครไนซ์กิจกรรม เอนจินสนับสนุนกลไกต่อไปนี้สำหรับการสื่อสารข้ามเธรด:

คุณสามารถสนับสนุนกลไกหลายสัญญาณเพื่อรองรับความต้องการในการสื่อสารข้ามเธรดของคุณ ตัวอย่างเช่น คุณสามารถส่งตารางที่ใช้ร่วมกันผ่าน API การส่งข้อความนักแสดง

การส่งข้อความนักแสดง

API การส่งข้อความนักแสดง อนุญาตให้สคริปต์ ไม่ว่าจะในบริบทเรียงลำดับหรือขนาน ส่งข้อมูลไปยังนักแสดงในโมเดลข้อมูลเดียวกัน การสื่อสารผ่าน API นี้เป็นแบบอะซิงโครนัส ซึ่งผู้ส่งจะไม่บล็อกจนกว่าผู้รับจะได้รับข้อความ

เมื่อส่งข้อความโดยใช้ API นี้ คุณต้องกำหนด หัวข้อ สำหรับการจำแนกประเภทข้อความ แต่ละข้อความสามารถส่งไปยังนักแสดงตัวเดียว แต่ที่นักแสดงนั้นสามารถมีการประชุมหลายรายการที่ผูกกับข้อความได้เท่านั้น สคริปต์ที่เป็นทายาทของนักแสดงเท่านั้นที่สามารถรับข้อความได้

API มีวิธีการดังต่อไปนี้:

  • Actor:SendMessage() สำหรับการส่งข้อความไปยังนักแสดง
  • Actor:BindToMessage() สำหรับการผูกคอลแบ็ก Luau เข้ากับข้อความที่มีหัวข้อที่กำหนดในบริบทเรียงลำดับ
  • Actor:BindToMessageParallel() สำหรับการผูกคอลแบ็ก Luau เข้ากับข้อความที่มีหัวข้อที่กำหนดในบริบทขนาน

ตัวอย่างต่อไปนี้แสดงถึงวิธีการใช้ Actor:SendMessage() เพื่อตั้งค่าหัวข้อและส่งข้อความจากฝั่งผู้ส่ง:

ตัวอย่างผู้ส่งข้อความ

local Workspace = game:GetService("Workspace")
-- ส่งข้อความสองข้อความไปยังนักแสดงที่ทำงานด้วยหัวข้อ "Greeting"
local workerActor = Workspace.WorkerActor
workerActor:SendMessage("Greeting", "Hello World!")
workerActor:SendMessage("Greeting", "Welcome")
print("ส่งข้อความแล้ว")

ตัวอย่างต่อไปนี้แสดงถึงวิธีการใช้ Actor:BindToMessageParallel() เพื่อผูกคอลแบ็กสำหรับหัวข้อเฉพาะในบริบทขนานจากฝั่งผู้รับ:

ตัวอย่างผู้รับข้อความ

-- รับนักแสดงที่สคริปต์นี้อยู่ภายใต้
local actor = script:GetActor()
-- ผูกคอลแบ็กสำหรับหัวข้อข้อความ "Greeting"
actor:BindToMessageParallel("Greeting", function(greetingString)
print(actor.Name, "-", greetingString)
end)
print("ผูกข้อความแล้ว")

ตารางที่ใช้ร่วมกัน

SharedTable เป็นโครงสร้างข้อมูลคล้ายตารางที่เข้าถึงได้จากสคริปต์ที่รันภายใต้หลายนักแสดง มันมีความสำคัญในสถานการณ์ที่มีข้อมูลจำนวนมากและต้องการสถานะที่ใช้ร่วมกันระหว่างเธรดหลายตัว สำหรับตัวอย่าง เมื่อมีนักแสดงหลายตัวทำงานในสถานะโลกทั่วไปที่ไม่ได้เก็บอยู่ในโมเดลข้อมูล

การส่งตารางที่ใช้ร่วมกันไปยังนักแสดงอื่นจะไม่สร้างสำเนาของข้อมูล แทนที่ตารางที่ใช้ร่วมกันช่วยให้มีการอัปเดตที่ปลอดภัยและเป็นอะตอมโดยสคริปต์หลายตัวในเวลาเดียวกัน ทุกการอัปเดตที่ทำโดยนักแสดงตัวหนึ่งในตารางที่ใช้ร่วมกันจะปรากฏให้เห็นทันทีต่อทุกนักแสดง ตารางที่ใช้ร่วมกันยังสามารถถูกโคลนในกระบวนการที่มีประสิทธิภาพในทรัพยากรที่ใช้การแบ่งปันโครงสร้างแทนการคัดลอกข้อมูลพื้นฐาน

การสื่อสารโดยตรงในโมเดลข้อมูล

คุณยังสามารถอำนวยความสะดวกในการสื่อสารระหว่างหลายเธรดโดยตรงโดยใช้โมเดลข้อมูลซึ่งนักแสดงที่แตกต่างกันสามารถเขียนและอ่านคุณสมบัติหรือแอตทริบิวต์ได้ในภายหลัง อย่างไรก็ตามเพื่อรักษาความปลอดภัยของเธรด สคริปต์ที่ทำงานในส่วนขนานจะไม่สามารถเขียนไปยังโมเดลข้อมูลได้ ดังนั้น การใช้งานโมเดลข้อมูลโดยตรงเพื่อการสื่อสารจึงมีข้อจำกัดและอาจบังคับให้สคริปต์ทำการซิงโครไนซ์บ่อยซึ่งอาจส่งผลต่อประสิทธิภาพของสคริปต์ของคุณ

ตัวอย่าง

การตรวจสอบความถูกต้องของเรย์แคสติ้งฝั่งเซิร์ฟเวอร์

สำหรับการต่อสู้และประสบการณ์การต่อสู้ คุณจำเป็นต้องเปิดใช้งาน เรย์แคสติ้ง สำหรับอาวุธของผู้ใช้ ด้วยลูกค้าจำลองอาวุธเพื่อให้ได้ความล่าช้าที่ดี เซิร์ฟเวอร์จะต้องยืนยันการโจมตีซึ่งเกี่ยวข้องกับการทำเรย์แคสและการคำนวณเชิงพฤติกรรมที่คำนวณความเร็วที่คาดการณ์ของตัวละคร และดูพฤติกรรมในอดีต

แทนที่จะใช้สคริปต์ศูนย์รวมภายในที่เชื่อมต่อกับเหตุการณ์ระยะไกลที่คลient ใช้ในการสื่อสารข้อมูลการโจมตี คุณสามารถทำการตรวจสอบการโจมตีแต่ละครั้งในด้านเซิร์ฟเวอร์ได้ในขนานโดยทุกตัวละครของผู้ใช้มีเหตุการณ์ระยะไกลที่แยกต่างหาก

สคริปต์ด้านเซิร์ฟเวอร์ที่ทำงานภายใต้ Actor ของตัวละครนั้นเชื่อมต่อกับเหตุการณ์ระยะไกลนี้โดยใช้การเชื่อมต่อขนานเพื่อรันตรรกะที่เกี่ยวข้องเพื่อยืนยันการโจมตี หากตรรกะพบนการยืนยันการโจมตี ความเสียหายจะถูกหักซึ่งเกี่ยวข้องกับการเปลี่ยนแปลงคุณสมบัติ ดังนั้นมันจึงทำงานเรียงตามลำดับในตอนแรก


local Workspace = game:GetService("Workspace")
local tool = script.Parent.Parent
local remoteEvent = Instance.new("RemoteEvent") -- สร้างเหตุการณ์ระยะไกลใหม่และบริบทให้กับเครื่องมือ
remoteEvent.Name = "RemoteMouseEvent" -- เปลี่ยนชื่อเพื่อให้สคริปต์ท้องถิ่นสามารถมองหา
remoteEvent.Parent = tool
local remoteEventConnection -- สร้างการอ้างอิงสำหรับการเชื่อมต่อของเหตุการณ์ระยะไกล
-- ฟังก์ชันที่ฟังเหตุการณ์ระยะไกล
local function onRemoteMouseEvent(player: Player, clickLocation: CFrame)
-- SERIAL: รันโค้ดตั้งค่าในลำดับ
local character = player.Character
-- เพิกเฉยต่อตัวละครของผู้ใช้ขณะทำเรย์แคสติ้ง
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = { character }
-- PARALLEL: ทำการเรย์แคสในขนาน
task.desynchronize()
local origin = tool.Handle.CFrame.Position
local epsilon = 0.01 -- ใช้เพื่อขยายเรย์ออกไปเล็กน้อยเนื่องจากสถานที่คลิกอาจมีการเปลี่ยนแปลงเล็กน้อยจากวัตถุ
local lookDirection = (1 + epsilon) * (clickLocation.Position - origin)
local raycastResult = Workspace:Raycast(origin, lookDirection, params)
if raycastResult then
local hitPart = raycastResult.Instance
if hitPart and hitPart.Name == "block" then
local explosion = Instance.new("Explosion")
-- SERIAL: โค้ดด้านล่างเปลี่ยนแปลงสถานะนอกนักแสดง
task.synchronize()
explosion.DestroyJointRadiusPercent = 0 -- ทำให้การระเบิดไม่มีอันตราย
explosion.Position = clickLocation.Position
-- นักแสดงหลายคนอาจได้รับส่วนเดียวกันในเรย์แคสและตัดสินใจทำลายมัน
-- นี้ปลอดภัยอย่างสมบูรณ์ แต่จะทำให้การระเบิดสองครั้งเกิดขึ้นในครั้งเดียวแทนที่เป็นหนึ่ง
-- ต่อไปนี้เป็นการตรวจสอบขั้นสุดท้ายว่าการดำเนินการมายังจุดนี้ก่อน
if hitPart.Parent then
explosion.Parent = Workspace
hitPart:Destroy() -- ทำลายมัน
end
end
end
end
-- เชื่อมต่อสัญญาณในลำดับในตอนแรกเนื่องจากโค้ดบางตัวไม่สามารถทำงานในขนาน
remoteEventConnection = remoteEvent.OnServerEvent:Connect(onRemoteMouseEvent)

การสร้างภูมิประเทศเชิงพรรณนาฝั่งเซิร์ฟเวอร์

เพื่อสร้างโลกกว้างสำหรับประสบการณ์ของคุณ คุณสามารถทำให้โลกเต็มไปด้วยข้อมูลแบบพลศาสตร์ การสร้างเชิงพรรณนามักสร้างชิ้นส่วนภูมิประเทศที่เป็นอิสระ โดยที่ผู้สร้างทำการคำนวณซับซ้อนสำหรับการวางวัตถุ การใช้วัสดุ และการเติม voxel การรันโค้ดการสร้างในขนานสามารถเพิ่มประสิทธิภาพของกระบวนการได้ ตัวอย่างโค้ดต่อไปนี้แสดงถึงตัวอย่าง


-- การประมวลผลขนานต้องการการใช้ดาราราศี
-- สคริปต์นี้โคลนตัวเอง; ตัวดั้งเดิมเริ่มกระบวนการ ในขณะที่โคลนทำหน้าที่เป็นผู้ทำงาน
local Workspace = game:GetService("Workspace")
local actor = script:GetActor()
if actor == nil then
local workers = {}
for i = 1, 32 do
local actor = Instance.new("Actor")
script:Clone().Parent = actor
table.insert(workers, actor)
end
-- วางงานทุกนักแสดงภายใต้ตนเอง
for _, actor in workers do
actor.Parent = script
end
-- สั่งให้นักแสดงสร้างภูมิประเทศโดยการส่งข้อความ
-- ในตัวอย่างนี้ นักแสดงได้รับเลือกแบบสุ่ม
task.defer(function()
local rand = Random.new()
local seed = rand:NextNumber()
local sz = 10
for x = -sz, sz do
for y = -sz, sz do
for z = -sz, sz do
workers[rand:NextInteger(1, #workers)]:SendMessage("GenerateChunk", x, y, z, seed)
end
end
end
end)
-- ออกจากสคริปต์เดิม; โค้ดที่เหลือทำงานในนักแสดงแต่ละตัว
return
end
function makeNdArray(numDim, size, elemValue)
if numDim == 0 then
return elemValue
end
local result = {}
for i = 1, size do
result[i] = makeNdArray(numDim - 1, size, elemValue)
end
return result
end
function generateVoxelsWithSeed(xd, yd, zd, seed)
local matEnums = {Enum.Material.CrackedLava, Enum.Material.Basalt, Enum.Material.Asphalt}
local materials = makeNdArray(3, 4, Enum.Material.CrackedLava)
local occupancy = makeNdArray(3, 4, 1)
local rand = Random.new()
for x = 0, 3 do
for y = 0, 3 do
for z = 0, 3 do
occupancy[x + 1][y + 1][z + 1] = math.noise(xd + 0.25 * x, yd + 0.25 * y, zd + 0.25 * z)
materials[x + 1][y + 1][z + 1] = matEnums[rand:NextInteger(1, #matEnums)]
end
end
end
return {materials = materials, occupancy = occupancy}
end
-- ผูกคอลแบ็กให้ถูกเรียกในบริบทการประมวลผลขนาน
actor:BindToMessageParallel("GenerateChunk", function(x, y, z, seed)
local voxels = generateVoxelsWithSeed(x, y, z, seed)
local corner = Vector3.new(x * 16, y * 16, z * 16)
-- ขณะนี้ WriteVoxels() ต้องถูกเรียกในระยะเวลาที่เรียง
task.synchronize()
Workspace.Terrain:WriteVoxels(
Region3.new(corner, corner + Vector3.new(16, 16, 16)),
4,
voxels.materials,
voxels.occupancy
)
end)

แนวทางปฏิบัติที่ดีที่สุด

เพื่อให้ได้ประโยชน์สูงสุดจากการโปรแกรมแบบขนาน โปรดทำตามแนวทางปฏิบัติดังต่อไปนี้เมื่อเพิ่มโค้ด Luau ของคุณ:

  • หลีกเลี่ยงการคำนวณนาน — แม้ว่าจะขนานอยู่ การคำนวณยาว ๆ สามารถบล็อกการประมวลผลของสคริปต์อื่น ๆ และทำให้เกิดความล่าช้า หลีกเลี่ยงการใช้การเขียนโปรแกรมแบบขนานเพื่อจัดการกับการคำนวณที่ยาวและไม่มีการหยุดชะงักเป็นจำนวนมาก

    แ diagram demonstrating how overloading the parallel execution phase can still cause lag
  • ใช้จำนวน นักแสดงที่เหมาะสม — สำหรับประสิทธิภาพที่ดีที่สุด ใช้ Actors มากขึ้น แม้ว่าอุปกรณ์จะมีคอร์น้อยกว่านักแสดง แต่การแบ่งละเอียดยังช่วยให้มีการ กระจายภาระที่มีประสิทธิภาพระหว่างคอร์

    การสาธิตว่าการใช้ นักแสดงที่มากกว่าจะช่วยกระจายภาระระหว่างคอร์

    นี่ไม่ได้หมายความว่าคุณควรใช้ Actors ให้มากที่สุด คุณยังควรแบ่งโค้ดออกเป็น Actors ตามหน่วยตรรกะ แทนที่จะย้ายโค้ดที่เชื่อมต่อกันไปยัง Actors ที่แตกต่างกัน ตัวอย่างเช่น หากคุณต้องการเปิดใช้งาน การตรวจสอบความถูกต้องของเรย์แคสติ้ง ในขนาน เป็นเรื่องสมเหตุสมผลที่จะใช้ 64 Actors และมากกว่าแค่ 4 ตัว แม้ว่าคุณจะกำหนดเป้าหมายที่ระบบ 4-core นี่เป็นผลดีต่อการปรับขนาดของระบบและช่วยให้อำนวยงานกระจายตามความสามารถของฮาร์ดแวร์ที่อยู่เบื้องหลัง แต่คุณก็ไม่ควรใช้ Actors มากเกินไปจนยากต่อการบำรุงรักษา

©2026 Roblox Corporation. Roblox, โลโก้ Roblox และ Powering Imagination เป็นส่วนหนึ่งของเครื่องหมายการค้าที่จดทะเบียน และไม่ได้จดทะเบียนของเราในสหรัฐฯ และประเทศอื่นๆ