programing

소정수 배열 클리어: memset vs. for loop

copysource 2022. 9. 1. 00:07
반응형

소정수 배열 클리어: memset vs. for loop

정수/플로트 배열을 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()은 컴파일러에 의해 inline이 될 것입니다(대부분의 컴파일러는 intrinsic으로 취급합니다.이는 기본적으로 가장 낮은 최적화 시 또는 명시적으로 비활성화되지 않는 한 inline임을 의미합니다).

를 들어, GCC 4.3의 릴리스 노트를 다음에 나타냅니다.

블록 이동 코드 생성(memcpy및 블록 세트(memset)이(가) 다시 작성되었습니다.GCC는 복사되는 블록의 크기와 최적화되는 CPU에 따라 최적의 알고리즘(루프, 언롤 루프, rep prefix를 사용한 명령 또는 라이브러리 호출)을 선택할 수 있게 되었습니다.새로운 옵션-minline-stringops-dynamically가 추가되었습니다.이 옵션에서 알 수 없는 크기의 문자열 연산이 확장되어 작은 블록은 인라인코드로 복사되지만 큰 블록의 경우 라이브러리 콜이 사용됩니다.그 결과, 보다 빠른 코드가-minline-all-stringops라이브러리 구현이 캐시 계층 힌트를 사용할 수 있는 경우.특정 알고리즘을 선택하는 휴리스틱은 다음을 통해 덮어쓸 수 있습니다.-mstringop-strategy·신규도memset0과 다른 값의 행이 표시됩니다.

컴파일러가 당신이 제시한 다른 예시로 비슷한 작업을 하는 것은 가능할지 모르지만, 그럴 가능성은 낮다고 생각합니다.

그리고...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))

이로 인해 사이즈의 계산이 불필요해져 길이 파라미터와 vlaue 파라미터를 교환하는 문제가 없어집니다.

즉, memset() "under the hood"를 사용합니다.컴파일러가 최적화에 대해 걱정하도록 의도한 내용을 기술합니다.대부분은 믿을 수 없을 정도로 잘합니다.

이 코드 자체를 고려하면 이미 모든 것이 알려졌습니다.하지만 만약 당신이 그 프로그램을 고려한다면, 나는 아무것도 모른다. 다른 방법이 있을 수 있다.예를 들어 이 코드가 어레이를 클리어하기 위해 일정 시간마다 실행되는 경우 글로벌 변수에 할당된 제로 요소의 새로운 배열을 항상 할당하는 스레드를 실행할 수 있습니다.이러한 배열을 클리어할 필요가 있는 코드는 단순히 어레이를 가리킵니다.

이것은 세 번째 옵션입니다.물론 최소 2개의 코어가 있는 프로세서에서 코드를 실행할 예정이라면 이 방법은 타당합니다.또한 코드를 여러 번 실행하여 이점을 확인해야 합니다.한 번만 실행할 경우 0으로 채워진 배열을 선언한 후 필요할 때 가리킬 수 있습니다.

이것이 누군가에게 도움이 되기를 바란다.

언급URL : https://stackoverflow.com/questions/1134103/clearing-a-small-integer-array-memset-vs-for-loop

반응형