부호 없는 정수와 부호 있는 정수의 성능
서명된 정수보다 부호 없는 정수를 사용하여 성능 이득/손실이 있습니까?
그렇다면 이것도 짧은 시간이고 긴 시간인가요?
2의 거듭제곱으로 나누면unsigned int
1교대 명령으로 최적화할 수 있기 때문입니다.와 함께signed int
디비전은 0을 향해 반올림하지만 올바른 반올림으로 전환하기 때문에 일반적으로 더 많은 기계 명령이 필요합니다.예:
int foo(int x, unsigned y)
{
x /= 8;
y /= 8;
return x + y;
}
여기 관련 정보가 있습니다.x
부품(서명된 분할):
movl 8(%ebp), %eax
leal 7(%eax), %edx
testl %eax, %eax
cmovs %edx, %eax
sarl $3, %eax
그리고 여기 관련 정보가 있습니다.y
부품(지정된 부문):
movl 12(%ebp), %edx
shrl $3, %edx
C++(및 C)에서는 부호 있는 정수 오버플로는 정의되어 있지 않지만 부호 없는 정수 오버플로는 랩하도록 정의되어 있습니다.예를 들어 gcc에서는 -fwrapv 플래그를 사용하여 서명된 오버플로를 정의할 수 있습니다(랩).
정의되지 않은 서명된 정수 오버플로는 컴파일러가 오버플로우가 발생하지 않는다고 가정할 수 있으며, 이는 최적화 기회를 가져올 수 있습니다.자세한 내용은 이 블로그 게시물을 참조하십시오.
unsigned
같은 성능 또는 더 나은 성능으로 이어집니다.signed
. 몇 가지 예:
- 2의 거듭제곱인 상수로 나눗셈(FredOverflow의 답변도 참조)
- 상수값으로 나눕니다(예를 들어, 내 컴파일러는 서명되지 않은 2개의 asm 명령과 서명된 6개의 명령을 사용하여 13으로 나눕니다).
- 짝수인지 확인(MS Visual Studio 컴파일러가 왜 4개의 명령으로 구현하는지 모르겠습니다)
signed
gcc는 1개의 명령으로 실행할 수 있습니다.unsigned
케이스)
short
보통 같은 퍼포먼스 또는 퍼포먼스 저하로 이어집니다.int
(비활성화)sizeof(short) < sizeof(int)
퍼포먼스 저하는 산술연산의 결과(통상은 이 값)를 할당하면 발생합니다.int
,절대.short
)를 유형변수로 지정합니다.short
프로세서 레지스터에 저장되어 있습니다(또한 타입입니다).int
) 에서의 모든 변환short
로.int
시간이 걸리고 귀찮다.
주의: 일부 DSP에는 고속 곱셈 명령이 있습니다.signed short
라고 입력합니다.이 경우는short
보다 빠르다int
.
의 차이에 대해서int
그리고.long
(64비트 아키텍처에 대해서는 잘 모릅니다)라고 밖에 생각할 수 없습니다.물론, 만약int
그리고.long
(32비트 플랫폼에서는) 같은 사이즈를 가지며 퍼포먼스도 동일합니다.
여러 사람이 지적한 매우 중요한 추가 사항:
대부분의 애플리케이션에서 정말 중요한 것은 메모리 용량과 사용된 대역폭입니다.필요한 최소 정수를 사용해야 합니다.short
, 어쩌면 심지어signed/unsigned char
)를 참조해 주세요.
이렇게 하면 성능이 향상되지만, 2 또는 4의 배율이 아니라 비선형적이며, 어느 정도 예측할 수 없습니다. 즉, 캐시 크기 및 애플리케이션의 계산과 메모리 전송 간의 관계에 따라 다릅니다.
부호 있는 정수와 부호 없는 정수의 성능 차이는 실제로 수락 답변보다 더 일반적입니다.부호 없는 정수를 임의의 정수로 나누는 것은 정수가 2의 거듭제곱인지 여부에 관계없이 부호 있는 정수를 상수로 나누는 것보다 빠르게 할 수 있다.http://ridiculousfish.com/blog/posts/labor-of-division-episode-iii.html 를 참조해 주세요.
투고 말미에, 다음의 섹션이 포함됩니다.
당연한 질문은 동일한 최적화가 서명된 분할을 개선할 수 있는지 여부입니다. 안타깝게도 다음 두 가지 이유로 개선되지 않은 것으로 보입니다.
배당의 증가는 크기가 증가해야 한다. 즉, n > 0이면 증가, n < 0이면 감소한다.이로 인해 추가 비용이 발생합니다.
비협조적 제수에 대한 벌금은 서명된 분할의 약 절반에 불과해 개선의 여지가 더 적다.
따라서, 반올림 알고리즘은 부호 있는 분할로 동작할 수 있지만, 표준 반올림 알고리즘보다 성능이 떨어지는 것으로 보입니다.
종래에는int
는 타깃 하드웨어 플랫폼의 네이티브 정수 형식입니다.다른 정수형은 퍼포먼스 패널티가 발생할 수 있습니다.
편집:
최신 시스템에서는 다음과 같은 점이 약간 다릅니다.
int
64비트 시스템에서는 호환성을 위해 실제로는 32비트일 수 있습니다.이것은 Windows 시스템에서 발생하는 것이라고 생각합니다.현대의 컴파일러는 암묵적으로
int
경우에 따라서는 짧은 유형의 계산을 수행할 때 사용합니다.
부호 없는 타입에서는 2의 거듭제곱으로 나누는 것이 빠를 뿐만 아니라 부호 없는 타입에서는 다른 값으로 나누는 것이 빠릅니다.Agner Fog의 Instruction 테이블을 보면 서명되지 않은 디비전이 서명된 버전과 비슷하거나 더 나은 성능을 가지고 있음을 알 수 있습니다.
예를 들어 AMD K7의 경우
설명 | 오퍼랜드 | 동작 | 레이텐시 | 상호 스루풋 |
---|---|---|---|---|
DIV | r8/m8 | 32 | 24 | 23 |
DIV | r16/m16 | 47 | 24 | 23 |
DIV | r32/m32 | 79 | 40 | 40 |
IDIV | r8 | 41 | 17 | 17 |
IDIV | r16 | 56 | 25 | 25 |
IDIV | r32 | 88 | 41 | 41 |
IDIV | m8 | 42 | 17 | 17 |
IDIV | m16 | 57 | 25 | 25 |
IDIV | m32 | 89 | 41 | 41 |
같은 것이 인텔 Pentium에도 적용됩니다.
설명 | 오퍼랜드 | 클럭 사이클 |
---|---|---|
DIV | r8/m8 | 17 |
DIV | r16/m16 | 25 |
DIV | r32/m32 | 41 |
IDIV | r8/m8 | 22 |
IDIV | r16/m16 | 30 |
IDIV | r32/m32 | 46 |
물론 그것들은 꽤 오래되었다.트랜지스터가 더 많은 새로운 아키텍처는 격차를 좁힐 수 있지만, 일반적으로 서명된 분할을 수행하려면 더 많은 마이크로 연산, 더 많은 논리, 더 많은 레이텐시가 필요합니다.
이것은, 특정의 프로세서에 의해서 크게 좌우됩니다.
대부분의 프로세서에는 부호 있는 산술과 부호 없는 산술에 대한 명령이 있기 때문에 부호 없는 정수를 사용하는 것의 차이는 컴파일러가 사용하는 정수를 사용하는 것에 있습니다.
어느 쪽이든 속도가 빠를 경우 프로세서에 따라 다르며, 그 차이는 매우 작을 수 있습니다.
IIRC, x86의 서명/서명되지 않은 경우에는 아무런 차이가 없습니다.반면, RAM으로 이동하거나 RAM에서 이동해야 하는 데이터 양이 더 길기 때문에 쇼트/롱은 다른 문제입니다(쇼트에서 롱으로 연장하는 것과 같은 주조 작업도 포함될 수 있습니다).
서명된 정수와 서명되지 않은 정수는 항상 단일 클럭 명령으로 동작하며 읽기/쓰기 성능은 동일하지만 Andrei Alexandrescu 박사에 따르면 서명되지 않은 정수는 서명되지 않은 정수가 선호됩니다.그 이유는 부호 비트를 낭비하지 않기 때문에 같은 비트수에 2배의 숫자를 넣을 수 있고 ROM 의 저하로 인해 음수를 체크하는 명령의 수가 적어지기 때문입니다.초고성능 스크립트 구현을 특징으로 하는 가부키 VM의 경험상 메모리로 작업할 때 실제로 서명된 번호가 필요한 경우는 거의 없습니다.나는 서명된 숫자와 서명되지 않은 숫자에 대한 포인터 계산을 몇 년 동안 해왔지만, 부호 비트가 필요하지 않을 때 서명된 숫자에 대한 이점을 찾지 못했다.
부호 있는 2의 보완 정수를 사용하여 2의 곱셈과 나눗셈을 수행할 수 있으므로 부호 있는 2를 사용하는 것이 좋습니다.최적화 기술에 대해서는 Andrei의 YouTube 비디오를 참조하십시오.세계에서 가장 빠른 정수-문자열 변환 알고리즘에 대한 좋은 정보도 제 기사에서 찾을 수 있습니다.
In short, don't bother before the fact. But do bother after.
If you want to have performance you have to use performance optimizations of a compiler which may work against common sense. One thing to remember is that different compilers can compile code differently and they themselves have different sorts of optimizations. If we're talking about a g++
compiler and talking about maxing out it's optimization level by using -Ofast
, or at least an -O3
flag, in my experience it can compile long
type into code with even better performance than any unsigned
type, or even just int
.
This is from my own experience and I recommend you to first write your full program and care about such things only after that, when you have your actual code on your hands and you can compile it with optimizations to try and pick the types that actually perform best. This is also a good very general suggestion about code optimization for performance, write quickly first, try compiling with optimizations, tweak things to see what works best. And you should also try using different compilers to compile your program and choosing the one that outputs the most performant machine code.
An optimized multi-threaded linear algebra calculation program can easily have a >10x performance difference finely optimized vs unoptimized. So this does matter.
Optimizer output contradicts logic in plenty of cases. For example, I had a case when a difference between a[x]+=b
and a[x]=b
changed program execution time almost 2x. And no, a[x]=b
wasn't the faster one.
Here's for example NVidia stating that for programming their GPUs:
Note: As was already the recommended best practice, signed arithmetic should be preferred over unsigned arithmetic wherever possible for best throughput on SMM. The C language standard places more restrictions on overflow behavior for unsigned math, limiting compiler optimization opportunities.
This will depend on exact implementation. In most cases there will be no difference however. If you really care you have to try all the variants you consider and measure performance.
부호 없는 정수는 양쪽을 비트스트림으로 저장 및 취급하는 것이 유리합니다.즉, 부호 없는 데이터일 뿐이므로 비트 시프트 연산을 통해 곱셈이 쉬워집니다(빠릅니다).
언급URL : https://stackoverflow.com/questions/4712315/performance-of-unsigned-vs-signed-integers
'programing' 카테고리의 다른 글
Nuxt.js 기반 사이트를 개선하여 Google PageSpeed 통찰력을 얻는 방법 (0) | 2022.06.10 |
---|---|
엑셀 파일 읽기 및 쓰기 방법 (0) | 2022.06.10 |
v-show가 소품 작업을 하지 않음 (0) | 2022.06.10 |
Vuetify.js 2 - babel-polyfill을 사용하면 데이터 테이블 바닥글이 올바르게 표시되지 않음 (0) | 2022.06.10 |
JUnit5에서 Mockito를 사용하는 방법 (0) | 2022.06.10 |