Mengubah nilai tambahan dari loop C# Parallel.For

Saya ingin mengonversi loop for yang menambah iterator sebanyak 2 setiap pass menjadi loop Paralel For menggunakan TPL. Data tidak bergantung pada urutan atau dibatasi dengan cara apa pun, tetapi saya hanya ingin memproses data di setiap elemen lain dari array sumber saya (yaitu _Datalist pada kode di bawah), sehingga perlu bertambah 2.

Lingkaran Untuk Saya:

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

Apakah mungkin untuk memberi tahu loop paralel bahwa saya ingin menambah i sebanyak dua, bukan satu?

Inilah Parallel Loop, tapi yang jelas i hanya bertambah 1 setiap iterasi:

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

Saya dapat memberitahu badan loop bagian dalam untuk mengabaikan nilai ganjil dari i, tetapi itu tampaknya sedikit berantakan - apakah ada cara untuk melakukannya dalam inisialisasi loop?


person Gareth    schedule 20.10.2010    source sumber
comment
Jangan abaikan saja nilai ganjilnya; yang menciptakan tugas dua kali lebih banyak dari yang Anda perlukan, sehingga menambah banyak overhead yang tidak perlu.   -  person Gabe    schedule 20.10.2010
comment
Ya, saya mengerti maksud Anda   -  person Gareth    schedule 20.10.2010


Jawaban (4)


Bagaimana tentang:

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

Anda dapat mengurangi separuh jumlah langkah dan menggandakan indeks:

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

Jawaban Darin Dimitrov menunjukkan cara yang mudah cara untuk mencapai hal ini.

Namun, hal ini tidak ditambahkan, karena ini biasanya merupakan tanda bahwa badan perulangan tidak benar-benar berbeda. Dalam kebanyakan kasus, kebutuhan untuk menggunakan nilai kenaikan yang berbeda biasanya hanya muncul bersamaan dengan kebutuhan pemrosesan dalam urutan tertentu atau masalah lain yang akan menyebabkan paralelisasi untuk menciptakan kondisi balapan.

person Reed Copsey    schedule 20.10.2010
comment
Dicatat untuk referensi di masa mendatang, tetapi dalam kasus yang saya terapkan loop ini, urutan pemrosesan elemen sebenarnya tidak menjadi masalah - person Gareth; 20.10.2010
comment
@Gareth: Saya baru saja menyebutkan ini karena sebenarnya ada diskusi (yang saya tidak dapat menemukan atm) oleh Stephen Toub yang menyebutkan secara spesifik mengapa Parallel.For tidak menambahkan fitur ini - dan pada dasarnya itu biasanya bermasalah untuk paralel pemrosesan, tetapi Anda selalu dapat mengatasinya melalui partisi atau parallel.foreach. - person Reed Copsey; 20.10.2010
comment
Saya percaya kasus penggunaan ini muncul secara alami ketika bekerja dengan instruksi SIMD di .NET, karena mereka beroperasi dengan membuat Vector<'T> untuk setiap elemen ke-n dari sebuah array, di mana N adalah lebar vektor. Anda tidak dapat memanfaatkan Parallel.For untuk fungsi vektor kecil karena trik enumerator atau perkalian mengalahkan manfaat kinerja. - person jackmott; 26.07.2016

Lewati saja nilai genap.

Task.Factory.StartNew(() =>
                Parallel.For(1, _DataList.Length, i =>
                {
                    if(i % 2 == 0)
                    {
                        // do work for   
                    }   
                })
            );
person Junior    schedule 19.09.2015
comment
Bisakah Anda menjelaskan lebih lanjut tentang jawaban Anda? Memberikan informasi atau penjelasan atas jawaban yang Anda berikan biasanya dianggap sebagai praktik yang baik. Ini mungkin lebih membantu pengguna atau OP di masa mendatang. - person Bono; 19.09.2015
comment
Ini bukan ide yang baik karena Anda membuat overhead dan itulah yang saya coba hindari - lihat komentar pertama pada pertanyaan tersebut. Untungnya ada beberapa solusi bagus 5 tahun yang lalu :) - person Gareth; 21.09.2015