ชี้แจง เคลื่อนไหว เฉลี่ย C รหัส


ฉันได้ profiled นี้โดยใช้ Profiler Visual C และบัญชีประมาณ 35 ของเวลาทำงาน ค่าเฉลี่ยเคลื่อนที่เชิงตัวเลขนี้เรียกว่ามากกว่าหนึ่งพันล้านครั้งเนื่องจากถูกใช้ซ้ำ ๆ ในการประมวลผลข้อมูลมากกว่า 400 กิกะไบต์ ข้อมูลออกมาจากอาร์เรย์ดิสก์ solid state ของ Raid Level 0 ดังนั้นการอ่านบัญชีข้อมูลนานกว่า 5 ครั้ง ขนาดของราคาอยู่ที่ประมาณ 100 ฉันเริ่มต้นโดยเร็วขึ้นโดยปัจจัยที่ 4 โดย precalculating มากที่สุดของข้อมูลที่เป็นไปได้ แล้วฉันสามารถเพิ่มขึ้นอีกครั้งโดยปัจจัยของ nene PaeneInsula Oct 30 11 at 20:41 ฉันสามารถเพิ่มความเร็วอีกครั้งโดย 12 ปัจจัยโดย multithreading มัน (ธรรมชาติของข้อมูลเป็นเช่นที่สามารถ multithreaded เช่นเดียวกับที่โหลดมีความสมดุลอย่างสมบูรณ์) และฉันมีมันทำงานบน i7 990x (ซึ่งมี 6 แกน, hyperthreaded จากทั้งหมด 12) โอเวอร์คล๊อก ndash PaeneInsula Oct 30 11 at 20:51 แน่นอน multithreading สามารถช่วย. แต่คุณเกือบจะสามารถปรับปรุงสมรรถนะในเครื่องแบบเกลียวได้ ขั้นแรกคุณกำลังคำนวณค่าผิดพลาด เฉพาะเครื่องที่ทันสมัยที่สุดเท่านั้นที่สามารถทำข้อมูลเชิงลบล่วงหน้าได้ เกือบทั้งหมด machihnes ได้เร็วขึ้นสำหรับหน่วย strides นั่นคือ การเปลี่ยนทิศทางของอาร์เรย์เพื่อให้คุณสแกนจากต่ำไปสูงแทนที่จะสูงไปต่ำเกือบเสมอดีกว่า จากนั้นให้เขียนบิตใหม่ - โปรดให้ฉันย่อชื่อตัวแปรเพื่อให้ง่ายต่อการพิมพ์: โดยวิธีนี้ฉันจะเริ่มต้นใช้ตัวย่อสำหรับราคาและ s เพื่อให้เรียบเพื่อบันทึกการพิมพ์ ฉันขี้เกียจ. แต่อาจเป็นได้เร็วกว่าเวลาแฝงระหว่าง avgi และ avgi-2 นั้นจะเพิ่มขึ้นเป็น 1 คูณและเพิ่มแทนที่จะลบออกและคูณระหว่าง avgi และ avgi-1 นั่นคือ มากกว่าสองเท่าเร็ว โดยทั่วไปแล้วคุณต้องการเขียนการกำเริบขึ้นใหม่เพื่อให้ avgi ถูกคำนวณในรูปแบบ avgj for j ให้มากที่สุดเท่าที่คุณจะทำได้โดยไม่ต้องกรอกข้อมูลในเครื่อง โดยทั่วไปแล้วคุณจะทำคูณเพิ่มขึ้นโดยรวมเพื่อให้ได้รับสตริงที่ทวีคูณ (และหักล้าง) บนเส้นทางที่สำคัญน้อยลง การข้ามจาก avgi-2 ถึง avgi เป็นเรื่องง่ายคุณน่าจะทำสามถึงสี่ได้ ระยะทางขึ้นอยู่กับว่าเครื่องของคุณมีขนาดเท่าใดและคุณมีทะเบียนกี่เท่า และแฝงของ adder บวกจุดและตัวคูณ หรือดีกว่ายังรสชาติของการคูณเพิ่มคำสั่งที่คุณมี - เครื่องที่ทันสมัยทั้งหมดมีพวกเขา เช่น. ถ้า MADD หรือ MSUB มีระยะเวลา 7 รอบคุณสามารถคำนวณได้ถึง 6 แบบในเงาแม้ว่าจะมีหน่วยลอยตัวเดียว pipelined เต็มรูปแบบ และอื่น ๆ น้อยลงหากมีการวางท่ออื่น ๆ ทุกรอบเช่นเดียวกับความแม่นยำสองเท่าของชิปที่มีอายุมากกว่าและ GPUs โค้ดแอสเซมบลีควรเป็นซอฟต์แวร์ pipelined เพื่อให้การวนรอบซ้ำ ๆ ซ้อนทับกัน คอมไพเลอร์ที่ดีควรทำเพื่อคุณ แต่คุณอาจต้องเขียนโค้ด C เพื่อให้ได้ประสิทธิภาพที่ดีที่สุด โดยวิธีการ: ฉันไม่ได้หมายถึงการแนะนำว่าคุณควรจะสร้างแถวของค่าเฉลี่ย แต่คุณต้องมีค่าเฉลี่ย 2 ค่าหาก avgi ถูกคำนวณในรูปแบบของ avgi-2 และอื่น ๆ คุณสามารถใช้อาร์เรย์ของ avgi ได้หากต้องการ แต่คิดว่าคุณต้องมี 2 หรือ 4 avgs ที่เรียกว่า creatively, avg0 และ avg1 (2, 3) และหมุนพวกเขา การแบ่งประเภทสะสมหรือค่าเฉลี่ยออกเป็นสองขั้นตอนหรือมากกว่าซึ่งรวมถึงขั้นตอนต่างๆของการกลับเป็นซ้ำเป็นเรื่องปกติในโค้ดสมรรถนะสูง โอ้ใช่: precalculate ss ฯลฯ ถ้าฉันได้ทำมันถูกต้องในความแม่นยำอนันต์นี้จะเหมือนกัน (Double check me, please.) อย่างไรก็ตามในความแม่นยำ Fin แน่นอนผลของคุณอาจแตกต่างหวังว่าเพียงเล็กน้อยเนื่องจากรอบที่แตกต่างกัน หากการเลื่อนออกถูกต้องและคำตอบต่างกันอย่างมีนัยสำคัญคุณอาจมีอัลกอริทึมที่ไม่เสถียรเป็นตัวเลข คุณเป็นคนที่รู้ หมายเหตุ: ข้อผิดพลาดในการปัดเศษทศนิยมจะเปลี่ยนบิตต่ำของคำตอบของคุณ ทั้งสองเนื่องจากการจัดเรียงรหัสใหม่และใช้ MADD ฉันคิดว่าคงเป็นได้ แต่คุณต้องตัดสินใจ หมายเหตุ: การคำนวณ avgi และ avgi-1 เป็นอิสระแล้ว ดังนั้นคุณจึงสามารถใช้ชุดคำสั่ง SIMD เช่น Intel SSE2 ซึ่งอนุญาตให้ใช้งานการดำเนินการสองค่า 64 บิตในการลงทะเบียนแบบ 128 บิตได้ตลอดเวลา ที่จะดีสำหรับเกือบ 2X บนเครื่องที่มี ALUs พอ หากคุณมีทะเบียนเพียงพอในการเขียน avgi ในแง่ avgi-4 (และฉันแน่ใจว่าคุณทำใน iA64) จากนั้นคุณสามารถไปที่ 4X wide ถ้าคุณมีสิทธิ์เข้าถึงเครื่องเช่น AVX 256 บิต บน GPU คุณสามารถไปสำหรับการกลับมาที่ลึกขึ้นเขียนใหม่ avgi ในแง่ของ avgi-8 และอื่น ๆ GPU บางตัวมีคำแนะนำที่คำนวณ AXB หรือ AXBY เป็นคำสั่งเดียว แม้ว่าจะมีความคล้ายคลึงกันมากขึ้นสำหรับ 32 บิตมากกว่าความละเอียด 64 บิต ในบางจุดอาจจะเริ่มถามว่า: คุณต้องการทำเช่นนี้ในหลายราคาในเวลาไม่เพียงแค่นี้จะช่วยให้คุณมี multithreading ก็จะเหมาะกับการทำงานบน GPU และใช้ Wide SIMD Minor Late Addition ฉันรู้สึกอึดอัดใจที่จะไม่ใช้ Horners Rule กับการแสดงออกอย่างมีประสิทธิภาพเล็กน้อย ผลแตกต่างกันเล็กน้อยกับการปัดเศษ ในการป้องกันของฉันคอมไพเลอร์ที่ดีควรทำเพื่อคุณ แต่กฎของ Hrners ทำให้ห่วงโซ่พึ่งพาอยู่ลึกขึ้นในแง่ของการคูณ คุณอาจจำเป็นต้องคลี่คลายและวางแนวลูปอีกสักครู่ หรือคุณสามารถทำในกรณีที่คุณรู้ล่วงหน้าว่านี่เป็นไปได้ที่จะเพิ่มขึ้นตามความเป็นจริง: แต่ฉันต้องการหลีกเลี่ยงการเพิ่ม ฉันมี googled และไม่พบตัวอย่างที่เหมาะสมหรืออ่านได้ โดยทั่วไปฉันต้องการติดตามค่าเฉลี่ยเคลื่อนที่ของสตรีมกระแสข้อมูลจำนวนจุดลอยโดยใช้ตัวเลข 1000 ครั้งล่าสุดเป็นตัวอย่างข้อมูล วิธีที่ง่ายที่สุดในการทำแบบทดสอบนี้คือการใช้อาร์เรย์แบบวงกลมค่าเฉลี่ยเคลื่อนที่แบบเสวนาและค่าเฉลี่ยเคลื่อนที่ที่เรียบง่ายกว่าและพบว่าผลลัพธ์จากอาร์เรย์แบบวงกลมเหมาะกับความต้องการของฉันมากที่สุด ถาม 12 มิ.ย. 12 เวลา 4:38 หากความต้องการของคุณเรียบง่ายคุณอาจลองใช้ค่าเฉลี่ยเคลื่อนที่แบบเสวนา ใส่เพียงแค่คุณสร้างตัวแปรสะสมและเมื่อโค้ดของคุณดูที่ตัวอย่างแต่ละโค้ดจะอัปเดตข้อมูลสะสมด้วยค่าใหม่ คุณสามารถเลือกค่า alpha คงที่ระหว่าง 0 ถึง 1 และคำนวณค่านี้: คุณเพียงแค่หาค่า alpha ที่ผลของตัวอย่างที่กำหนดจะใช้เวลาประมาณ 1000 ตัวอย่างเท่านั้น อืมฉันไม่แน่ใจว่านี่เหมาะกับคุณแล้วตอนนี้ฉันวางมันไว้ที่นี่แล้ว ปัญหาคือ 1000 เป็นหน้าต่างยาวสวยสำหรับค่าเฉลี่ยเคลื่อนที่ที่อธิบายไม่แน่ใจว่ามีอัลฟาที่จะกระจายค่าเฉลี่ยมากกว่า 1000 หมายเลขล่าสุดโดยไม่ต้อง underflow ในการคำนวณจุดลอย แต่ถ้าคุณต้องการค่าเฉลี่ยที่เล็กลงเช่น 30 ตัวเลขหรือมากกว่านี่เป็นวิธีที่ง่ายและรวดเร็วในการดำเนินการ ตอบ 12 มิ.ย. 12 เวลา 4:44 1 ในโพสต์ของคุณ ค่าเฉลี่ยเคลื่อนที่ที่อธิบายได้จะทำให้ตัวแปรอัลฟ่าเป็นตัวแปรได้ ดังนั้นจึงช่วยให้สามารถใช้คำนวณค่าเฉลี่ยของฐานเวลา (เช่นไบต์ต่อวินาที) ถ้าเวลานับตั้งแต่การอัปเดตสะสมครั้งล่าสุดเป็นเวลามากกว่า 1 วินาทีคุณจะยอมให้ alpha เป็น 1.0 มิเช่นนั้นคุณสามารถปล่อยให้ alpha เป็น (usecs ตั้งแต่ update1000000 ครั้งล่าสุด) ndash jxh Jun 12 12 at 6:21 โดยทั่วไปฉันต้องการติดตามค่าเฉลี่ยเคลื่อนที่ของกระแสอย่างต่อเนื่องของกระแสตัวเลขจุดลอยใช้ล่าสุด 1000 หมายเลขเป็นตัวอย่างข้อมูล โปรดทราบว่าด้านล่างปรับปรุงชุดค่าผสมทั้งหมดเป็นองค์ประกอบที่เพิ่มขึ้นโดยไม่ต้องเสียค่าใช้จ่ายในการคำนวณ O (N) traversal เพื่อคำนวณผลรวม - จำเป็นสำหรับค่าเฉลี่ย - ตามความต้องการ ทั้งหมดถูกกำหนดเป็นพารามิเตอร์อื่นจาก T เพื่อสนับสนุนเช่น ใช้ยาวนานเมื่อรวม 1000 ยาว s, int สำหรับ char s หรือ double เพื่อรวม float s นี่เป็นบิตที่มีข้อบกพร่องในการที่ numsamples อาจผ่าน INTMAX - ถ้าคุณสนใจคุณสามารถใช้ unsigned long long หรือใช้สมาชิกข้อมูล bool พิเศษเพื่อบันทึกเมื่อเติมคอนเทนเนอร์เป็นครั้งแรกในขณะที่วนรอบ numsamples รอบ (ดีที่สุดแล้วเปลี่ยนชื่อบางอย่างที่ไม่เป็นอันตรายเช่น pos) ตอบ 12 มิ.ย. 12 at 5:19 สมมติว่าตัวดำเนินการ quotvoid (T sample) quot ก็คือ quotvoid operatorltlt (T sample) quot ndash o วันที่ 8 มิ.ย. 14 เวลา 11:52 น. oPhút ahhh เห็นดี จริงฉันตั้งใจจะให้โมฆะดำเนิน () (T ตัวอย่าง) แต่แน่นอนคุณสามารถใช้สิ่งที่คุณต้องการสัญกรณ์. จะแก้ไขขอบคุณ ndash Tony D Jun 8 14 at 14: 27Is เป็นไปได้ที่จะใช้ค่าเฉลี่ยเคลื่อนที่ใน C โดยไม่ต้องใช้หน้าต่างของตัวอย่าง Ive พบว่าฉันสามารถเพิ่มประสิทธิภาพบิตโดยเลือกขนาดหน้าต่าง thats อำนาจของสองเพื่อให้บิต - เปลี่ยนแทนการหาร แต่ไม่จำเป็นต้องบัฟเฟอร์จะดี มีวิธีแสดงผลลัพธ์เฉลี่ยเคลื่อนที่ใหม่ตามผลการค้นหาเดิมและตัวอย่างใหม่กำหนดค่าเฉลี่ยเคลื่อนที่ตัวอย่างเช่นข้ามหน้าต่างตัวอย่าง 4 ตัวอย่าง: เพิ่มตัวอย่างใหม่ e: ค่าเฉลี่ยเคลื่อนที่สามารถใช้งานได้แบบ recursively , แต่สำหรับการคำนวณที่แน่นอนของค่าเฉลี่ยเคลื่อนที่คุณต้องจำตัวอย่างการป้อนข้อมูลที่เก่าแก่ที่สุดในผลรวม (เช่นในตัวอย่างของคุณ) สำหรับค่าเฉลี่ยเคลื่อนที่ N ที่คำนวณโดย: yn คือสัญญาณขาออกและ xn เป็นสัญญาณขาเข้า อีคิว (1) สามารถเขียน recursively เป็นดังนั้นคุณจำเป็นต้องจำตัวอย่าง xn-N เพื่อคำนวณ (2) ที่ระบุโดย Conrad Turner คุณสามารถใช้หน้าต่างแทนยาวได้ (ไม่ จำกัด ) แทนซึ่งจะช่วยให้คุณสามารถคำนวณเอาท์พุทได้เฉพาะจากผลลัพธ์ที่ผ่านมาและอินพุทปัจจุบัน: แต่นี่ไม่ใช่ค่าเฉลี่ยเคลื่อนที่ (unweighted) แต่เป็นค่าชี้แจง (อย่างน้อยที่สุดในทางทฤษฎี) คุณจะไม่มีวันลืมอะไรเลย (น้ำหนักเพียงเล็กน้อยและเล็กลงสำหรับตัวอย่างที่ไกลเกินกว่าที่ผ่านมา) ฉันใช้ค่าเฉลี่ยเคลื่อนที่โดยไม่มีหน่วยความจำรายการสำหรับโปรแกรมติดตาม GPS ที่ฉันเขียน ฉันเริ่มต้นด้วย 1 ตัวอย่างและหารด้วย 1 เพื่อให้ได้ค่าเฉลี่ยปัจจุบัน จากนั้นผมจะเพิ่มตัวอย่าง anothe และหารด้วย 2 เป็นค่าเฉลี่ยปัจจุบัน นี้ยังคงจนกว่าฉันจะได้รับความยาวเฉลี่ย ทุกครั้งหลังจากนั้นฉันเพิ่มในตัวอย่างใหม่ให้ได้ค่าเฉลี่ยและลบค่าเฉลี่ยดังกล่าวออกจากยอดรวม ฉันไม่ใช่นักคณิตศาสตร์ แต่ดูเหมือนจะเป็นวิธีที่ดีที่จะทำ ฉันคิดว่ามันจะเปิดท้องของคนที่แต่งตัวประหลาดคณิตศาสตร์จริง แต่ก็จะเปิดออกเป็นหนึ่งในวิธีที่ได้รับการยอมรับในการทำมัน และทำงานได้ดี เพียงแค่จำไว้ว่ายิ่งความยาวของคุณยิ่งใหญ่เท่าไรก็ยิ่งช้าลงตามสิ่งที่คุณต้องการทำ นั่นอาจไม่สำคัญตลอดเวลา แต่เมื่อไปตามดาวเทียมถ้าคุณช้าเส้นทางอาจอยู่ไกลจากตำแหน่งจริงและจะดูไม่ดี คุณอาจมีช่องว่างระหว่างจุดเริ่มต้นและจุดต่อท้าย ฉันเลือกความยาวของ 15 ปรับปรุง 6 ครั้งต่อนาทีเพื่อให้ได้อย่างราบรื่นเพียงพอและไม่ได้รับไกลจากตำแหน่งนั่งจริงกับจุดเส้นทางที่ราบรื่น ตอบ 16 พค. 16 ที่ 23:03 เริ่มต้นทั้งหมด 0, นับ 0 (ทุกครั้งที่เห็นค่าใหม่จากนั้นหนึ่งอินพุท (scanf) หนึ่งเพิ่ม totalnewValue, หนึ่งที่เพิ่มขึ้น (นับ) หนึ่งหารเฉลี่ย (totalcount) นี่จะเป็นค่าเฉลี่ยเคลื่อนที่มากกว่า input ทั้งหมดในการคํานวณคาเฉลี่ยโดยใชเพียง 4 อินพุทตอไปเทานั้นจะตองใช4 inputvariables อาจคัดลอก input แตละ input ไปยัง inputvariable ที่สูงกวาจากนั้นคา new moving average เปน sum ของ inputvariables 4 หารดวย 4 (right shift 2) ดีถ้าทุกปัจจัยการผลิตเป็นบวกเพื่อให้การคำนวณเฉลี่ยตอบกุมภาพันธ์ 3 15 ที่ 4:06 ที่จริงจะคำนวณค่าเฉลี่ยรวมและไม่เฉลี่ยเคลื่อนไหวตามนับได้รับผลกระทบขนาดใหญ่ของตัวอย่างการป้อนข้อมูลใหม่ ๆ กลายเป็น vanishingly ขนาดเล็ก ndash Hilmar Feb ในขั้นตอนการสร้างอัลกอริธึมการซื้อขายแลกเปลี่ยนและต้องการลองถ่ายภาพของฉันในการคำนวณ EMA (Exponential Moving Averages) ผลของฉันดูเหมือนจะถูกต้อง (เทียบกับการคํานวณ) ns ฉันทำด้วยมือ) ดังนั้นฉันเชื่อว่าวิธีการต่อไปนี้ทำงาน แต่เพียงต้องการที่จะได้รับชุดพิเศษของดวงตาเพื่อให้แน่ใจ im ไม่ขาดอะไร โปรดทราบว่านี่เป็นเพียงการส่งคืน EMA สำหรับราคาล่าสุด แต่ไม่ได้ส่งคืนอาร์เรย์ของ EMA เนื่องจากไม่ใช่สิ่งที่ฉันต้องการสำหรับแอ็พพลิเคชันของฉัน การทับซ้ำเป็นเครื่องมือที่ดีสำหรับงานที่เหมาะสม แต่ที่นี่ใช้เพื่อทำให้เกิดการวนซ้ำง่าย เช่นรหัส เป็นเรื่องยากที่จะอ่านและอธิบายเหตุผล จะช้าลงเนื่องจากโค้ดใน ema ต้องการเพียงแค่เรียกใช้เพียงครั้งเดียวเท่านั้น จะล้มเหลวด้วยค่าที่มากพอของหน้าต่างเนื่องจากล้นกองเรียก Pythons โปรดระบุอย่างน้อยพารามิเตอร์ของแต่ละฟังก์ชันเช่น หน้าต่างนั้นคือความยาวของหน้าต่างและตำแหน่งดังกล่าวนับถอยหลังจากส่วนท้ายของข้อมูล (ในความเป็นจริงสิ่งต่างๆจะชัดเจนยิ่งขึ้นถ้าตำแหน่งเป็นดัชนีส่งต่อไปยังข้อมูลปกติ) ยกข้อยกเว้นเมื่อคุณพบว่าพารามิเตอร์มีค่าที่ไม่ถูกต้อง การส่งคืน None จะทำให้เกิดข้อผิดพลาดที่ทำให้เกิดความสับสนขึ้นในภายหลัง ในความเป็นจริงถ้าฉันลองตัวบ่งชี้ () ema (closeprices, 600) ฉันได้รับการเรียกซ้ำอนันต์เนื่องจาก sma ส่งกลับไม่มี ซึ่งทำให้ ema เรียก sma ซ้ำแล้วซ้ำอีก จุดก่อนหน้ายังแสดงให้เห็นว่าถ้า len (data) lt หน้าต่าง 2 ไม่ใช่เช็คที่ถูกต้อง 1 ใน data-window2 1: - window 1 ดูเหมือนจะไม่ถูกต้องกับฉัน ฉันสมมุติว่าคุณต้องการ data-window2: - window คำสั่ง return previousema อยู่ในที่แปลกเนื่องจาก ณ จุดนี้คุณได้คำนวณ currentema ใหม่ นี่เป็นกรณีฐานของการทับทิมและเป็นเรื่องปกติที่จะต้องจัดการกับกรณีฐานก่อน ข้อเสนอของฉันสำหรับ ema: ตอบ 26 พ. ย. ที่ 18:56 บทวิจารณ์ที่น่าตื้น: คุณไม่จำเป็นต้องเขียนชั้นเรียนสำหรับสิ่งที่คุณกำลังทำอยู่ (และขอแนะนำให้คุณดูวิดีโอนี้) ชั้นของคุณไม่ได้ห่อหุ้มข้อมูลใด ๆ ไว้และคุณเพียงแค่ใช้เพื่อทำหน้าที่ของคุณในเอนทิตีเดียวกันเท่านั้น ฉันเดาสิ่งที่จะง่ายต่อการเข้าใจถ้าคุณได้กำหนด classmethod เพื่อให้ชัดเจนว่าคุณเคยชินจริงๆพึ่งพาใด ๆ เช่นใด. อย่างไรก็ตามตัวเลือกที่ดียิ่งขึ้นคือการกำหนดฟังก์ชันในโมดูลตัวบ่งชี้ ผมขอขอบคุณสำหรับคำแนะนำที่ผมได้ทำเป็น classmethods และถกเถียงกันว่าจะไปมาระหว่างการใช้คลาสหรือเพียงแค่กำหนดฟังก์ชันในโมดูลตัวบ่งชี้ (ซึ่งตอนนี้ผมจะทำ) ndash ChrisC พ. ย. 25 14 ตอน 19:12 แค่ดูวิดีโอที่ยอดเยี่ยมมาก ndash ChrisC พ. ย. 25 14 ที่ 19:43 คำตอบของคุณ 2017 Stack Exchange, Inc

Comments

Popular Posts