Parallel Luau

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

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

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

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

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

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

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

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

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

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

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

An example of a Script under an Actor

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

A tree of actors and scripts that shows how a script is owned by its closest actor

ปลดการซิงโครไนซ์เธรด

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ตัวอย่าง

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

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

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

สคริปต์ฝั่งเซิร์ฟเวอร์ที่ทำงานภายใต้ 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)
-- ตามลำดับ: รันโค้ดการตั้งค่าในลำดับ
local character = player.Character
-- ไม่สนใจตัวละครของผู้ใช้ในขณะที่ทำการเรย์แคสติ้ง
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = { character }
-- ขนาน: ทำการเรย์แคสติ้งในขนาน
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")
-- ตามลำดับ: โค้ดด้านล่างนี้เปลี่ยนแปลงสถานะนอกนักแสดง
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 แต่ความละเอียดช่วยให้การกระจายภาระงานมีประสิทธิภาพมากขึ้นระหว่างคอร์

    Demonstration of how using more actors balances the load across cores

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

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