Tôi đã thử nghiệm hiệu suất của System.Threading.Parallel vs Threading và tôi ngạc nhiên khi thấy Parallel mất nhiều thời gian hơn để hoàn thành các tác vụ hơn là luồng. Tôi chắc chắn đó là do kiến thức giới hạn của tôi về Song song, mà tôi mới bắt đầu đọc.C# Song song Vs. Hiệu suất mã luồng
Tôi nghĩ tôi sẽ chia sẻ một vài đoạn trích và nếu có ai có thể chỉ ra cho tôi mã paralle đang chạy chậm hơn so với mã luồng. Cũng cố gắng chạy so sánh tương tự để tìm số nguyên tố và tìm thấy mã song song kết thúc muộn hơn nhiều so với mã luồng.
public class ThreadFactory
{
int workersCount;
private List<Thread> threads = new List<Thread>();
public ThreadFactory(int threadCount, int workCount, Action<int, int, string> action)
{
workersCount = threadCount;
int totalWorkLoad = workCount;
int workLoad = totalWorkLoad/workersCount;
int extraLoad = totalWorkLoad % workersCount;
for (int i = 0; i < workersCount; i++)
{
int min, max;
if (i < (workersCount - 1))
{
min = (i * workLoad);
max = ((i * workLoad) + workLoad - 1);
}
else
{
min = (i * workLoad);
max = (i * workLoad) + (workLoad - 1 + extraLoad);
}
string name = "Working Thread#" + i;
Thread worker = new Thread(() => { action(min, max, name); });
worker.Name = name;
threads.Add(worker);
}
}
public void StartWorking()
{
foreach (Thread thread in threads)
{
thread.Start();
}
foreach (Thread thread in threads)
{
thread.Join();
}
}
}
Đây là chương trình:
Stopwatch watch = new Stopwatch();
watch.Start();
int path = 1;
List<int> numbers = new List<int>(Enumerable.Range(0, 10000));
if (path == 1)
{
Parallel.ForEach(numbers, x =>
{
Console.WriteLine(x);
Thread.Sleep(1);
});
}
else
{
ThreadFactory workers = new ThreadFactory(10, numbers.Count, (min, max, text) => {
for (int i = min; i <= max; i++)
{
Console.WriteLine(numbers[i]);
Thread.Sleep(1);
}
});
workers.StartWorking();
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds.ToString());
Console.ReadLine();
Cập nhật:
Lấy Khóa cân nhắc: Tôi đã thử đoạn sau. Một lần nữa kết quả tương tự, song song dường như kết thúc chậm hơn nhiều.
đường dẫn = 1; cieling = 10000000;
List<int> numbers = new List<int>();
if (path == 1)
{
Parallel.For(0, cieling, x =>
{
lock (numbers)
{
numbers.Add(x);
}
});
}
else
{
ThreadFactory workers = new ThreadFactory(10, cieling, (min, max, text) =>
{
for (int i = min; i <= max; i++)
{
lock (numbers)
{
numbers.Add(i);
}
}
});
workers.StartWorking();
}
Cập nhật 2: Chỉ cần một cập nhật nhanh chóng mà máy tính của tôi có Quad Core Processor. Vì vậy, song song có 4 lõi có sẵn.
Bạn không nên khóa trên ForEach, nó thực hiện nội bộ này. Nhưng sử dụng ReaderWriterLockSlim, sẽ làm cho nó nhanh trở lại;) –
Đặt ThreadFactory của bạn thành 2 luồng và đặt đồng thời tối đa trên Parallel.For thành 2, loại bỏ Console.WriteLine và làm điều gì đó phù hợp hơn. Bây giờ họ so sánh như thế nào? Hãy thử 3 và 3; 4 và 4; ... Tại một số điểm Parallel.ForEach sẽ quyết định nó phân bổ đủ chủ đề và sẽ phân bổ ít hơn tối đa bạn nói với nó, nhưng ít nhất là đến thời điểm đó bạn sẽ được so sánh timings bằng cách sử dụng * cùng * số chủ đề. –
@Hightechrider: Vâng về ném khối lượng công việc thực tế vào nó, như tôi đã đề cập trong câu hỏi, tôi đã thử nghiệm điều này trước việc tìm kiếm số nguyên tố, xử lý khá chuyên sâu, cho thấy 100% hoạt động trong suốt và thấy rằng ThreadFactory chạy waaaaaayyy nhanh hơn. Hãy thử nó ra và xem .. Tôi thậm chí đã cố gắng thiết lập số lượng thread đến 2,3 vv Kết quả tương tự. – ace