: 어떤 상황에서
- , 나는 함수 접근법을 통해 서브 루틴 방식을 사용하여 더 나은 성능을 얻을 수 있나요?
- 성능이 저하되면 왜 기능을 사용하고 싶습니까?
첫 번째 질문에 대해 중요한 점은 스스로 테스트하는 것이 가장 좋습니다. 특정 측면이 많이 있습니다.
그러나 나는 당신을 안내 할 수있는 어떤 것을 빠르게 노크했습니다. 이와
module test
implicit none
type t1
real, allocatable :: x(:)
end type t1
contains
function div_fun(f,g) result(q)
type(t1), intent(in) :: f, g
type(t1) q
q%x = f%x/g%x
end function div_fun
subroutine div_sub1(f, g, q)
type(t1), intent(in) :: f, g
type(t1), intent(out) :: q
q%x = f%x/g%x
end subroutine div_sub1
subroutine div_sub2(f, g, q)
type(t1), intent(in) :: f, g
type(t1), intent(inout) :: q
q%x(:) = f%x/g%x
end subroutine div_sub2
end module test
, 나는 때때로 함수와 서브 루틴을 사용하여 사이에 유의 한 차이가 없음을 관찰하고, 때로는 있었다. 즉, 컴파일러, 플래그 등에 따라 다릅니다.
그러나 무슨 일이 일어나는지주의하는 것이 중요합니다.
결과에 할당이 필요하며 서브 루틴 div_sub1
의 경우 intent(out)
인수에는 할당이 필요합니다. [함수 결과를 할당하면 나중에 추가됩니다.상기 할당이 재사용된다 div_sub2
에서
(이하 "결과"인자이다 intent(inout)
) 우리는 q%x(:)
를 사용하여 자동으로 재 할당을 억제. 후자의 부분은 중요합니다. 컴파일러는 크기 조정의 필요 여부를 확인하기 위해 오버 헤드를 자주 겪습니다. 이 후반 부분은 q
의 의도를 div_sub1
에서 inout
으로 변경하여 테스트 할 수 있습니다.
[이 div_sub2
접근 방식에는 크기가 변하지 않는다는 가정이 있습니다. 이것은 텍스트에 의해 뒷받침 된 것으로 보입니다.]
첫 번째 질문에 대해 결론을 내리면 : 직접 확인하십시오.하지만 파생 된 유형을 사용하여 할당을 단순히 "숨기고 있는지"궁금합니다. 매개 변수화 된 파생 유형을 사용하면 매우 다른 답변을 얻을 수 있습니다.
두 번째 질문과 관련하여 기능이 일반적으로 사용되는 이유는 무엇입니까? (당신이 요청했습니다 이전 질문) 질문 텍스트와 링크에서
q = div_fun(f,g)
call div_sub2(f,g,q) ! Could be much faster
난 당신이 /
연산자를 오버로드 무언가가 있다고 가정합니다 : 당신은 내가 매우 특별한 경우 검토 한주의 것 우리가이 이항 연산자로 사용할 수 있습니다로
q = f/g ! Could be slower, but looks good.
call div_sub2(f,g,q)
을 허용
interface operator (/)
module procedure div_fun
end interface
(참조 포트 2008 7.1.5, 7.1.6 실행) 절차는 반드시 함수 여야합니다. 이 답변의 이전 개정판에 대한 귀하의 의견에 대한 응답으로
div_sub1 및 div_sub2 이진 연산자는 div_fun과 동일하지 않습니까?
적어도 포트란이 2 진수 연산자 (위와 같은 링크)로 정의하는 점에서 대답은 "아니오"입니다. [div_fun
자체가 이진 연산자가 아니기 때문에 함수와 함수를 결합한 일반 인터페이스의 조합]
이진 연산을 사용하면 식의 일부가 될 수 있습니다.
q = q + alpha*(f/g) ! Very neat
call div_sub2(f,g,temp1)
call mult_sub(alpha, temp1, temp2)
call add_sub(q, temp2, temp3)
call assign_sub(q, temp3)
서브 루틴을 사용하면 약간 지저분해질 수 있습니다. 위의 예제는 "적절한"측면 (또는 전문 서브 루틴)을 처리하여 약간 정돈 될 수 있지만, 이것이 최종 점이됩니다. 함수 결과가 (할당 포함) 나중에 사용하기 전에 완전히 평가되기 때문에 우리는 두 번째 질문에 대한 결론적으로
f = f/g ! or f=div_fun(f,g)
call div_sub2(f,g,f) ! Beware aliasing
같은 상황이 : 성능이 전부는 아니예요.
[당신은 표준 준수를 적용하면/표시하기 위해 .f90
및 .f03
파일 접미사를 사용하는 것을 의미하는 경우 마지막으로, 당신은 사람들이 그것에 대해 어떻게 생각하는지 볼 수 있습니다.]
예, 감사 – Charlie