2010-02-23 34 views
13

Tôi có một ứng dụng là CPU chuyên sâu. Khi dữ liệu được xử lý trên một chủ đề duy nhất, việc sử dụng CPU sẽ tới 100% trong nhiều phút. Vì vậy, hiệu suất của ứng dụng dường như bị ràng buộc bởi CPU. Tôi đã đa luồng logic của ứng dụng, dẫn đến tăng hiệu suất tổng thể. Tuy nhiên, việc sử dụng CPU hầu như không vượt quá 30% -50%. Tôi mong đợi CPU (và nhiều lõi) đi đến 100% vì tôi xử lý nhiều tập hợp dữ liệu cùng một lúc.Lý do tại sao việc sử dụng CPU không đạt 100% với C# và APM là gì?

Dưới đây là ví dụ đơn giản về logic mà tôi sử dụng để bắt đầu chuỗi. Khi tôi chạy ví dụ này, CPU đi đến 100% (trên một máy lõi 8/16). Tuy nhiên, ứng dụng của tôi sử dụng cùng một mẫu thì không.

public class DataExecutionContext 
{ 
    public int Counter { get; set; } 

    // Arrays of data 
} 

static void Main(string[] args) 
{ 
    // Load data from the database into the context 
    var contexts = new List<DataExecutionContext>(100); 
    for (int i = 0; i < 100; i++) 
    { 
     contexts.Add(new DataExecutionContext()); 
    } 

    // Data loaded. Start to process. 
    var latch = new CountdownEvent(contexts.Count); 
    var processData = new Action<DataExecutionContext>(c => 
    { 
     // The thread doesn't access data from a DB, file, 
     // network, etc. It reads and write data in RAM only 
     // (in its context). 
     for (int i = 0; i < 100000000; i++) 
      c.Counter++; 
    }); 

    foreach (var context in contexts) 
    { 
     processData.BeginInvoke(context, new AsyncCallback(ar => 
     { 
      latch.Signal(); 
     }), null); 
    } 

    latch.Wait(); 
} 

Tôi đã giảm số lượng khóa xuống mức tối thiểu nghiêm ngặt (chỉ chốt đang khóa). Cách tốt nhất tôi tìm thấy là tạo ra một bối cảnh trong đó một luồng có thể đọc/ghi trong bộ nhớ. Các ngữ cảnh không được chia sẻ giữa các chủ đề khác. Chủ đề không thể truy cập cơ sở dữ liệu, tệp hoặc mạng. Nói cách khác, tôi đã lược tả đơn đăng ký của mình và tôi không tìm thấy bất kỳ nút cổ chai nào.

Tại sao việc sử dụng CPU của ứng dụng của tôi không giảm khoảng 50%? Đó có phải là mẫu tôi sử dụng không? Tôi có nên tạo chủ đề của riêng mình thay vì sử dụng hồ bơi chuỗi .Net không? Có gotchas nào không? Có công cụ nào mà bạn có thể giới thiệu cho tôi để tìm sự cố của tôi không?

Cảm ơn!

+0

Có thể, nhưng khá khó xảy ra sẽ là mã của bạn được kích hoạt một rất nhiều bộ sưu tập rác, đòi hỏi một số lượng đồng bộ hóa. –

Trả lời

6

Có nhiều điều có thể gây ra hành vi này.

Trước tiên, bạn có loại CPU nào? Nếu bạn có một bộ vi xử lý i7 hoặc tương tự, hệ điều hành sẽ thấy điều này là có 8 lõi, khi trong thực tế, nó có 4 lõi với 2 hyperthreads/core. Đối với hầu hết các hoạt động, siêu phân luồng không thực sự cung cấp khả năng mở rộng giống như một lõi thứ hai, mặc dù hệ điều hành nhìn thấy nó theo cách này. Tôi đã làm điều này khiến cho việc sử dụng CPU tổng thể của tôi xuất hiện thấp hơn đối với hệ điều hành ...

Thứ hai, có thể bạn có một số dạng chia sẻ thực sự xảy ra. Bạn đề cập rằng bạn có khóa - ngay cả khi nó được giữ ở mức tối thiểu, các khóa có thể ngăn bạn lập kế hoạch này một cách hiệu quả.

Ngoài ra, ngay bây giờ, bạn đang lên lịch cho tất cả 100 mục công việc, phải lên phía trước. Các os sẽ phải trang trong và ngoài những chủ đề 100. Bạn có thể muốn hạn chế điều này để chỉ cho phép một số lượng nhất định xử lý tại một thời điểm nhất định. Điều này là dễ dàng hơn nhiều bằng cách sử dụng thư viện song song nhiệm vụ mới (chỉ cần sử dụng Parallel.ForEach với một thiết lập ParallelOptions để có một số lượng tối đa của chủ đề) - nhưng có thể được thực hiện trên của riêng bạn.

Giả sử bạn đang lên lịch cho tất cả 100 mục để xử lý đồng thời, phân trang có thể cản trở khả năng nhận được thông lượng tối đa.

Ngoài ra, nếu bạn đang làm bất kỳ công việc "thực tế" nào khác - bạn có thể gặp sự cố chia sẻ sai, đặc biệt nếu bạn đang làm việc với mảng hoặc bộ sưu tập được chia sẻ (ngay cả khi các yếu tố bạn đang xử lý là không được chia sẻ).

Tôi khuyên bạn nên chạy ứng dụng này trong hồ sơ đồng thời trong VS 2010 - nó sẽ cung cấp cho bạn bức tranh rõ ràng hơn về những gì đang xảy ra.

+0

Tôi đã thử trên nhiều máy: Core Duo (sử dụng ~ 80-90%), i7 (sử dụng ~ 50%), Dual Xeon L5520 (sử dụng ~ 40-50%). – Martin

+0

Vì bạn ở 80-90% trong bộ đôi cốt lõi và thấp hơn so với những người khác, có vẻ như bạn có sự cố chia sẻ sai hoặc thật. Chia sẻ sai có thể xảy ra nếu bạn đang cố gắng sử dụng dữ liệu nằm quá chặt trong bộ nhớ, từ nhiều chủ đề - chia sẻ thực sự là do khóa ... –

+1

Tôi thấy rằng bài viết về MSDN về False Sharing (http: // msdn. microsoft.com/en-us/magazine/cc872851.aspx) và có vẻ như đó có thể là vấn đề của tôi ... Tôi không chắc chắn hoàn toàn hiểu được False Sharing. Làm thế nào bạn tìm ra điều này? – Martin

2

Đây là đặc tính mà không cần xem ứng dụng của bạn, nhưng nếu ứng dụng của bạn đang xử lý tệp, cơ sở dữ liệu, tạo nhiều đối tượng (yêu cầu bộ nhớ), làm việc với thiết bị mạng hoặc thiết bị phần cứng. có thể đang hạn chế ứng dụng của bạn đạt được mức sử dụng 100% cpu. Điều này kết hợp với chuyển đổi luồng cũng có thể là một yếu tố.

Bạn nói rằng bạn đang sử dụng mẫu của ví dụ bạn đã cung cấp, nhưng bạn nói ví dụ này đạt mức sử dụng 100% nhưng ứng dụng của bạn thì không. Vì vậy, có một số khác biệt ở đó, và bạn nên cố gắng mô tả chi tiết hơn những gì ứng dụng của bạn đang làm. 50% sử dụng không phải là xấu. Nhiều ứng dụng chạy ở mức 50% trên CPU Intel siêu luồng và chúng vẫn chạy tốt. Nếu ứng dụng không đạt tới mức sử dụng CPU 100% và bạn vẫn nhận được hiệu suất tốt, thì tôi sẽ nói đó thực sự là một điều tốt, bởi vì nó có nghĩa là bạn có một số phòng đầu vì nó không phải là CPU bị ràng buộc nữa. Điều này có nghĩa là các trường hợp mà những thứ khác có thể mất thời gian CPU, ứng dụng của bạn sẽ không bị ảnh hưởng nhiều. Nếu nó ở mức sử dụng 100% thì bạn sẽ thấy waver hiệu suất của ứng dụng khi các quá trình khác kích hoạt sử dụng CPU.

0

Nếu bạn đang làm cho rất nhiều cấp phát bộ nhớ nhỏ - đống quản lý có thể trở thành một nguồn tài nguyên chia sẻ rằng khối các chủ đề và làm chậm quá trình này và do đó sử dụng CPU

Các vấn đề liên quan