Borealid's answer bao gồm kiểm tra và tìm hiểu, không thể đánh bại như lời khuyên.
Nhưng có lẽ nhiều hơn để thử nghiệm điều này hơn bạn có thể nghĩ: bạn muốn chủ đề của bạn để tránh tranh chấp cho dữ liệu bất cứ nơi nào có thể. Nếu dữ liệu hoàn toàn chỉ đọc, thì bạn có thể thấy hiệu suất tốt nhất nếu các chuỗi của bạn đang truy cập dữ liệu "tương tự" - đảm bảo đi qua dữ liệu trong các khối nhỏ tại một thời điểm, vì vậy mỗi chuỗi đang truy cập dữ liệu từ same pages over and over again. Nếu dữ liệu là hoàn toàn chỉ đọc, thì sẽ không có vấn đề gì nếu mỗi lõi có bản sao riêng của các dòng bộ nhớ cache. (Mặc dù điều này có thể không tận dụng tối đa bộ nhớ cache của từng lõi.)
Nếu dữ liệu được sửa đổi theo bất kỳ cách nào, bạn sẽ thấy các cải tiến hiệu suất đáng kể nếu bạn giữ chủ đề cách từ mỗi khác .Hầu hết bộ nhớ lưu trữ dữ liệu dọc theo cache lines và bạn tuyệt vọng muốn giữ lại mỗi cache line from bouncing among CPUs để có hiệu suất tốt. Trong trường hợp đó, bạn có thể muốn giữ các luồng khác nhau chạy trên dữ liệu thực sự xa nhau để tránh việc chạy với nhau. Vì vậy: nếu bạn đang cập nhật dữ liệu trong khi làm việc trên nó, tôi khuyên bạn nên có N hoặc 2 * N thực hiện (đối với N lõi), bắt đầu chúng với SIZE/N * M làm điểm bắt đầu của chúng, cho các chủ đề từ 0 đến M. (0, 1000, 2000, 3000, cho bốn chủ đề và 4000 đối tượng dữ liệu.) Điều này sẽ cho bạn cơ hội tốt nhất để đưa các dòng bộ nhớ cache khác nhau vào mỗi lõi và cho phép các cập nhật tiếp tục mà không có dòng bộ nhớ cache nảy:
+--------------+---------------+--------------+---------------+--- ...
| first thread | second thread | third thread | fourth thread | first ...
+--------------+---------------+--------------+---------------+--- ...
Nếu bạn không cập nhật dữ liệu khi làm việc trên nó, bạn có thể muốn bắt đầu N hoặc 2 * N đề thi (đối với N lõi), bắt đầu chúng với 0, 1, 2, 3 , vv .. và di chuyển từng cái tiến lên bằng N hoặc 2 * N các phần tử với mỗi lần lặp. Điều này sẽ cho phép hệ thống bộ nhớ cache tìm nạp từng trang từ bộ nhớ một lần, điền vào bộ nhớ cache của CPU với dữ liệu gần như giống hệt nhau và hy vọng giữ cho mỗi lõi có dữ liệu mới.
+-----------------------------------------------------+
| 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 ... |
+-----------------------------------------------------+
tôi cũng khuyên bạn nên sử dụng sched_setaffinity(2)
trực tiếp trong mã của bạn để lực các chủ đề khác nhau để xử lý riêng của họ. Theo kinh nghiệm của tôi, Linux hướng tới keep each thread on its original processor rất nhiều, nó sẽ không di chuyển các tác vụ sang các lõi khác mà không hoạt động.
Điều đó sẽ có nhiều chủ đề! Tôi nghĩ bạn có nghĩa là số lõi, phải không? – dasblinkenlight
Giả sử rằng tất cả các thao tác trên các số nguyên có thể xảy ra hoàn toàn đồng thời, bạn chỉ cần chia cho số lõi. Nó là khó khăn hơn nhiều để ước tính khi công việc không thể được thực hiện đồng thời. –
Các chủ đề này có thực hiện bất kỳ (chặn) I/O hoặc bất kỳ hoạt động chặn nào như thông tin liên lạc mạng hoặc cơ sở dữ liệu không? Nếu không, thì có thể số lõi tối ưu là N. Trong trường hợp của bạn, 4. Nếu không, 2N hoặc 3N sẽ đáng thử nghiệm - trong khi một luồng đang làm I/O, một luồng khác có thể hoạt động. – selbie