การเปลี่ยนค่าส่วนเพิ่มของ C# Parallel.For loop

ฉันต้องการแปลง for loop ซึ่งเพิ่มตัววนซ้ำ 2 ทุกๆ การส่งผ่านเป็น Parallel For loop โดยใช้ TPL ข้อมูลไม่ได้ขึ้นอยู่กับลำดับหรือข้อจำกัดใดๆ แต่ฉันต้องการประมวลผลข้อมูลในองค์ประกอบอื่นๆ ของอาร์เรย์ต้นทางของฉันเท่านั้น (ซึ่งก็คือ _Datalist ในโค้ดด้านล่าง) ดังนั้นจึงต้องเพิ่มขึ้น 2

ห่วงของฉัน:

for (int i = 1; i < _DataList.Length - 1; i += 2)
{
     // Do work for _DataList[i]
}

เป็นไปได้ไหมที่จะบอกลูปขนานว่าฉันต้องการเพิ่ม i ทีละสองแทนที่จะเป็นหนึ่ง?

นี่คือ Parallel Loop แต่เห็นได้ชัดว่าฉันเพิ่มขึ้นเพียง 1 ต่อการวนซ้ำแต่ละครั้ง:

        Task.Factory.StartNew(() =>
            Parallel.For(1, _DataList.Length, i =>
            {
                // do work for _DataList[i]                    
            })
        );

ฉันสามารถบอกเนื้อความของลูปด้านในให้ละเว้นค่าแปลก ๆ ของ i ได้ แต่ดูเหมือนว่าจะยุ่งนิดหน่อย - มีวิธีทำในการเริ่มต้นลูปหรือไม่?


person Gareth    schedule 20.10.2010    source แหล่งที่มา
comment
อย่ามองข้ามค่าคี่เท่านั้น ที่สร้างงานได้มากเป็นสองเท่าที่คุณต้องการ ซึ่งเพิ่มค่าใช้จ่ายที่ไม่จำเป็นจำนวนมาก   -  person Gabe    schedule 20.10.2010
comment
ใช่ ฉันเห็นสิ่งที่คุณหมายถึง   -  person Gareth    schedule 20.10.2010


คำตอบ (4)


เกี่ยวกับ:

var odds = Enumerable.Range(1, _DataList.Length).Where(i => i % 2 != 0);

Task.Factory.StartNew(() =>
    Parallel.ForEach(odds, i =>
    {
        // do work for _DataList[i]                    
    })
);
person Darin Dimitrov    schedule 20.10.2010

คุณสามารถลดจำนวนขั้นตอนลงครึ่งหนึ่งและเพิ่มดัชนีเป็นสองเท่า:

Parallel.For(0, _DataList.Length / 2, i =>
{
    // do work for _DataList[2 * i]                    
});
person dtb    schedule 20.10.2010

คำตอบของ Darin Dimitrov แสดงวิธีง่ายๆ วิธีที่จะทำให้สิ่งนี้สำเร็จ

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

person Reed Copsey    schedule 20.10.2010
comment
บันทึกไว้สำหรับการอ้างอิงในอนาคต แต่ในกรณีที่ฉันใช้ลูปนี้ ลำดับการประมวลผลขององค์ประกอบนั้นไม่ได้เป็นปัญหาจริงๆ - person Gareth; 20.10.2010
comment
@Gareth: ฉันเพิ่งพูดถึงสิ่งนี้เนื่องจากมีการสนทนาจริง ๆ (ซึ่งฉันหา atm ไม่เจอ) โดย Stephen Toub กล่าวถึงโดยเฉพาะว่าทำไม Parallel.For ไม่ได้เพิ่มคุณสมบัตินี้ - และโดยพื้นฐานแล้วมันลงมาที่มันมักจะเป็นปัญหาสำหรับการขนาน กำลังประมวลผล แต่คุณสามารถแก้ไขได้ตลอดเวลาผ่านตัวแบ่งพาร์ติชันหรือ Parallel.foreach - person Reed Copsey; 20.10.2010
comment
ฉันเชื่อว่ากรณีการใช้งานนี้เกิดขึ้นอย่างเป็นธรรมชาติมากเมื่อทำงานกับคำสั่ง SIMD ใน .NET เนื่องจากคำสั่งเหล่านี้ทำงานโดยการสร้าง Vector<'T> สำหรับแต่ละองค์ประกอบที่ n ของอาร์เรย์ โดยที่ N คือความกว้างของเวกเตอร์ คุณไม่สามารถใช้ประโยชน์จาก Parallel.For สำหรับฟังก์ชันเวกเตอร์ขนาดเล็กได้ เนื่องจากตัวแจงนับหรือเทคนิคการคูณจะทำลายผลประโยชน์ที่สมบูรณ์แบบ - person jackmott; 26.07.2016

เพียงข้ามค่าคู่

Task.Factory.StartNew(() =>
                Parallel.For(1, _DataList.Length, i =>
                {
                    if(i % 2 == 0)
                    {
                        // do work for   
                    }   
                })
            );
person Junior    schedule 19.09.2015
comment
คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับคำตอบของคุณได้ไหม? โดยปกติแล้วการให้ข้อมูลหรือคำอธิบายสำหรับคำตอบที่คุณให้ถือเป็นแนวทางปฏิบัติที่ดี สิ่งนี้อาจช่วยเหลือผู้ใช้ในอนาคตหรือ OP ได้มากขึ้น - person Bono; 19.09.2015
comment
นี่ไม่ใช่ความคิดที่ดีในขณะที่คุณกำลังสร้างค่าใช้จ่ายและเป็นสิ่งที่ฉันพยายามหลีกเลี่ยง - ดูความคิดเห็นแรกของคำถาม โชคดีที่มีวิธีแก้ปัญหาที่ดีเมื่อ 5 ปีที่แล้ว :) - person Gareth; 21.09.2015