2012-02-15 39 views
5

CPU của tôi là Core i3 330M với 2 lõi và 4 luồng. Khi tôi thực hiện lệnh cat /proc/cpuinfo trong terminal của tôi, nó giống như tôi có 4 CPUS. Khi tôi sử dụng chức năng OpenMP get_omp_num_procs() Tôi cũng nhận được 4.OpenMP và lõi/chủ đề

Bây giờ tôi có một lớp vectơ C++ chuẩn, tôi có nghĩa là một lớp mảng kép có kích thước cố định không sử dụng các mẫu biểu thức. Tôi đã cẩn thận song song tất cả các phương pháp của lớp và tôi nhận được tốc độ "mong đợi".

Câu hỏi đặt ra là: tôi có thể đoán tốc độ tăng tốc dự kiến ​​trong trường hợp đơn giản như vậy không? Ví dụ, nếu tôi thêm hai vectơ không song song cho các vòng lặp tôi nhận được một thời gian (sử dụng lệnh thời gian shell). Bây giờ nếu tôi sử dụng OpenMP, tôi có nên chia thời gian chia cho 2 hoặc 4, theo số lõi/chủ đề không? Tôi nhấn mạnh rằng tôi chỉ yêu cầu vấn đề đơn giản đặc biệt này, nơi không có sự phụ thuộc lẫn nhau trong dữ liệu và mọi thứ đều là tuyến tính (bổ sung vectơ).

Dưới đây là một số mã:

Vector Vector::operator+(const Vector& rhs) const 
{ 
    assert(m_size == rhs.m_size); 
    Vector result(m_size); 
    #pragma omp parallel for schedule(static) 
    for (unsigned int i = 0; i < m_size; i++) 
      result.m_data[i] = m_data[i]+rhs.m_data[i]; 

    return result; 
} 

Tôi đã đọc bài này: OpenMP thread mapping to physical cores.

Tôi hy vọng rằng ai đó sẽ cho tôi biết thêm về cách OpenMP hoàn thành công việc trong trường hợp đơn giản này. Tôi nên nói rằng tôi là một người mới bắt đầu trong tính toán song song.

Cảm ơn!

Trả lời

3

EDIT: Bây giờ, một số mã đã được thêm vào.

Trong ví dụ cụ thể đó, có rất ít tính toán và rất nhiều quyền truy cập bộ nhớ. Vì vậy, hiệu suất sẽ phụ thuộc rất nhiều vào:

  • Kích thước của vec-tơ.
  • Cách bạn định thời gian. (bạn có một vòng lặp ngoài cho mục đích thời gian)
  • Liệu dữ liệu đã có trong bộ nhớ cache chưa.

Đối với kích thước véc tơ lớn hơn, bạn có thể thấy hiệu suất bị giới hạn bởi băng thông bộ nhớ của bạn. Trong trường hợp đó, song song sẽ không giúp ích gì nhiều. Đối với kích thước nhỏ hơn, chi phí của luồng sẽ chiếm ưu thế. Nếu bạn đang tăng tốc "mong đợi", có thể bạn đang ở đâu đó ở giữa kết quả tối ưu.

Tôi từ chối cung cấp số cứng vì nói chung, "đoán" hiệu suất, đặc biệt trong các ứng dụng đa luồng là nguyên nhân bị mất trừ khi bạn có kiến ​​thức kiểm tra trước đó hoặc kiến ​​thức thân mật của cả chương trình và hệ thống đang chạy.

Cũng như một ví dụ đơn giản lấy từ câu trả lời của tôi ở đây: How to get 100% CPU usage from a C program

Trên một Core i7 920 @ 3.5 GHz (4 lõi, 8 bài):

Nếu tôi chạy với 4 đề, kết quả là:

This machine calculated all 78498 prime numbers under 1000000 in 39.3498 seconds 

Nếu tôi chạy với 4 đề và rõ ràng (sử dụng Task Manager) ghim bài trên 4 lõi vật lý riêng biệt, kết quả là:

This machine calculated all 78498 prime numbers under 1000000 in 30.4429 seconds 

Vì vậy, điều này cho thấy làm thế nào không thể đoán trước nó là ngay cả một ứng dụng song song rất đơn giản và đáng xấu hổ. Các ứng dụng liên quan đến việc sử dụng bộ nhớ nặng và đồng bộ hóa nhận được nhiều điều xấu hơn ...

1

Để thêm vào câu trả lời Mysticals. Vấn đề của bạn hoàn toàn là băng thông bộ nhớ bị chặn. Hãy xem STREAM benchmark. Chạy nó trên máy tính của bạn trong trường hợp đơn và đa luồng, và nhìn vào kết quả Triad - đây là trường hợp của bạn (tốt, gần như, vì vector đầu ra của bạn là cùng một lúc trong các vectơ đầu vào của bạn). Tính toán số lượng dữ liệu bạn di chuyển và Bạn sẽ biết chính xác hiệu suất mong đợi.

Tính năng đa luồng có hoạt động cho vấn đề này không? Vâng. Thật hiếm khi một lõi CPU duy nhất có thể bão hòa toàn bộ băng thông bộ nhớ của hệ thống. Máy tính hiện đại cân bằng băng thông bộ nhớ có sẵn với số lượng lõi có sẵn. Từ kinh nghiệm của tôi, bạn sẽ cần khoảng một nửa số lõi để bão hòa băng thông bộ nhớ bằng thao tác ghi nhớ đơn giản. Nó có thể mất một vài chi tiết nếu bạn làm một số tính toán trên đường.

Lưu ý rằng trên hệ thống NUMA, bạn sẽ cần phải liên kết các chuỗi với lõi CPU và sử dụng phân bổ bộ nhớ cục bộ để có được kết quả tối ưu. Điều này là do trên các hệ thống như vậy, mỗi CPU có bộ nhớ cục bộ riêng của nó, mà truy cập là nhanh nhất. Bạn vẫn có thể truy cập toàn bộ bộ nhớ hệ thống như trên các SMP thông thường, nhưng chi phí truyền thông này phải chịu chi phí - CPU phải trao đổi dữ liệu một cách rõ ràng. Các luồng liên kết tới CPU và sử dụng phân bổ cục bộ là cực kỳ quan trọng. Không thực hiện được điều này sẽ giết chết khả năng mở rộng. Kiểm tra libnuma nếu bạn muốn làm điều này trên Linux.

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