2010-01-30 32 views
14

Tôi đang xây dựng một ứng dụng sẽ thực hiện theo dõi đối tượng từ nguồn cấp dữ liệu video và sử dụng thông tin từ đó để chạy hệ thống hạt trong OpenGL. Mã để xử lý nguồn cấp dữ liệu video có phần chậm, 200 - 300 mili giây cho mỗi khung hình ngay bây giờ. Hệ thống này sẽ chạy trên có một bộ xử lý lõi kép. Để tối đa hóa hiệu suất, tôi muốn giảm tải công cụ xử lý ảnh xuống một bộ xử lý và chỉ truyền dữ liệu liên quan trở lại ứng dụng chính vì nó có sẵn, trong khi vẫn để ứng dụng chính khởi động trên bộ xử lý khác.Cách cấu trúc ứng dụng C++ để sử dụng bộ xử lý đa lõi

Tôi cần làm gì để tắt công việc máy ảnh cho bộ xử lý khác và cách xử lý giao tiếp với ứng dụng chính?

Chỉnh sửa: Tôi đang chạy Windows 7 64 bit.

Trả lời

12

Về cơ bản, bạn cần đa luồng ứng dụng của mình. Mỗi luồng thực thi chỉ có thể bão hòa một lõi. Các luồng riêng biệt có xu hướng được chạy trên các lõi riêng biệt. Nếu bạn khăng khăng rằng mỗi thread LUÔN LUÔN thực thi trên một lõi cụ thể, thì mỗi hệ điều hành có cách riêng để xác định điều này (mặt nạ ái lực & chẳng hạn) ... nhưng tôi không khuyên bạn nên sử dụng nó.

OpenMP là tuyệt vời, nhưng đó là một chút mỡ trong ass, đặc biệt là khi tham gia trở lại từ một song song. YMMV. Thật dễ sử dụng, nhưng không phải ở tất cả các tùy chọn hoạt động tốt nhất. Nó cũng yêu cầu hỗ trợ trình biên dịch.

Nếu bạn đang sử dụng Mac OS X 10.6 (Snow Leopard), bạn có thể sử dụng Grand Central Dispatch. Thật thú vị khi đọc về, ngay cả khi bạn không sử dụng nó, vì thiết kế của nó thực hiện một số thực hành tốt nhất. Nó cũng không phải là tối ưu, nhưng nó tốt hơn so với OpenMP, mặc dù nó cũng yêu cầu hỗ trợ trình biên dịch.

Nếu bạn có thể quấn đầu xung quanh chia ứng dụng của bạn thành "công việc" hoặc "công việc", bạn có thể đẩy những công việc này xuống dưới nhiều ống như bạn có lõi. Hãy nghĩ đến việc xử lý hàng loạt của bạn dưới dạng đơn vị nguyên tử của công việc. Nếu bạn có thể phân đoạn chính xác, bạn có thể chạy xử lý máy ảnh của mình trên cả hai lõi và chuỗi chính của bạn cùng một lúc.

Nếu truyền thông được giảm thiểu cho mỗi đơn vị công việc, thì nhu cầu về mutexes và các nguyên tắc khóa khác sẽ được giảm thiểu. Khóa học hạt luồng là dễ dàng hơn nhiều hạt mịn. Và, bạn luôn có thể sử dụng thư viện hoặc khung làm việc để giảm gánh nặng. Hãy xem xét Boost's Thread library nếu bạn sử dụng phương pháp thủ công. Nó cung cấp các trình bao bọc di động và một sự trừu tượng tốt đẹp.

1

Bạn cần một số loại khung để xử lý đa lõi. OpenMP có vẻ là một lựa chọn khá đơn giản.

+2

Bạn cũng có thể chỉ sử dụng pthread hoặc bất kỳ hệ điều hành nào đã cung cấp. – pestilence669

+1

@Pestilence - vâng, mặc dù tôi muốn đề xuất các giải pháp đa nền tảng :) –

+0

lol. pthreads trên Cygwin sau đó! :) – pestilence669

2

Tôi khuyên bạn nên chống lại OpenMP, OpenMP là nhiều hơn cho mã số thay vì người tiêu dùng/mô hình sản xuất mà bạn dường như có.

Tôi nghĩ bạn có thể làm điều gì đó đơn giản bằng cách sử dụng các chủ đề nâng cao để sinh ra chuỗi công việc, bộ nhớ chung (để truyền dữ liệu thu được) và một số cơ chế thông báo để báo cho dữ liệu của bạn khả dụng (xem xét ngắt luồng).

Tôi không biết bạn xử lý loại công việc gì, nhưng bạn có thể xem các khối xây dựng chủ đề Intel và các nguyên tố tích hợp Intel, chúng có nhiều chức năng xử lý video nhanh hơn (giả sử chúng có chức năng)

+0

Xét rằng sự phân chia giữa người tiêu dùng và nhà sản xuất sẽ đạt được hầu như không có gì về hiệu quả, tôi nghĩ rằng anh ấy sẽ cần xử lý song song dữ liệu máy ảnh. Và không có cách nào dễ dàng để đảm bảo rằng một tăng thứ hai :: thread sẽ sinh ra trên lõi khác anyway ... –

+0

MPI sẽ là thực tế hơn trong trường hợp này tôi nghĩ. – tur1ng

+0

mà không biết chi tiết khó nói, nhưng nói chung tôi đồng ý với bạn. Trong Linux đất có tiện ích cpuset kiểm soát vị trí thread, đã không sử dụng nó bản thân mình mặc dù. theo ý kiến ​​của tôi mpi sẽ là một overkill, tôi không nghĩ rằng ông Bell có ý định chạy trên nhiều nút. – Anycorn

1

Tùy thuộc vào số lượng lõi bạn có. Nếu bạn chỉ có 2 lõi (CPU, bộ vi xử lý, hyperthreads, bạn biết những gì tôi có nghĩa là), sau đó OpenMP không thể cung cấp cho một sự gia tăng to lớn trong hiệu suất, nhưng sẽ giúp đỡ.Mức tăng tối đa bạn có thể có là chia thời gian của bạn cho số bộ vi xử lý sao cho nó vẫn sẽ mất 100 - 150 ms mỗi khung hình.

Phương trình là
thời gian song song = (([tổng thời gian để thực hiện một nhiệm vụ] - [code mà không thể được song song])/[số cpu]) + [mã mà không thể được song song]

Về cơ bản, OpenMP đá ở chế biến vòng lặp song song. Nó khá dễ sử dụng

#pragma omp parallel for 
for (i = 0; i < N; i++) 
    a[i] = 2 * i; 

và bang, bạn cho song song. Nó không hoạt động cho mọi trường hợp, không phải mọi thuật toán đều có thể được song song theo cách này nhưng nhiều thuật toán có thể được viết lại (bị tấn công) để tương thích. Nguyên tắc chính là Hướng dẫn đơn, Nhiều dữ liệu (SIMD), áp dụng cùng một mã chập cho nhiều pixel chẳng hạn.

Nhưng đơn giản việc áp dụng sổ ghi chép sách này đi ngược lại các quy tắc tối ưu hóa.
1-Benchmark mã của bạn
2-Tìm các tắc nghẽn REAL với "khoa học" bằng chứng (số) thay vì chỉ đoán mà bạn nghĩ rằng có một nút cổ chai
3-Nếu nó thực sự đang xử lý vòng, sau đó OpenMP là dành cho bạn

Có thể tối ưu hóa đơn giản trên mã hiện tại của bạn có thể mang lại kết quả tốt hơn, ai biết được?

Đường khác sẽ chạy opengl trong chuỗi và xử lý dữ liệu trên một chuỗi khác. Điều này sẽ giúp ích rất nhiều nếu opengl hoặc hệ thống kết xuất hạt của bạn mất rất nhiều năng lượng, nhưng hãy nhớ rằng luồng có thể dẫn đến các loại tắc nghẽn đồng bộ hóa khác.

0

Giống như những gì Pestilence đã nói, bạn chỉ cần ứng dụng của bạn được đa luồng. Rất nhiều các khuôn khổ như OpenMP đã được đề cập, vì vậy đây là một khác:

Intel Thread Building Blocks

Tôi chưa bao giờ sử dụng nó trước, nhưng tôi nghe những điều tuyệt vời về nó.

Hy vọng điều này sẽ hữu ích!

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