ฉันต้องการข้อมูลเกี่ยวกับวิธีการคิดอย่างถูกต้องเกี่ยวกับการปิด C ++ 11 และstd::function
ในแง่ของวิธีการใช้งานและวิธีจัดการหน่วยความจำ
แม้ว่าฉันจะไม่เชื่อในการเพิ่มประสิทธิภาพก่อนกำหนด แต่ฉันก็มีนิสัยในการพิจารณาผลกระทบด้านประสิทธิภาพของตัวเลือกของฉันอย่างรอบคอบในขณะที่เขียนโค้ดใหม่ ฉันยังเขียนโปรแกรมแบบเรียลไทม์ในปริมาณพอสมควรเช่นในไมโครคอนโทรลเลอร์และสำหรับระบบเสียงซึ่งต้องหลีกเลี่ยงการจัดสรรหน่วยความจำแบบไม่กำหนด / การหยุดการจัดสรร
ดังนั้นฉันจึงต้องการพัฒนาความเข้าใจให้ดีขึ้นว่าเมื่อใดควรใช้หรือไม่ใช้ C ++ lambdas
ความเข้าใจปัจจุบันของฉันคือแลมด้าที่ไม่มีการปิดจับนั้นเหมือนกับการเรียกกลับ C อย่างไรก็ตามเมื่อสภาพแวดล้อมถูกจับด้วยค่าหรือโดยการอ้างอิงอ็อบเจ็กต์ที่ไม่ระบุชื่อจะถูกสร้างขึ้นบนสแต็ก std::function
เมื่อมูลค่าปิดต้องถูกส่งกลับจากฟังก์ชั่นหนึ่งใน wraps จะเกิดอะไรขึ้นกับหน่วยความจำการปิดในกรณีนี้? คัดลอกจากสแต็กไปยังฮีปหรือไม่ เป็นอิสระเมื่อใดก็ตามที่std::function
เป็นอิสระกล่าวคือมีการนับการอ้างอิงเหมือน a std::shared_ptr
หรือไม่?
ฉันคิดว่าในระบบเวลาจริงฉันสามารถตั้งค่าฟังก์ชั่นห่วงโซ่ของแลมบ์ดาผ่าน B เป็นอาร์กิวเมนต์ต่อเนื่องไปเพื่อให้ท่อการประมวลผลA->B
จะถูกสร้างขึ้น ในกรณีนี้การปิด A และ B จะถูกจัดสรรครั้งเดียว แม้ว่าฉันไม่แน่ใจว่าสิ่งเหล่านี้จะถูกจัดสรรบนสแต็กหรือฮีป อย่างไรก็ตามโดยทั่วไปดูเหมือนว่าปลอดภัยที่จะใช้ในระบบเรียลไทม์ ในทางกลับกันถ้า B สร้างฟังก์ชันแลมบ์ดาบางฟังก์ชัน C ซึ่งส่งคืนหน่วยความจำสำหรับ C จะได้รับการจัดสรรและจัดสรรซ้ำ ๆ ซึ่งจะไม่เป็นที่ยอมรับสำหรับการใช้งานแบบเรียลไทม์
ในรหัสหลอกคือ DSP loop ซึ่งฉันคิดว่าจะปลอดภัยแบบเรียลไทม์ ฉันต้องการประมวลผลบล็อก A และ B โดยที่ A เรียกใช้อาร์กิวเมนต์ ฟังก์ชั่นทั้งสองนี้ส่งคืนstd::function
อ็อบเจ็กต์ดังนั้นf
จะเป็นstd::function
อ็อบเจ็กต์ที่สภาพแวดล้อมของมันถูกเก็บไว้บนฮีป:
auto f = A(B); // A returns a function which calls B
// Memory for the function returned by A is on the heap?
// Note that A and B may maintain a state
// via mutable value-closure!
for (t=0; t<1000; t++) {
y = f(t)
}
และสิ่งที่ฉันคิดว่าอาจใช้ไม่ดีในโค้ดเรียลไทม์:
for (t=0; t<1000; t++) {
y = A(B)(t);
}
และสิ่งหนึ่งที่ฉันคิดว่าหน่วยความจำสแต็กน่าจะใช้สำหรับการปิด:
freq = 220;
A = 2;
for (t=0; t<1000; t++) {
y = [=](int t){ return sin(t*freq)*A; }
}
ในกรณีหลังนี้การปิดจะถูกสร้างขึ้นในการวนซ้ำแต่ละครั้ง แต่ไม่เหมือนกับตัวอย่างก่อนหน้านี้คือราคาถูกเนื่องจากเหมือนกับการเรียกใช้ฟังก์ชันไม่มีการจัดสรรฮีป ยิ่งไปกว่านั้นฉันสงสัยว่าคอมไพเลอร์สามารถ "ยก" การปิดและทำการเพิ่มประสิทธิภาพแบบอินไลน์ได้หรือไม่
ถูกต้องหรือไม่ ขอบคุณ.
operator()
. ไม่มีการ "ยก" ให้เสร็จแลมดาก็ไม่ได้มีอะไรพิเศษ พวกมันเป็นเพียงส่วนสั้น ๆ สำหรับอ็อบเจ็กต์ฟังก์ชันเฉพาะที่