2009-10-12 30 views
7

Tôi đã sử dụng con trỏ được chia sẻ cho thời gian hiện tại và tôi có vấn đề về hiệu suất trong chương trình của mình ... Vì vậy, tôi muốn biết liệu con trỏ được chia sẻ có dẫn đến giảm hiệu suất hay không. Nếu vậy, thì làm thế nào cứng? Cảm ơn rất nhiều.Con trỏ chia sẻ và hiệu suất

Chương trình của tôi là đa luồng, sử dụng tiêu chuẩn :: tr1 :: shared_ptr

+6

Heh. Không có câu trả lời ở đây, nhưng tôi chỉ thích cách tiêu đề đã được phrased. Tôi đang hình dung các CPU vui vẻ thực hiện các hướng dẫn khi đột nhiên nó nhìn thấy một hướng dẫn chia sẻ con trỏ vào mặt sau của đường ống. "Ồ không, chuyện này sẽ huuuuurt ...... OW!" –

+0

Điều gì khiến bạn cho rằng vấn đề là con trỏ được chia sẻ? –

+0

Có người nói rằng họ lãng phí thời gian cpu, đó là: P – Guest

Trả lời

4

Con trỏ được chia sẻ được tính tham chiếu. Đặc biệt khi bạn đang sử dụng đa luồng, việc tăng và giảm số lượng tham chiếu có thể mất một lượng thời gian đáng kể. Lý do đa luồng đau ở đây là nếu bạn đã chuyển một con trỏ được chia sẻ giữa các chuỗi, số tham chiếu sẽ kết thúc được chia sẻ giữa các chuỗi đó, vì vậy mọi thao tác phải được đồng bộ hóa giữa các chuỗi. Điều đó có thể làm chậm mọi thứ xuống một chút.

Chỉnh sửa: Đối với những người quan tâm đến việc khóa liên động chuỗi chậm hơn có thể thực hiện một số thao tác khá đơn giản, hãy xem thử nghiệm của Herb Sutter với một vài triển khai CoW Strings. Mặc dù thử nghiệm của anh ấy không hoàn hảo (ví dụ: anh ấy chỉ thử nghiệm trên Windows), nó vẫn cho một số ý tưởng về loại chậm bạn có thể mong đợi. Đối với hầu hết các mục đích thực tế, bạn có thể/có thể nghĩ về một chuỗi CoW như một cái gì đó giống như một shared_ptr<charT>, với rất nhiều (không liên quan) chức năng thành viên được thêm vào.

+0

Điều này chỉ đúng nếu bạn sử dụng cơ chế đếm tham chiếu là luồng nhận biết. Nó không xuất hiện rằng đây là trường hợp theo các tài liệu http://www.boost.org/doc/libs/1_38_0/libs/smart_ptr/shared_ptr.htm#ThreadSafety – JaredPar

+2

Ông không nói những gì shared_ptr ông đang sử dụng. Một số đã được thread nhận thức, và một số thì không. Nó mở để đặt câu hỏi liệu người đó có đang sử dụng hay không. Điều đó nói rằng, bạn đã chắc chắn rằng cơ hội này là nguyên nhân của một vấn đề hiệu suất khá xa. –

+0

Đã thêm thông tin – Guest

10

Hầu như không thể trả lời chính xác câu hỏi này được cung cấp cho dữ liệu. Cách duy nhất để thực sự nói những gì đang gây ra một vấn đề hiệu năng trong ứng dụng của bạn là chạy một trình lược tả trên chương trình và kiểm tra đầu ra.

Điều đó đang được nói, rất khó xảy ra việc shared_ptr đang làm chậm tốc độ. Loại shared_ptr và nhiều biến thể được phát triển tại nhà sớm được sử dụng trong một số lượng ngày càng tăng của các chương trình C++. Bản thân tôi sử dụng chúng trong công việc của tôi (chuyên nghiệp ở nhà). Tôi đã dành rất nhiều thời gian để lược tả các ứng dụng công việc của tôi và shared_ptr chưa từng có vấn đề gì trong mã của tôi hoặc bất kỳ mã nào khác đang chạy trong ứng dụng. Có nhiều khả năng lỗi đó ở nơi khác.

3

Rất khó - bạn sẽ phải dành hầu hết thời gian để chuyển các con trỏ xung quanh.

Hiệu quả của ptr được chia sẻ thường nhỏ và khó xây dựng một trường hợp cạnh mà chúng trở thành vấn đề (giả sử triển khai đúng và trình biên dịch tối ưu hóa đúng).

Tác động của ptr chia sẻ:

  • tăng kích thước phân bổ.
    Điều đó chỉ quan trọng nếu bạn có nhiều con trỏ được chia sẻ cho các đối tượng rất nhỏ (ví dụ: hàng chục triệu shared_ptr<int>) và/hoặc đang hoạt động gần với giới hạn bộ nhớ. Có một khả năng nhỏ so với sự suy giảm hiệu suất đáng chú ý nếu phân bổ thêm vượt quá một mức độ bộ nhớ cache/NUMA trong một vòng lặp bên trong

  • tăng numer phân bổ
    shared_ptr allcoates một đối tượng theo dõi (tính tham khảo, số lượng yếu và deleter) . Điều này đặt áp lực lên heap và có thể gây ra suy giảm chung nếu bạn có tổng số phân bổ và deallocations cao.
    có thể tránh được bằng cách sử dụng make_shared, đặt referent và trackng đối tượng vào một phân bổ đơn

  • tham khảo đếm
    làm tăng chi phí của một bản sao của một con trỏ. Trong một ứng dụng đơn luồng, bạn sẽ nhận thấy rằng chỉ có bạn dành phần lớn thời gian sao chép con trỏ của bạn. Trong một ứng dụng đa luồng, bạn vẫn cần có sự tranh chấp cao trên cùng một con trỏ.
    Chi phí sao chép có thể được chia ở nhiều nơi bằng cách chuyển số shared_ptr<T> const & ví dụ: làm đối số hàm.

  • dereferencing
    Chi phí dereferencing thêm là zero trong xây dựng phát hành một trình biên dịch tối ưu hóa. Gỡ lỗi xây dựng thường tương đương với các cuộc gọi chức năng và kiểm tra NULL bổ sung. Tuy nhiên, đặc biệt là trong quá trình gỡ lỗi, bạn sẽ phải dành phần lớn thời gian cho các con trỏ dereferencing để tạo sự khác biệt.


Without informaiton thêm, chúng tôi không thể giúp bạn. Bạn cần mô tả "vấn đề hiệu suất" là gì (độ chậm nói chung, hoạt động nhất định mất nhiều thời gian, nhiều trao đổi) và một số số liệu quan trọng - ứng dụng của bạn làm gì, số lượng con trỏ thông minh, tần suất chúng được sao chép, và các hoạt động khác mà bạn chạy sẽ làm nảy sinh các con trỏ thông minh.

Hoặc bạn học cách sử dụng màn hình hiệu suất và/hoặc trình lược tả để tìm ra nguyên nhân gây ra sự chậm chạp và nếu có tắc nghẽn cụ thể.

5

Nếu chương trình của bạn có vấn đề về hiệu năng, bạn nên đoán xem vấn đề có thể là gì, nhưng nếu bạn muốn đặt cược, gần như 100% có thể là một thứ khác hoàn toàn. Hồ sơ có thể tìm thấy vấn đề. This is the method I use.

0

Một điều có thể làm tổn thương hiệu suất là vượt quá shared_ptr làm tham số hàm. Một giải pháp cho điều đó sẽ chuyển các tham chiếu đến shared_ptr. Tuy nhiên, đây là vi tối ưu hóa, vì vậy chỉ làm điều đó khi thực sự cần thiết

chỉnh sửa: Khi nghĩ về điều này, có những cách tốt hơn để tối ưu hóa:

  • Khi quá đi qua các con trỏ, có lẽ bạn nên để cho đối tượng làm điều gì đó thay vì kéo nó xung quanh.
  • Bạn có thể vượt qua (const) tham chiếu đến các đối tượng thay vì con trỏ
  • vượt qua một tham chiếu đến con trỏ khi con trỏ cần phải được thay đổi
0

Đừng đoán về hiệu suất: Profile mã của bạn.

12

Nếu ứng dụng của bạn đang truyền đi khoảng 700 byte tin nhắn XML có thể chứa trong 65 byte thông báo giao thức Google hoặc 85 byte tin nhắn ASN.1 thì có lẽ nó sẽ không quan trọng. Nhưng nếu nó được xử lý một triệu somethings một giây sau đó tôi sẽ không bỏ qua chi phí của việc thêm 2 đầy đủ đọc sửa đổi viết (RMW) chu kỳ để đi qua của một con trỏ.

Đọc sửa đổi đầy đủ ghi là theo thứ tự 50 ns vì vậy hai là 100 ns. Chi phí này là chi phí của một khóa-inc và một khóa-dec - giống như 2 CAS. Đây là một nửa của một cửa sổ dự trữ phần quan trọng và phát hành.Điều này được so sánh với một chu kỳ máy đơn lẻ (400 PICO giây trên máy 2.5GHZ)

Và điều này thậm chí không bao gồm các chi phí khác để làm mất hiệu lực dòng bộ nhớ cache thực sự chứa số, ảnh hưởng của khóa BUS trên các bộ xử lý khác, v.v.

Việc truyền con trỏ thông minh bằng tham chiếu const gần như luôn được ưa thích. Nếu callee không tạo ra một con trỏ chia sẻ mới khi anh ta muốn đảm bảo hoặc kiểm soát toàn bộ vòng đời của con trỏ thì đó là lỗi trong callee. Để đi tham khảo an toàn, các con trỏ thông minh xung quanh theo giá trị chỉ là yêu cầu các lần truy cập hiệu suất.

Việc sử dụng con trỏ tham chiếu giúp đơn giản hóa tuổi thọ không nghi ngờ, nhưng để chuyển con trỏ được chia sẻ theo giá trị để cố gắng bảo vệ chống lại các lỗi trong callee là vô nghĩa và hoàn toàn vô nghĩa.

Sử dụng quá nhiều tính tham chiếu có thể theo thứ tự ngắn sẽ biến một chương trình mảnh dẻ có thể xử lý các thông báo 1mm mỗi giây (mps) thành một phần chất béo xử lý 150k mps trên cùng một phần cứng. Đột nhiên bạn cần một nửa số máy chủ và $ 10000/năm tiền điện.

Bạn luôn tốt hơn nếu bạn có thể quản lý thời gian tồn tại của đối tượng mà không cần tính tham chiếu.

Một ví dụ về cải tiến đơn giản là nói nếu bạn định hâm mộ đối tượng và bạn biết bề rộng của quạt (n) tăng theo n thay vì tăng từng phần riêng lẻ.

BTW khi cpu nhìn thấy tiền tố khóa, nó thực sự nói "Ồ không có điều này sẽ làm tổn thương".

Tất cả những gì được nói, tôi đồng ý với mọi người rằng bạn nên xác minh điểm nóng.

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