2012-01-11 46 views
10

Tôi đang giải quyết một vấn đề lớn hơn nhiều và đã gặp lỗi khi cố gắng sử dụng OpenMP để song song một số vòng lặp. Tôi đã sao chép vấn đề với một số mã đơn giản dưới đây bắt chước mã của riêng tôi.Sử dụng OpenMP và Eigen gây ra vòng lặp vô hạn/bế tắc

Vấn đề là khi tôi chạy chương trình, nó sẽ ngẫu nhiên đi vào một số loại vòng lặp vô hạn/bế tắc (CPU là 100%, nhưng không làm gì cả). Từ những gì tôi có thể nói từ thử nghiệm của tôi, một trong những chủ đề cố gắng để tính toán sản phẩm ma trận ma trận nhưng không bao giờ kết thúc vì một lý do nào đó.

Tôi biết rằng nếu bạn bật OpenMP, Eigen sẽ song song các sản phẩm ma trận ma trận bằng cách sử dụng OpenMP. Tôi cũng thêm một vòng lặp song song khác bên ngoài này. Tuy nhiên, lỗi này vẫn xảy ra nếu tôi vô hiệu hóa song song của Eigen bằng cách xác định EIGEN_DONT_PARALLELIZE.

Tôi đang sử dụng phiên bản gcc 4.6.0 20101127 trên MacOS 10.6.8 với Eigen 3.0.4.

tôi không thể tìm ra những gì có thể đi sai ...

#include <iostream> 
#include <Eigen/Core> 

using namespace std; 
using namespace Eigen; 

MatrixXd Test(MatrixXd const& F, MatrixXd const& G) 
{ 
    MatrixXd H(F.rows(), G.cols()); 
    H.noalias() = F*G; 

    return H; 
} 

int main() 
{ 
    MatrixXd F = MatrixXd::Random(2,2); 
    MatrixXd G = MatrixXd::Random(2,2); 

    #pragma omp parallel for 
    for (unsigned int i = 0; i < 10000; ++i) 
    MatrixXd H = Test(F,G); 

    cout << "Done!" << endl; 
} 
+0

Có phải 'MatrixXd :: Random' an toàn không? – Mysticial

+0

Trong mã thực sự của tôi, tôi không gọi MatrixXd :: Ngẫu nhiên. Chỉnh sửa: Tôi đã thay đổi mã để loại bỏ các cuộc gọi đến MatrixXd :: Ngẫu nhiên và lỗi vẫn còn đó. – user1144371

+0

nó không phải là một cái gì đó ngu ngốc như [this] (http://eigen.tuxfamily.org/dox/TopicWrongStackAlignment.html)? Bởi vì hiện tại điều này không giống như một lỗi openmp. Tôi đã tải xuống và chạy chương trình của bạn song song mà không gặp bất kỳ sự cố nào với phiên bản gcc 4.5.0 20100604. – Bort

Trả lời

10

Sau khi một số lỗi, tôi nghĩ vấn đề nằm ở Eigen. Trong tập tin src/Core/products/GeneralBlockPanelKernel.h có một chức năng gọi là manage_caching_sizes khai báo hai biến tĩnh:

static std::ptrdiff_t m_l1CacheSize = 0; 
static std::ptrdiff_t m_l2CacheSize = 0; 

Thay đổi này để:

static std::ptrdiff_t m_l1CacheSize = 0; 
static std::ptrdiff_t m_l2CacheSize = 0; 
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize) 

cố định vấn đề của tôi.

+2

Tôi chỉ nhận thấy rằng lỗi này đã được sửa trong các phiên bản Eigen gần đây, nhờ vào câu hỏi stackoverflow này, xem báo cáo lỗi: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=406 Vì vậy, bây giờ giải pháp sẽ là để cập nhật thư viện Eigen của bạn. – catchmeifyoutry

2

Tôi có cùng một vấn đề, ngay cả với phiên bản Eigen (3.0.5) gần đây nhất. Tôi đã thử sửa chữa đề xuất ở trên và nó không phải là có thể với phiên bản 3.0.5, vì các initializers mới. Vì vậy, tôi đã thực hiện thay đổi sau:

static std::ptrdiff_t m_l1CacheSize; 
static std::ptrdiff_t m_l2CacheSize; 
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize) 

if (m_l1CacheSize==0) 
{ 
    m_l1CacheSize = manage_caching_sizes_second_if_negative(queryL1CacheSize(),8 * 1024); 
    m_l2CacheSize = manage_caching_sizes_second_if_negative(queryTopLevelCacheSize(),1*1024*1024); 
} 

khắc phục sự cố của tôi.

2

Tôi đã gặp sự cố tương tự khi sử dụng Microsoft Visual Studio 2010 SP1 PPL/parallel_for. Các giải pháp được mô tả trong

http://eigen.tuxfamily.org/dox/TopicMultiThreading.html

Sử dụng Eigen trong một ứng dụng đa luồng

Trong trường hợp ứng dụng của riêng bạn là đa luồng, và nhiều đề thực hiện cuộc gọi đến Eigen, sau đó bạn phải khởi Eigen bởi gọi thói quen sau đây trước khi tạo chủ đề:

#include <Eigen/Core> 

int main(int argc, char** argv) 
{ 
    Eigen::initParallel(); 

    ... 
} 

Trong trường hợp ứng dụng của bạn được song song với OpenMP, bạn có thể muốn tắt tính năng song song của riêng Eigen như được mô tả chi tiết trong phần trước đó.

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