작은 정수 배열 지우기 : memset 대 for 루프
정수 / 부동 배열을 0으로 만드는 두 가지 방법이 있습니다.
memset(array, 0, sizeof(int)*arraysize);
또는:
for (int i=0; i <arraysize; ++i)
array[i]=0;
분명히 memset은 큰 arraysize
. 그러나 memset의 오버 헤드가 실제로 for 루프의 오버 헤드보다 큰 지점은 어디입니까? 예를 들어, 크기가 5 인 배열의 경우 어떤 것이 가장 좋을까요? 첫 번째, 두 번째 또는 아마도 언 롤링 된 버전 :
array[0] = 0;
array[1] = 0;
array[2] = 0;
array[3] = 0;
array[4] = 0;
모든 가능성에서 memset ()은 컴파일러에 의해 인라인됩니다 (대부분의 컴파일러는이를 '내장'으로 취급합니다. 즉, 가장 낮은 최적화에서 또는 명시 적으로 비활성화하지 않는 한 기본적으로 인라인됨을 의미합니다).
예를 들어, 다음은 GCC 4.3의 일부 릴리스 노트입니다 .
블록 이동 (
memcpy
) 및 블록 세트 (memset
) 의 코드 생성 이 다시 작성되었습니다. GCC는 이제 복사되는 블록의 크기와 최적화되는 CPU를 기반으로 최상의 알고리즘 (루프, 언 롤링 된 루프, rep 접두사가있는 명령어 또는 라이브러리 호출)을 선택할 수 있습니다. 새로운 옵션-minline-stringops-dynamically
이 추가되었습니다. 이 옵션을 사용하면 알 수없는 크기의 문자열 작업이 확장되어 작은 블록이 인라인 코드로 복사되는 반면 큰 블록의 경우 라이브러리 호출이 사용됩니다. 따라서-minline-all-stringops
라이브러리 구현이 캐시 계층 힌트를 사용할 수있을 때보 다 코드가 더 빠릅니다 . 특정 알고리즘을 선택하는 휴리스틱은를 통해 덮어 쓸 수 있습니다-mstringop-strategy
. 새로memset
0과 다른 값 도 인라인됩니다.
컴파일러가 당신이 준 대체 예제와 비슷한 일을 할 수는 있지만 가능성은 적을 것입니다.
그리고 grep
부팅의 의도가 무엇인지 한눈에 쉽게 알 수 있습니다 (루프도 특히 어렵지 않습니다).
Michael이 이미 언급했듯이 gcc와 나는 대부분의 다른 컴파일러가 이미 이것을 매우 잘 최적화한다고 생각합니다. 예를 들어 gcc는 이것을
char arr[5];
memset(arr, 0, sizeof arr);
으로
movl $0x0, <arr+0x0>
movb $0x0, <arr+0x4>
그것보다 더 나아지지는 않습니다 ...
측정하지 않고 질문에 답할 수있는 방법은 없습니다. 컴파일러, CPU 및 런타임 라이브러리 구현에 전적으로 의존합니다.
memset ()은 버퍼 오버 플로우, 매개 변수 반전의 경향이 있고 '바이트 단위'만 지우는 불행한 능력이 있기 때문에 "코드 냄새"가 될 수 있습니다. 그러나 극단적 인 경우를 제외하고는 '가장 빠르다'는 것이 안전한 내기입니다.
일부 문제를 피하기 위해 매크로를 사용하여 래핑하는 경향이 있습니다.
#define CLEAR(s) memset(&(s), 0, sizeof(s))
이것은 크기 계산을 회피하고 길이 및 값 매개 변수를 바꾸는 문제를 제거합니다.
간단히 말해서, "내부에서"memset ()을 사용하십시오. 의도 한대로 작성하고 컴파일러가 최적화에 대해 걱정하게하십시오. 대부분은 엄청나게 잘합니다.
이 코드 자체를 고려하면 이미 말한 바 있습니다. 그러나 내가 아무것도 모르는 프로그램에서 그것을 고려하면 다른 일을 할 수 있습니다. 예를 들어이 코드가 배열을 지우기 위해 매번 실행되는 경우 전역 변수에 할당 된 0 요소의 새 배열을 지속적으로 할당하는 스레드를 실행할 수 있습니다. 단순히 가리 킵니다.
이것은 세 번째 옵션입니다. 물론 두 개 이상의 코어가있는 프로세서에서 코드를 실행할 계획이라면 이는 의미가 있습니다. 또한 이점을 확인하려면 코드를 두 번 이상 실행해야합니다. 한 번만 실행하는 경우 0으로 채워진 배열을 선언 한 다음 필요할 때 가리킬 수 있습니다.
이것이 누군가를 도울 수 있기를 바랍니다.
참조 URL : https://stackoverflow.com/questions/1134103/clearing-a-small-integer-array-memset-vs-for-loop
'developer tip' 카테고리의 다른 글
arm64와 aarch64의 차이점 (0) | 2020.12.31 |
---|---|
Apache 대신 Glassfish를 사용하는 이유는 무엇입니까? (0) | 2020.12.31 |
shared_ptr 통과 비용 (0) | 2020.12.31 |
Android의 VideoView에서 비디오 재생 (0) | 2020.12.31 |
Xcode를 업데이트하는 방법은 무엇입니까? (0) | 2020.12.31 |