루프 뒤 또는 루프 내부에서 변수를 선언하시겠습니까? - 페이지 11

 
Vict :

내가 보니 단일 컴파일러가 https://en.cppreference.com/w/cpp/compiler_support 모듈을 완료하지 않았으므로 볼 것이 없습니다.

여전히 clang을 통해 모듈을 사용했습니다.

 // module
export module M;
export int f( int x) {
     return 2 + x;
}

// main.cc
import M;
int main() {
         for ( int i = 0 ;  i < 1000000 ;  ++ i)
                f( 5 );
}

최적화로 컴파일하면 사이클이 전혀 실행되지 않습니다(즉, 최적화는 번역 단위 + 포함된 모듈 간에 수행되며 이전과 같이 하나의 번역 단위에서만 수행되지 않음). LTO 없이. std c ++는 완전히 모듈인 IMHO로 이동할 수 있는 후보이며 질문이 없을 것입니다. "이 인공적인 예제에서 베어 사이클이 왜 그렇게 느린가요?"

 
Alexey Navoykov :

그래서 그들은 다음과 같은 경우에도 그가 매번 메모리를 할당하고 삭제한다는 것을 알게 된 것 같습니다.


그건 그렇고, 나는 지난 시간에 잘못된 결과를 제공했을 수도 있습니다. x86 모드일 가능성이 큽니다. 이제 x64에서 테스트 중입니다. C ++의 결과가 훨씬 좋습니다.

1) ~ 2000ms

2) ~200ms(3배 빨라짐)

사실, Studio도 최신 버전으로 업데이트했는데, 분명히 이것 역시 영향을 받았기 때문입니다. x86도 이제 과거 측정보다 빠릅니다.

글쎄, 일반적으로 이제 C ++는 Sharpe를 그렇게 부끄럽게 배수하지 않습니다. 총 약 3회

흠, 그래서 가비지 컬렉터가 없는데, 정의에 대한 질문은 무엇입니까?

나는 속도에 대해 말하는 것이 아니라 메모리에 대해 말하는 것입니다
 
Alexey Navoykov , constexpr 문자열과 벡터가 C++20으로 끌어온 것으로 나타났습니다. 저것들. 우리의 이러한 모든 테스트는 한 줄 유지 관리 명령을 전혀 사용하지 않으며 거기에 메모리를 할당하는 등의 작업을 수행합니다. (물론 캐릭터들이 당시의 상처에서 나오지 않는다면). 시원한.
 
Vict :
Alexey Navoykov , constexpr 문자열과 벡터가 C++20으로 끌어온 것으로 나타났습니다. 저것들. 우리의 이러한 모든 테스트는 한 줄 유지 관리 명령을 전혀 사용하지 않으며 거기에 메모리를 할당하는 등의 작업을 수행합니다. (물론 캐릭터들이 당시의 상처에서 나오지 않는다면). 시원한.

따라서 이를 위해서는 모든 것을 constexpr로 명시적으로 표시해야 합니다. 아니면 자동으로 결정할까요?

내가 볼 때 문제는 표준이 아니라 컴파일러에 있습니다. 그가 지금 초과분을 자르지 못하도록 막는 것이 있습니까? Sharp 컴파일러가 정상적으로 최적화 되고 동일한 Microsoft 의 플러스 버전이 실패하는 것이 특히 이상합니다. (그런 구조를 최적화한다는 측면에서) 공통 기반이 있어야 하는 것처럼 보이지만

 
Alexey Navoykov :

따라서 이를 위해서는 모든 것을 constexpr로 명시적으로 표시해야 합니다. 아니면 자동으로 결정할까요?

자동으로 컴파일 타임에 알려진 줄이 문자열에 들어가는 것으로 충분합니다. 이 문자열을 사용하는 모든 작업(검색, 바꾸기, ...)은 컴파일 시간에 동일합니다(Sharpe와 Mkl도 컴파일 시간에 우리의 예를 고려한 것 같습니다). 계획은 모든 컨테이너를 constepxr로 만드는 것입니다. 저것들. 더 이상 컴파일러의 기분에 의존하지 않지만 표준에 의해 보장됩니다. 예를 들어 문자열 구문 분석을 통해 템플릿 매개변수를 계산할 수 있습니다. 흥미로운 점은 다음과 같습니다. new/delete가 이제 constexpr(constexpr 유형의 경우)이기도 합니다.

내가 볼 때 문제는 표준이 아니라 컴파일러에 있습니다. 그가 지금 초과분을 자르지 못하도록 막는 것이 있습니까? Sharp 컴파일러가 정상적으로 최적화 되고 동일한 Microsoft 의 플러스 버전이 실패하는 것이 특히 이상합니다. (그런 구조를 최적화한다는 측면에서) 공통 기반이 있어야 하는 것처럼 보이지만

장점은 최적화 기회 측면에서 단점이 있습니다. 이는 하나의 번역 단위 프레임워크 내에서만 가능합니다(LTO를 사용하지 않는 경우). 물론 헤더 파일에서 전체 std를 수행할 수 있지만 그렇지 않습니다(컴파일 시간 때문에?). Sharp with module은 이와 관련하여 더욱 발전되었습니다. 그러나 C++20에서는 이것이 모듈의 출현으로 곧 수정될 것입니다. 거기에 std를 전송할 계획도 있습니다(모듈이 먼저 테스트된 다음 제출될 것입니다). 그러나 VS는 이미 모듈에서 std를 만든 것 같습니다. 시도해 볼 수 있습니다(위 링크를 남겼습니다).

그러나 나는 여전히 주장합니다. 주기 후에 선언하는 것이 좋습니다(기본 유형이 아닌 경우).

 
Alexey Navoykov :

관심을 끌기 위해 C#에서도 테스트하기로 결정했습니다. 결과는 속도 측면에서 실제로 서로 다르지 않을 뿐만 아니라 C ++보다 훨씬 빠르게 작동합니다.

결과:

합계: 894782460, 시간: 69ms

합계: 894782460, 시간: 56ms

다음은 C++에서 해당하는 내용입니다.

합계: 894782460, 시간: 2947ms

합계: 894782460, 시간: 684ms

VS 2019에서 테스트 . 모든 최적화가 활성화되었습니다.

용광로에서 C++)

ps C#의 결과는 테스트에서 테스트로 눈에 띄게 점프하지만 평균적으로 두 옵션의 속도가 동일한 것으로 나타났습니다.

힌트: 샤프에서 문자열은 기본 유형이고 플러스에서는 플러스로 작성된 클래스입니다. Sharp의 변형에서 문자열 할당은 플러스 단위로 한 번 발생합니다(10e6번). 결과적으로 전문가는 더 빠르지만 코드를 작성할 때 사상가를 포함해야 하며 보잉에서 인도인처럼 꼽추를 조각하지 않아야 합니다.
 
SeriousRacoon :
힌트: 샤프에서 문자열은 기본 유형이고 플러스에서는 플러스로 작성된 클래스입니다. Sharp의 변형에서 문자열 할당은 플러스 단위로 한 번 발생합니다(10e6번). 결과적으로 전문가는 더 빠르지만 코드를 작성할 때 사상가를 포함해야 하며 보잉에서 인도인처럼 꼽추를 조각하지 않아야 합니다.
아니요, 완전히 다른 문제입니다. 방금 문자열이 클래스라는 것을 잊었고 개체 자체가 아니라 할당된 참조가 있습니다. 따라서 이 형식에서는 비교가 올바르지 않습니다.
 

그건 그렇고, 최적화에 대해. 컴파일러가 여기에서 무언가를 최적화하기를 원하십니까?

mutex mtx;

void thread_0() {
        while (true) {
                do_task_0();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_1();
                }
                do_task_2();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_3();
                }
                do_task_4();
        {
}
void thread_1() {
        while (true) {
                do_task_5();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_6();
                }
                do_task_7();
                {
                        lock_guard < mutex > lck{mtx};
                        do_task_8();
                }
                do_task_9();
        {
}
 
Alexey Navoykov :
아니요, 완전히 다른 문제입니다. 방금 문자열이 클래스라는 것을 잊었고 개체 자체가 아니라 할당된 참조가 있습니다. 따라서 이 형식에서는 비교가 올바르지 않습니다.
참조(포인터)는 어디에 할당됩니까? 플러스 문자열 클래스에서? 무슨 말을 하는지, 버퍼 할당과 복사가 있습니다.
 
SeriousRacoon :
참조(포인터)는 어디에 할당됩니까? 플러스 문자열 클래스에서? 무슨 말을 하는지, 버퍼 할당과 복사가 있습니다.

그는 날카로운 것에 대해 이야기하고 있습니다.