2011-02-03 28 views
5

Trong một trong các dự án của tôi, tôi đã xác định cuộc gọi đến std::deque<T>::clear() là một nút cổ chai lớn.Xóa STL trong chủ đề chuyên dụng

Vì vậy, tôi quyết định chuyển hoạt động này trong một chuyên dụng, chủ đề ưu tiên thấp:

template <class T> 
void SomeClass::parallelClear(T& c) 
{ 
    if (!c.empty()) 
    { 
     T* temp = new T; 
     c.swap(*temp); // swap contents (fast) 

     // deallocate on separate thread 
     boost::thread deleteThread([=]() { delete temp; }); 

     // Windows specific: lower priority class 
     SetPriorityClass(deleteThread.native_handle(), BELOW_NORMAL_PRIORITY_CLASS); 
    } 
} 

void SomeClass:clear(std::deque<ComplexObject>& hugeDeque) 
{ 
    parallelClear(hugeDeque); 
} 

Điều này dường như làm việc tốt (VisualC++ 2010), nhưng tôi tự hỏi nếu tôi bỏ qua bất kỳ lỗ hổng lớn. Tôi sẽ hoan nghênh ý kiến ​​của bạn về mã trên.

thông tin bổ sung:

SomeClass:clear() được gọi từ một GUI sợi, và giao diện người dùng là không đáp ứng cho đến khi trở về cuộc gọi. Mặt khác, hugeQueue không bị truy cập bởi chuỗi đó trong vài giây sau khi xóa.

+0

Có chậm không ngay cả khi bạn chạy mà không có trình gỡ lỗi được đính kèm? –

+0

Các hộp chứa STL không phải là chủ đề an toàn, vì vậy mã của bạn nên coi đó là tiền đề trước khi thực hiện các hoạt động trên các vùng chứa trong môi trường nhiều luồng. – DumbCoder

+0

Có. Các deque tôi thực sự sử dụng có chứa hàng triệu đối tượng (không ints) –

Trả lời

2

Điều này chỉ hợp lệ nếu bạn đảm bảo rằng quyền truy cập vào vùng heap được đăng. Windows hiện truy cập hàng loạt vào heap chính theo mặc định, nhưng có thể tắt hành vi này và không đảm bảo rằng nó hoạt động trên nền tảng hoặc thư viện. Như vậy, tôi sẽ cẩn thận tùy thuộc vào nó - hãy chắc chắn rằng nó được ghi nhận rõ ràng rằng nó phụ thuộc vào đống được chia sẻ giữa các luồng và rằng đống là an toàn luồng để truy cập.

Cá nhân tôi chỉ đơn giản đề xuất sử dụng trình phân bổ tùy chỉnh để khớp với mẫu phân bổ/deallocation sẽ là cải thiện hiệu suất tốt nhất ở đây - hãy nhớ rằng tạo chuỗi có chi phí không quan trọng.

Chỉnh sửa: Nếu bạn đang sử dụng thiết kế luồng kiểu GUI/công nhân, thì thực sự, bạn nên tạo, quản lý phá hủy đường dẫn trên chuỗi công nhân.

+0

@DeadMG: người ta có thể tắt serialization trên cơ sở cho mỗi hệ thống? Hay đây là một thiết lập thời gian biên dịch? –

+0

Vì vậy, trong phân bổ tùy chỉnh này, bạn sẽ sử dụng một đống chuyên dụng, mà bạn deallocate tất cả cùng một lúc khi thanh toán bù trừ? –

+0

@Daniel: Theo như tôi biết, bạn có thể thay đổi cài đặt khi chạy. Đối với người cấp phát tùy chỉnh của bạn, tôi không biết đủ về các mẫu phân bổ của bạn - nhưng nếu bạn có một đối tượng rất lớn và một loạt các deallocations, thì cũng có thể đáng để nó giải quyết toàn bộ đống. Tất nhiên, bạn vẫn phải hủy các đối tượng liên quan. – Puppy

1

Xin lưu ý rằng không chắc chắn rằng điều này sẽ cải thiện hiệu suất tổng thể của ứng dụng của bạn. Các cửa sổ tiêu chuẩn heap (cũng là phân mảnh thấp đống) không được đặt ra để thường xuyên truyền thông tin phân bổ từ một sợi khác. Điều này sẽ làm việc, nhưng nó có thể sản xuất khá một chi phí chế biến.

Các tài liệu của các cấp phát bộ nhớ tích trữ có thể là một điểm khởi đầu không nhận được sâu hơn vào rằng: http://www.cs.umass.edu/~emery/hoard/hoard-documentation.html

cách tiếp cận của bạn sẽ cải thiện mặc dù đáp ứng, vv

+0

Cảm ơn bạn đã trả lời. Trong trường hợp của tôi, heap thường sẽ được truy cập 1'000'000 lần từ chuỗi A, sau đó cùng một số tiền từ chuỗi B (để deallocate các đối tượng được phân bổ bởi A), và như vậy. Vì vậy, tôi không chuyển đổi thường xuyên. Nhưng tôi sẽ kiểm tra các lựa chọn thay thế với các trình phân bổ cụ thể (phần còn lại của ứng dụng đã thực hiện và sử dụng các thói quen quản lý bộ nhớ cụ thể của riêng nó). –

0

Ngoài những điều được đề cập bởi các áp phích khác bạn nên xem xét nếu các đối tượng chứa trong bộ sưu tập có ái lực luồng, ví dụ đối tượng COM trong căn hộ có ren đơn lẻ có thể không tuân theo loại lừa này.

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