그렇지 않은 가장 관용적 인 방법, 또는 라인의 가장 적은 수에 기록 할 수있는 방법,하지만 요청으로이 질문은 오히려 오래된 있지만, 몇 가지 벤치 마크를 필요로 가장 빠른 방법입니다. 그리고 실제 테스트없이 그 질문에 대답하는 것은 어리석은 일입니다. 그래서 저는 memset 대 std :: fill 대 AnT의 답변의 ZERO 대 AVX 내장 함수를 사용하여 만든 솔루션의 네 가지 솔루션을 비교했습니다.
이 솔루션은 일반적이지 않으며 32 비트 또는 64 비트의 데이터에서만 작동합니다. 이 코드가 잘못된 작업을 수행하는 경우 의견을 보내주십시오.
#include<immintrin.h>
#define intrin_ZERO(a,n){\
size_t x = 0;\
const size_t inc = 32 / sizeof(*(a));/*size of 256 bit register over size of variable*/\
for (;x < n-inc;x+=inc)\
_mm256_storeu_ps((float *)((a)+x),_mm256_setzero_ps());\
if(4 == sizeof(*(a))){\
switch(n-x){\
case 3:\
(a)[x] = 0;x++;\
case 2:\
_mm_storeu_ps((float *)((a)+x),_mm_setzero_ps());break;\
case 1:\
(a)[x] = 0;\
break;\
case 0:\
break;\
};\
}\
else if(8 == sizeof(*(a))){\
switch(n-x){\
case 7:\
(a)[x] = 0;x++;\
case 6:\
(a)[x] = 0;x++;\
case 5:\
(a)[x] = 0;x++;\
case 4:\
_mm_storeu_ps((float *)((a)+x),_mm_setzero_ps());break;\
case 3:\
(a)[x] = 0;x++;\
case 2:\
((long long *)(a))[x] = 0;break;\
case 1:\
(a)[x] = 0;\
break;\
case 0:\
break;\
};\
}\
}
저수준 최적화 전문가가 아니기 때문에 이것이 가장 빠른 방법이라고 주장하지 않겠습니다. 오히려 그것은 memset보다 빠른 올바른 아키텍처 종속 구현의 예입니다.
이제 결과에. 정적으로 및 동적으로 할당 된 크기 100 int 및 long long 배열의 성능을 계산했지만, 정적 배열에서 데드 코드 제거를 수행 한 msvc를 제외하고는 결과가 매우 비슷했기 때문에 동적 배열 성능 만 보여 드리겠습니다. time.h의 낮은 정밀도 시계 기능을 사용하여 시간 표시는 1 백만 회 반복에 대한 ms입니다.
clang 3.8 (clang-cl 프런트 엔드 사용, 최적화 플래그 = / OX / arch : AVX / Oi / Ot)
int:
memset: 99
fill: 97
ZERO: 98
intrin_ZERO: 90
long long:
memset: 285
fill: 286
ZERO: 285
intrin_ZERO: 188
gcc 5.1.0 (최적화 플래그 : -O3 -march = native -mtune = native -mavx) :
int:
memset: 268
fill: 268
ZERO: 268
intrin_ZERO: 91
long long:
memset: 402
fill: 399
ZERO: 400
intrin_ZERO: 185
msvc 2015 (최적화 플래그 : / OX / arch : AVX / Oi / Ot) :
int
memset: 196
fill: 613
ZERO: 221
intrin_ZERO: 95
long long:
memset: 273
fill: 559
ZERO: 376
intrin_ZERO: 188
여기에는 llvm killing gcc, MSVC의 일반적인 반점 최적화 (정적 배열에서 인상적인 데드 코드 제거를 수행 한 다음 채우기 성능이 끔찍함)가 있습니다. 내 구현이 훨씬 빠르지 만 비트 지우기가 다른 설정 작업보다 훨씬 적은 오버 헤드를 가지고 있음을 인식하기 때문일 수 있습니다.
Clang의 구현은 훨씬 더 빠르기 때문에 더 많이 볼 가치가 있습니다. 일부 추가 테스트에서는 memset이 실제로 0에 특화되어 있음을 보여줍니다 .400 바이트 배열의 경우 0이 아닌 memset은 훨씬 느리고 (~ 220ms) gcc와 비슷합니다. 그러나 800 바이트 배열을 사용하는 0이 아닌 memsetting은 속도 차이가 없습니다. 이것이 아마도이 경우 memset이 내 구현보다 성능이 떨어지는 이유 일 것입니다. 전문화는 작은 배열에만 해당되며 컷오프는 800 바이트 정도입니다. 또한 gcc 'fill'및 'ZERO'는 memset (생성 된 코드보기)에 최적화되지 않으며 gcc는 단순히 동일한 성능 특성을 가진 코드를 생성합니다.
결론 : memset은 실제로이 작업에 최적화되어 있지 않으며 사람들이 그렇게 생각할 것입니다 (그렇지 않으면 gcc와 msvc 및 llvm의 memset의 성능이 동일합니다). 성능이 중요하다면 memset은 특히 이러한 어색한 중간 크기의 배열에 대한 최종 솔루션이되어서는 안됩니다. 이는 비트 지우기에 특화되지 않았고 컴파일러가 자체적으로 수행 할 수있는 것보다 더 잘 최적화되지 않았기 때문입니다.
new
되는 C ++ ...