สถานที่สำคัญ เป็นห้องสมุดโปรไฟล์ที่เรียบง่ายสำหรับ OCAML มันให้หลักในการกำหนดส่วนของรหัสและวัดประสิทธิภาพของรหัสเครื่องมือที่รันไทม์ มาตรการที่มีอยู่นั้นได้มาจากการรวมวงจร CPU (โดยใช้ตัวนับตราประทับเวลาของ CPU) เวลาการใช้งาน (โดยใช้ Sys.time
) และไบต์ที่จัดสรร (พร้อม Gc.allocated_bytes
) เครื่องมือของรหัสอาจทำได้ด้วยมือโดยอัตโนมัติหรือกึ่งอัตโนมัติโดยใช้ส่วนขยาย PPX
ในระหว่างการดำเนินการของโปรแกรมของคุณการสำรวจรหัสเครื่องมือโดยโฟลว์การควบคุมจะถูกบันทึกเป็น "callgraph" ที่มีมาตรการที่รวบรวม ผลลัพธ์อาจถูกเรียกดูโดยตรงบนคอนโซลหรือส่งออกไปยัง JSON
เครื่องมือนี้มีวัตถุประสงค์เพื่อใช้เป็นวิธีการค้นหาว่าเวลาที่ใช้เวลาในโปรแกรมของคุณ (และไม่ใช่มาตรฐานส่วนของรหัสอิสระเช่น core_bench) ในขณะที่ให้ผลลัพธ์ที่สอดคล้องกับส่วนเครื่องมือของรหัส OCAML ของคุณเท่านั้น (ตรงกันข้ามกับเครื่องมือที่ ทำงานโดยตรงกับไบนารีปฏิบัติการเช่น GPROF หรือ PERF)
สำหรับข้อมูลเพิ่มเติมคุณสามารถเรียกดู API
ห้องสมุดแบ่งออกเป็นสองแพ็คเกจ: landmarks
สำหรับห้องสมุดรันไทม์และ landmarks-ppx
สำหรับตัวประมวลผลล่วงหน้าที่ใช้เครื่องมือวัดอัตโนมัติ
opam install landmarks
หรือ
opam install landmarks-ppx
จะติดตั้งไลบรารีรันไทม์หรือทั้งไลบรารีรันไทม์และตัวประมวลผลล่วงหน้า
git clone https://github.com/LexiFi/landmarks.git
cd landmarks
dune build @install
เพียงใช้ landmarks
ในห้องสมุดและ landmarks-ppx
เพื่อเปรียบเทียบการปฏิบัติงานและห้องสมุดของคุณ ตัวอย่างเช่นไฟล์ dune
ต่อไปนี้จะสร้าง test
แบบปฏิบัติการโดยใช้ไลบรารี landmarks
และ PPX ตัวเลือก --auto
FLAG เปิดใช้เครื่องมืออัตโนมัติ (ดูด้านล่าง)
(executable
(name test)
(libraries landmarks)
(preprocess (pps landmarks-ppx --auto))
)
เป็นไปได้ที่จะใช้ Dune เพื่อกระตุ้นการใช้เครื่องมือของโครงการโดยอัตโนมัติ ดู Lexifi/Landmarks-Starter สำหรับตัวอย่างพื้นฐานและดูคู่มือ Dune สำหรับข้อมูลเพิ่มเติม
ocamlfind ocamlopt -c -package landmarks prog.ml
ocamlfind ocamlopt -o prog -package landmarks -linkpkg prog.cmx
คุณสามารถแทนที่ "Ocamlopt" โดย "OCAMLC" เพื่อรวบรวมโปรแกรมใน bytecode
ocamlfind ocamlopt -c -package landmarks -package landmarks-ppx -ppxopt landmarks-ppx,--auto prog.ml
ocamlfind ocamlopt -o prog -package landmarks -linkpkg prog.cmx
โปรดทราบว่า "-PPXOPT Landmarks-PPX,-Auto" เป็นตัวเลือกและเปิดใช้เครื่องมืออัตโนมัติ
มีสามหลักหลัก:
val register : string -> landmark
val enter : landmark -> unit
val exit : landmark -> unit
ฟังก์ชั่น register
ประกาศสถานที่สำคัญใหม่และควรใช้ที่ Toplevel ฟังก์ชั่น enter
และ exit
จะใช้เพื่อกำหนดส่วนของรหัสที่แนบมากับสถานที่สำคัญ ในตอนท้ายของการทำโปรไฟล์เราจะเรียกคืนข้อมูลเวลารวมเวลาที่ใช้ในการใช้งานรหัสชิ้นส่วนที่เกี่ยวข้อง ในระหว่างการดำเนินการร่องรอยของสถานที่สำคัญที่เข้าชมแต่ละครั้งจะถูกบันทึกไว้เพื่อสร้าง "callgraph"
ตัวอย่างเช่น:
open Landmark
let loop = register " loop "
let sleep = register " sleep "
let main = register " main "
let zzz () =
enter sleep;
Unix. sleep 1 ;
exit sleep
let () =
begin
start_profiling () ;
enter main;
enter loop;
for _ = 1 to 9 do
zzz ()
done ;
exit loop;
zzz () ;
exit main;
end
(ไฟล์นี้สามารถรวบรวมได้ด้วย ocamlfind ocamlc -o prog -package landmarks -package unix -linkpkg prog.ml
)
callgraph เหนี่ยวนำคือ:
- 100.00% : main
| - 90.00% : loop
| | - 100.00% : sleep
| - 10.00% : sleep
ซึ่งสามารถถอดความได้เป็น:
clock()
ห้องสมุดมีผลผูกพันกับเคาน์เตอร์วัฏจักรประสิทธิภาพสูงสำหรับสถาปัตยกรรม x86 32 และ 64 บิต (โปรดทราบว่าคุณอาจใช้ landmarks-noc.cm(x)a
ที่เก็บถาวรเพื่อให้การใช้งานของคุณเอง) มันถูกใช้เพื่อวัดเวลาที่ใช้ในรหัสเครื่องมือ
เพื่อหลีกเลี่ยงการเขียนรหัสหม้อต้มคุณสามารถใช้ส่วนขยาย PPX ที่แจกจ่ายกับแพ็คเกจนี้ จะช่วยให้โปรแกรมเมอร์สามารถนิพจน์เครื่องมือโดยใช้คำอธิบายประกอบและฟังก์ชั่นระดับบนสุดของเครื่องมือโดยอัตโนมัติ
ค่า expr [@landmark "name"]
ถูกขยายเข้าไปใน
Landmark. enter __generated_landmark_1;
let r =
try expr with e -> Landmark. exit __generated_landmark_1; raise e
in
Landmark. exit __generated_landmark_1;
r
และการประกาศ
let __generated_landmark_1 = Landmark. register " name "
ต่อท้ายในระดับบนสุด
มันควรจะชี้ให้เห็นว่าการเปลี่ยนแปลงนี้ไม่ได้รักษาสายเรียกคืนหาง (และยังช่วยป้องกันการปรับรูปแบบ polymorphism บางส่วน) หากต้องการแก้ไขปัญหาเหล่านี้ขอแนะนำให้ใช้ส่วนขยายอื่น ๆ ที่ให้ไว้รอบ ๆ let ... in
และ let rec ... in
:
let [ @ landmark] f = body
ซึ่งขยายใน:
let __generated_landmark_2 = Landmark. register " f "
let f = body
let f x1 ... xn =
Landmark. enter __generated_landmark_2;
let r =
try f x1 ... xn with e -> Landmark. exit __generated_landmark_2; raise e
in
Landmark. exit __generated_landmark_2;
r
เมื่อ arity n
ของ f
ได้รับโดยการนับเหตุการณ์ที่เกิดขึ้นตื้นของ fun ... ->
และ function ... ->
ใน body
โปรดทราบว่าเมื่อใช้คำอธิบายประกอบนี้กับการเชื่อมโยง Let-REC จะมีการบันทึกการโทรเข้าจุดเท่านั้น ตัวอย่างเช่นในรหัสชิ้นส่วนต่อไปนี้
let () =
let [ @ landmark] rec even n = (n = 0 ) || odd (n - 1 )
and [ @ landmark] odd n = (n = 1 ) || n > 0 && even (n - 1 )
in Printf. printf " 'six is even' is %b n " (even 6 )
สถานที่สำคัญที่เกี่ยวข้องกับ "แม้กระทั่ง" จะถูกสำรวจอย่างแน่นอน (และไม่ใช่สามครั้ง!) ในขณะที่กระแสควบคุมจะไม่ผ่านสถานที่สำคัญที่เกี่ยวข้องกับ "แปลก"
คำอธิบายประกอบโครงสร้าง [@@@landmark "auto"]
และ [@@@landmark "auto-off"]
เปิดใช้งานหรือปิดการใช้งานเครื่องมือวัดอัตโนมัติของฟังก์ชั่นระดับบนสุดในโมดูล ในโหมดอัตโนมัติการประกาศฟังก์ชั่นทั้งหมดมีคำอธิบายประกอบโดยปริยาย เครื่องมือวัดอัตโนมัติสามารถเปิดใช้งาน/ปิดใช้งานสำหรับไฟล์ทั้งหมดผ่านตัวเลือก auto
ใน OCAML_LANDMARKS
ตามรายละเอียดด้านล่าง
ตัวแปรสภาพแวดล้อม OCAML_LANDMARKS
ถูกอ่านในสองขั้นตอนที่แตกต่างกัน: เมื่อผู้เขียน PPX ถูกดำเนินการและเมื่อโมดูลสถานที่สำคัญถูกโหลดโดยโปรแกรมเครื่องมือ ตัวแปรนี้ถูกแยกวิเคราะห์เป็นรายการรายการที่คั่นด้วยเครื่องหมายจุลภาคของ option=argument
หรือ option
โดยที่ option
คือ:
ในระหว่างขั้นตอนการเขียน PPX (ตามเวลารวบรวม):
auto
(ไม่มีอาร์กิวเมนต์): เปิดเครื่องมืออัตโนมัติโดยค่าเริ่มต้น (ทำงานราวกับว่าแต่ละโมดูลเริ่มต้นด้วยคำอธิบายประกอบ [@@@landmark "auto"]
)
threads
(ไม่มีอาร์กิวเมนต์): บอกส่วนขยาย PPX ให้ใช้โมดูล Landmark_threads
แทนโมดูล Landmark
เมื่อโหลดโปรแกรมเครื่องมือ (ที่รันไทม์):
format
ที่มีอาร์กิวเมนต์ที่เป็นไปได้: textual
(ค่าเริ่มต้น) หรือ json
มันควบคุมรูปแบบผลลัพธ์ของการทำโปรไฟล์ซึ่งเป็นตัวแทนคอนโซลที่เป็นมิตรหรือการเข้ารหัส JSON ของ CallGraph
threshold
ที่มีตัวเลขระหว่าง 0.0 ถึง 100.0 เป็นอาร์กิวเมนต์ (ค่าเริ่มต้น: 1.0) หากเกณฑ์ไม่ได้เป็นศูนย์เอาต์พุตข้อความจะซ่อนโหนดใน callgraph ด้านล่างเกณฑ์นี้ (เป็นเปอร์เซ็นต์ของเวลาของผู้ปกครอง) ตัวเลือกนี้ไม่มีความหมายสำหรับรูปแบบอื่น ๆ
output
ด้วยอาร์กิวเมนต์ที่เป็นไปได้: stderr
(ค่าเริ่มต้น), stdout
, temporary
, <file>
(โดยที่ <file>
เป็นพา ธ ของไฟล์) มันบอกว่าจะส่งออกผลลัพธ์ของการทำโปรไฟล์ ด้วย temporary
มันจะพิมพ์ในไฟล์ชั่วคราว (ชื่อของไฟล์นี้จะถูกพิมพ์บนข้อผิดพลาดมาตรฐาน) คุณสามารถใช้ temporary:<directory>
เพื่อระบุไดเรกทอรีที่สร้างไฟล์
debug
โดยไม่มีข้อโต้แย้ง เปิดใช้งานโหมด verbose ที่ส่งออกร่องรอยบน stderr ทุกครั้งที่มีการเรียกว่าสถานที่สำคัญ
time
ที่ไม่มีข้อโต้แย้ง นอกจากนี้ยังรวบรวมการประทับเวลา Sys.time
ระหว่างการทำโปรไฟล์
off
โดยไม่มีข้อโต้แย้ง ปิดการใช้งานโปรไฟล์
on
ไม่มีข้อโต้แย้ง เปิดใช้งานการทำโปรไฟล์ (ค่าเริ่มต้นอาจละเว้น)
allocation
โดยไม่มีข้อโต้แย้ง นอกจากนี้ยังรวบรวมข้อมูล Gc.allocated_byte
คุณสามารถรวบรวมเว็บดูบนคอมพิวเตอร์ของคุณหรือเรียกดูออนไลน์ คุณต้องโหลดไฟล์ JSON โดยใช้ FilePicker จากนั้นคุณสามารถคลิกไปรอบ ๆ เพื่อเรียกดู CallGraph
โมดูล Landmark
ไม่ปลอดภัยกับด้าย หากคุณมีหลายเธรดคุณต้องตรวจสอบให้แน่ใจว่าส่วนใหญ่หนึ่งเธรดกำลังดำเนินการรหัสเครื่องมือ สำหรับการที่คุณสามารถใช้โมดูล Landmark_threads
(รวมอยู่ในสถานที่สำคัญ-Threads.cm (x) ที่เก็บถาวร) ที่ป้องกันไม่ให้ฟังก์ชั่นที่ไม่ปลอดภัยของเธรดเพื่อดำเนินการในเธรดทั้งหมด
คำอธิบายประกอบในการแสดงออกอาจทำให้อารมณ์แปรปรวนด้วยความหลากหลาย (นี่ไม่ใช่กรณีของคำอธิบายประกอบที่มีผลผูกพัน) ตัวอย่างเช่นชิ้นส่วนของรหัสต่อไปนี้จะล้มเหลวในการรวบรวม:
let test = ( fun x -> x)[ @ landmark " test " ]
in test " string " , test 1
แพ็คเกจ 'สถานที่สำคัญ' นี้ได้รับอนุญาตจาก Lexifi ภายใต้เงื่อนไขของใบอนุญาต MIT
ติดต่อ: [email protected]