소정수 배열 클리어: 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
·신규도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))
이로 인해 사이즈의 계산이 불필요해져 길이 파라미터와 vlaue 파라미터를 교환하는 문제가 없어집니다.
즉, memset() "under the hood"를 사용합니다.컴파일러가 최적화에 대해 걱정하도록 의도한 내용을 기술합니다.대부분은 믿을 수 없을 정도로 잘합니다.
이 코드 자체를 고려하면 이미 모든 것이 알려졌습니다.하지만 만약 당신이 그 프로그램을 고려한다면, 나는 아무것도 모른다. 다른 방법이 있을 수 있다.예를 들어 이 코드가 어레이를 클리어하기 위해 일정 시간마다 실행되는 경우 글로벌 변수에 할당된 제로 요소의 새로운 배열을 항상 할당하는 스레드를 실행할 수 있습니다.이러한 배열을 클리어할 필요가 있는 코드는 단순히 어레이를 가리킵니다.
이것은 세 번째 옵션입니다.물론 최소 2개의 코어가 있는 프로세서에서 코드를 실행할 예정이라면 이 방법은 타당합니다.또한 코드를 여러 번 실행하여 이점을 확인해야 합니다.한 번만 실행할 경우 0으로 채워진 배열을 선언한 후 필요할 때 가리킬 수 있습니다.
이것이 누군가에게 도움이 되기를 바란다.
언급URL : https://stackoverflow.com/questions/1134103/clearing-a-small-integer-array-memset-vs-for-loop
'programing' 카테고리의 다른 글
C# 비동기/대기 Java 등가물? (0) | 2022.09.01 |
---|---|
vue js 1.x 대신 Vue js 2.x 지시문을 사용하여 투고를 제목별로 필터링하는 방법 (0) | 2022.09.01 |
URL을 변경하지 않고 vue 라우터 경로 변경 (0) | 2022.09.01 |
에러노를 설정할까요? (0) | 2022.09.01 |
C/C++에서 바이트의 비트 순서를 되돌리는 가장 간단한 방법은 무엇입니까? (0) | 2022.08.31 |