2015-02-26 4 views
0

У меня есть следующий код Fortran, который вызывает функцию C++ parallel_klu. parallel_klu создает восемь потоков (для выполнения другой функции, называемой factor) каждый раз, когда она вызывается, и после ее возвращения в Fortran потоки уничтожаются.Фортран и потоки C++

program linkFwithCPP   
    use iso_c_binding 
    implicit none 
    interface 
    subroutine my_routine (Ax, Ai, Ap, b, n, nz) bind (C, name = "parallel_klu") 
    import :: c_double 
    import :: c_int 
    integer (c_int), intent (out), dimension (*) :: Ap 
    integer (c_int), intent (out), dimension (*) :: Ai 
    real (c_double), intent (out), dimension (*) :: Ax 
    real (c_double), intent (out), dimension (*) :: b 
    integer(c_int), value :: n 
    integer(c_int), value :: nz 
    end subroutine 
    end interface 


    integer,parameter ::n=10 
    integer,parameter ::nz=34 

    ! declare the 4 arrays 
    real (c_double), dimension (0:nz-1) :: Ax 
    real (c_double), dimension (0:n-1) :: b 
    integer (c_int), dimension (0:n) :: Ap 
    integer (c_int), dimension (0:nz-1) :: Ai 
    !Inputing array values 
    open(unit = 1, file = 'Ax.txt') 
    read(1,*) Ax   
    close(1) 

    open(unit = 2, file = 'Ai.txt') 
    read(2,*) Ai    
    close(2) 

    open(unit = 3, file = 'Ap.txt') 
    read(3,*) Ap    
    close(3) 

    open(unit = 4, file = 'b.txt') 
    read(4,*) b    
    close(4) 


    ! Call C++ function 
    call my_routine(Ax, Ai, Ap, b, n, nz) 
    write (*, *) "Fortran: b:", b 
    pause 
end program linkFwithCPP 

Функция в C++ заключается в следующем:

void parallel_klu(double Ax[], int Ai[], int Ap[], double b[], const int n, const int nz) 
{ 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 0, 5000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 5000, 10000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 10000, 15000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 15000, 20000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 20000, 25000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 25000, 30000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 30000, 35000)); 
    threadList.push_back(std::thread(factor, Ap, Ai, Ax, b, Q, P, Pinv, n, 35000, 40000)); 

// wait for all threads to finish 
for (auto& threadID : threadList){ 
    threadID.join(); 
} 

} 

Есть ли способ избежать создания 8 потоков каждый раз, когда функция parallel_klu называется? Что-то вроде создания их для самого первого вызова, а затем просто отправки сигнала для того, чтобы потоки выполнялись снова.

+0

просто используйте OpenMP –

ответ

0

Во-первых, я бы настоятельно рекомендовал выяснить, является ли создание потоков убийством производительности вашего приложения.

Если это так, вы можете использовать концепцию, называемую пулом потоков, которая представляет собой набор потоков, к которым вы можете отправлять задачи, и поддерживает потоки, созданные/действующие, когда ничего не нужно делать. Эта концепция также может использоваться для фиксации числа рабочих потоков. Некоторые полезные рекомендации приведены в this answer.