2010-11-11 44 views
5

Tôi đang viết một số mã sinh ra khá nhiều chủ đề (khoảng 512 vào lúc này, nhưng điều đó có thể cao hơn trong tương lai). Mỗi chủ đề chỉ thực hiện một số lượng nhỏ các hoạt động, vì vậy tôi muốn các chi phí mà các chủ đề đặt trên hệ thống được giữ ở mức tối thiểu.Kích thước ngăn xếp của chủ đề an toàn?

Tôi đang đặt kích thước ngăn xếp bằng cách sử dụng pthread_attr_setstacksize() và tôi có thể nhận kích thước ngăn xếp tối thiểu cho phép từ PTHREAD_STACK_MIN. Nhưng câu hỏi của tôi là: Có an toàn khi sử dụng PTHREAD_STACK_MIN cho kích thước ngăn xếp của luồng không? Làm cách nào để tính toán số lượng ngăn xếp tôi cần? Có bất kỳ chi phí ẩn nào mà tôi sẽ cần phải thêm vào tính toán của tôi không?

Ngoài ra, còn có bất kỳ kỹ thuật nào khác mà tôi có thể sử dụng để giảm gánh nặng của luồng trên hệ thống không?

Trả lời

4

Giảm kích thước ngăn xếp luồng sẽ không giảm chi phí (không phải về CPU, sử dụng bộ nhớ hoặc hiệu suất). Giới hạn duy nhất của bạn về khía cạnh này là tổng không gian địa chỉ ảo có sẵn cho các luồng trên nền tảng của bạn.

Tôi sẽ sử dụng kích thước ngăn xếp mặc định cho đến khi nền tảng hiển thị các sự cố khác (nếu xảy ra ở tất cả). Sau đó, giảm thiểu mức sử dụng ngăn xếp nếu và khi có sự cố phát sinh. Tuy nhiên, điều này sẽ dẫn đến các vấn đề hiệu suất thực tế, vì bạn sẽ cần phải tăng số lượng truy cập hoặc devise thread-dependent allocation ở nơi khác.

các chi phí ẩn có thể bao gồm:

  • Phân bổ mảng lớn trên stack, chẳng hạn như bằng VLA, alloca() hoặc chỉ đơn giản tĩnh có kích thước mảng tự động.
  • Mã bạn không kiểm soát hoặc không nhận thức được hậu quả của việc sử dụng như mẫu, lớp nhà máy, vv Tuy nhiên, do bạn không chỉ định C++, điều này ít có khả năng trở thành vấn đề.
  • Mã đã nhập từ tiêu đề thư viện, v.v. Có thể thay đổi giữa các phiên bản và thay đổi đáng kể ngăn xếp của chúng hoặc thậm chí sử dụng chuỗi.
  • Đệ quy. Điều này xảy ra do các điểm trên cũng được, hãy xem xét những thứ như boost::bind, mẫu variadic, macro điên, và sau đó chỉ đệ quy chung bằng bộ đệm hoặc đối tượng lớn trên ngăn xếp.

Bạn cũng có thể thiết lập kích thước ngăn xếp, thao tác ưu tiên luồng và tạm ngưng và tiếp tục chúng theo yêu cầu, điều này sẽ hỗ trợ đáng kể tính năng lập lịch và hệ thống. Pthreads cho phép bạn thiết lập phạm vi tranh chấp; LWP và trong phạm vi lập kế hoạch thay đổi rộng rãi trong đặc điểm hiệu suất của chúng.

Dưới đây là một số liên kết hữu ích:

+0

Cảm ơn Matt. Tôi nghĩ điều này gần nhất với câu trả lời tôi là Sau. Tôi đã hy vọng rằng ai đó sẽ nói "thêm sizeof() của tất cả các biến cục bộ của bạn, thêm 42 byte cho phí trên luồng và sau đó thêm 10% cho may mắn", nhưng có vẻ như có nhiều khả năng hơn lúc chơi. Cảm ơn những lời khuyên về các ưu tiên và đình chỉ. –

+2

@ ltn100: không, nó giống như "kiểm tra kỹ lưỡng mã của bạn với kích thước ngăn xếp được chỉ định, trong bối cảnh gỡ lỗi sẽ phát hiện tràn. Sau đó, thêm 10% cho may mắn". –

+2

@ ltn100: Nếu bạn có thể tìm thấy công cụ gỡ lỗi thực sự đo lường việc sử dụng ngăn xếp nước cao trên nền tảng của mình, điều đó tốt, nhưng nền tảng nơi bạn thực sự cần thực hiện điều này (vì stack là RAM vật lý phía trước) những người có công cụ gỡ lỗi tốt nhất. Và bạn phải * thực sự * kỹ lưỡng với thử nghiệm. Bất kỳ điều nhỏ nào, bao gồm các thay đổi đối với các thư viện mà bạn liên kết động hoặc các biến môi trường mà chúng nhìn vào, hoặc (theo nghĩa đen) vào ngày trong tuần, có thể làm tăng dấu nước cao của bạn. Tránh VLAs, tránh mọi đệ quy phụ thuộc vào dữ liệu đầu vào. –

7

Bạn không nên tạo bất kỳ nơi nào gần nhiều chuỗi đó và bạn chắc chắn không nên tạo một chuỗi mới để thực hiện một số thao tác nhỏ. Bạn nên tạo một chủ đề mới nếu và chỉ khi các chủ đề hiện tại của bạn (s) được bão hòa hoàn toàn VÀ có nhiều quan tâm vật lý hoặc hợp lý hơn để làm việc. Điều đó đặt một giới hạn cứng trên một ứng dụng hiện tại hợp lý vào khoảng 10 chủ đề hoặc lâu hơn, ngay cả khi bạn chạy trên một hexacore bạn chỉ cần 12 hoặc cao hơn. Một thiết kế như vậy là rất thiếu sót, sẽ sử dụng một lượng lớn bộ nhớ quá trình, và sẽ không thực sự cải thiện hiệu năng.

Đối với kích thước ngăn xếp, bạn không thể tính toán số lượng bạn cần cho một chuỗi tùy ý, vì nó hoàn toàn phụ thuộc vào mã chạy. Tuy nhiên, trong Visual Studio, kích thước stack điển hình là một vài megabyte. Bạn sẽ phải đăng toàn bộ mã và việc tháo gỡ kết quả được thực hiện bởi luồng để biết kích thước ngăn xếp sẽ sử dụng bao nhiêu. Chỉ cần gắn nó với một vài megabyte.

+1

+1: Nhưng bạn có thể muốn đề hơn lõi nếu chủ đề của bạn là thường xuyên IO-bound ... –

+0

@ Oli Nhưng không phải 50x nhiều. –

+4

@C. Ross: phụ thuộc vào cách I/O bị ràng buộc. OK, vì vậy có nhiều cách khác để xây dựng một hệ thống I/O không đồng bộ hiệu quả hơn trong tài nguyên (và có lẽ kém hiệu quả hơn trong thời gian của tôi, tùy thuộc vào mức độ tốt với hàng đợi sự kiện, 'select', v.v.) sẽ dành 99,8% thời gian chờ I/O mạng, sau đó tôi muốn 500 chủ đề. Đôi khi RAM rẻ hơn các lập trình viên, đôi khi nó không phải là ;-) –

5

Kích thước theo yêu cầu của các khung stack phụ thuộc vào trình biên dịch bạn sử dụng, về cơ bản bạn có thể thử để đoán kích thước của biến tự động của bạn, các thông số và một số chi phí cho sự trở lại địa chỉ, tiết kiệm thanh ghi, vv

Bạn nên xem xét liệu nó sẽ là một thay thế để sử dụng một Thread Pool. Vì việc tạo chuỗi không phải là miễn phí.

+1

Tôi hoài nghi về việc liệu các hồ luồng có lợi ích đáng kể cho việc triển khai hiện đại hay không. Không ai sử dụng 'LinuxThreads' và hack như thế nữa. Bạn có một tài liệu tham khảo cập nhật về chi phí tương đối của việc tạo chuỗi không? –

+1

Thật vậy. Tạo chủ đề khác nhau về chi phí, nhưng nói chung nó rẻ ở những ngày này. Tuy nhiên tôi nghĩ rằng điểm liên quan đến hồ bơi vẫn còn đứng. Họ là một công cụ hữu ích để xem xét, nhưng tôi thấy rằng hầu hết mọi người chỉ cố gắng tìm một lý do để sử dụng chúng. –