Bạn không thể dễ dàng phân biệt chất thải do chuyển đổi luồng và do sự tranh cãi về bộ nhớ cache. Bạn CÓ THỂ đo lường sự tranh chấp chủ đề .. Cụ thể là, trên Linux, bạn có thể cat/proc/PID/XXX và nhận được rất nhiều thống kê chi tiết cho mỗi luồng. TUY NHIÊN, vì bộ lập lịch trước sẽ không tự bắn vào chân, bạn sẽ không nhận được nhiều hơn 30 thiết bị chuyển mạch ctx mỗi giây cho dù bạn sử dụng bao nhiêu chủ đề .. Và thời gian đó sẽ tương đối nhỏ so với số lượng công việc bạn đang làm .. Chi phí thực tế của chuyển đổi ngữ cảnh là ô nhiễm bộ nhớ cache. ví dụ. có một xác suất cao mà bạn sẽ có phần lớn các cache nhớ khi bạn đã chuyển ngữ cảnh trở lại. Vì vậy, thời gian hệ điều hành và bối cảnh chuyển đổi-đếm có giá trị tối thiểu.
Giá trị thực sự có giá trị là tỷ lệ giữa các đường liên kết trong bộ nhớ cache giữa các luồng. Tùy thuộc vào CPU, một dòng bộ nhớ cache bẩn theo sau là một peer-CPU đọc là SLOWER hơn là một bộ nhớ cache-miss - bởi vì bạn phải ép buộc CPU ngang hàng để viết giá trị của nó cho mem chính trước khi bạn thậm chí có thể bắt đầu đọc .. CPU cho phép bạn kéo từ các dòng bộ nhớ cache ngang hàng mà không cần nhấn chính mem.
Vì vậy, điều quan trọng là hoàn toàn giảm thiểu BẤT CỨ cấu trúc bộ nhớ được sửa đổi chia sẻ .. Hãy làm mọi thứ như chỉ đọc nhất có thể .. BAO GỒM này chia sẻ bộ đệm FIFO (bao gồm cả nhóm điều hành) .. Cụ thể là nếu bạn đã sử dụng hàng đợi được đồng bộ hóa - thì mọi sync-op là vùng bộ nhớ bị dơ bẩn. Và nhiều hơn nữa, nếu tỷ lệ đủ cao, nó sẽ có khả năng kích hoạt một cái bẫy hệ điều hành để ngăn chặn, chờ đợi cho mutex của thread ngang hàng.
Lý tưởng là phân đoạn RAM, phân phối cho một số lượng công nhân cố định một đơn vị công việc lớn, sau đó sử dụng chốt đếm hoặc một số rào cản bộ nhớ khác (sao cho mỗi chuỗi chỉ chạm vào một lần). Lý tưởng nhất là bất kỳ bộ đệm tạm thời nào được cấp phát trước thay vì đi vào và ra khỏi một nhóm bộ nhớ dùng chung (mà sau đó gây ra sự tranh chấp bộ đệm). Java 'đồng bộ' khối đòn bẩy (đằng sau hậu trường) một không gian bộ nhớ hash-bảng chia sẻ và do đó kích hoạt không mong muốn bẩn-đọc, tôi đã không xác định nếu java 5 Khóa đối tượng tránh điều này, nhưng bạn vẫn tận dụng hệ điều hành quầy 't giúp đỡ trong thông lượng của bạn. Rõ ràng hầu hết các hoạt động OutputStream đều kích hoạt các cuộc gọi được đồng bộ hóa như vậy (và tất nhiên là thường làm đầy bộ đệm luồng chung).
Nói chung, kinh nghiệm của tôi là luồng đơn nhanh hơn việc xử lý mùn cho mảng byte-mảng/đối tượng chung, v.v. Ít nhất với các thuật toán sắp xếp/lọc đơn giản mà tôi đã thử nghiệm. Điều này đúng cả trong Java và C trong kinh nghiệm của tôi. Tôi đã không cố gắng FPU intesive ops (như phân chia, sqrt), nơi cache-dòng có thể ít yếu tố. Về cơ bản nếu bạn là một CPU duy nhất, bạn không có vấn đề về dòng bộ nhớ cache (trừ khi hệ điều hành luôn xóa bộ nhớ cache ngay cả trong các chủ đề được chia sẻ), nhưng đa luồng mua bạn ít hơn không có gì. Trong siêu phân luồng, đó là cùng một thỏa thuận. Trong cấu hình bộ nhớ cache L2/L3 được chia sẻ CPU đơn (ví dụ: AMD), bạn có thể tìm thấy một số lợi ích. Trong đa CPU Intel BUS, quên nó - chia sẻ ghi nhớ là tồi tệ hơn đơn luồng.
Nguồn
2011-08-09 11:30:10
Nếu bạn không muốn thiết kế ứng dụng, nhưng chỉ cần đo lường sự khác biệt về hiệu suất (có đọc lại câu hỏi của bạn). Sau đó, hy vọng thuật toán có thể được chia tuyến tính, sau đó được chuyển thành một số chủ đề có thể cấu hình, với 1 có thể có một đường dẫn mã thay thế đặc biệt. Sau đó, chỉ cần chạy mỗi (có thể có trước khi xuất cảnh zip up/proc/self/*). Cũng sử dụng ghi/báo cáo thời gian nano của đầu/cuối của mỗi luồng (thay vì đồng bằng của chúng). –