使用size_t长度会影响编译器优化吗? [英] Using `size_t` for lengths impacts on compiler optimizations?
问题描述
在阅读这个问题时,我已经看到第一个评论说:
While reading this question, I've seen the first comment saying that:
size_t
并不是一个好主意,出于优化/ UB的原因,适当的类型是带符号的类型。
size_t
for length is not a great idea, the proper types are signed ones for optimization/UB reasons.
后面是另一条支持推理的评论。是真的吗
followed by another comment supporting the reasoning. Is it true?
这个问题很重要,因为如果我要写例如矩阵库,图像尺寸可以为 size_t
,只是为了避免检查它们是否为负数。但是,所有循环自然会使用 size_t
。这可能会对优化产生影响吗?
The question is important, because if I were to write e.g. a matrix library, the image dimensions could be size_t
, just to avoid checking if they are negative. But then all loops would naturally use size_t
. Could this impact on optimization?
推荐答案
size_t
大多数情况下是历史性事故-如果您的世界是16位,则最大对象大小从32767变为65535是一个大胜利;在当今的主流计算(以64位和32位为标准)中, size_t
是未签名的事实在很大程度上是令人讨厌的。
size_t
being unsigned is mostly an historical accident - if your world is 16 bit, going from 32767 to 65535 maximum object size is a big win; in current-day mainstream computing (where 64 and 32 bit are the norm) the fact that size_t
is unsigned is mostly a nuisance.
尽管无符号类型具有 less 不确定的行为(因为保证了环绕),但实际上它们大多具有位域语义,这通常是导致错误和其他不良后果的原因。特别是:
Although unsigned types have less undefined behavior (as wraparound is guaranteed), the fact that they have mostly "bitfield" semantics is often cause of bugs and other bad surprises; in particular:
-
无符号值之间的差异也是无符号的,并且具有通常的环绕语义,因此,如果您期望负数
difference between unsigned values is unsigned as well, with the usual wraparound semantics, so if you may expect a negative value you have to cast beforehand;
unsigned a = 10, b = 20;
// prints UINT_MAX-10, i.e. 4294967286 if unsigned is 32 bit
std::cout << a-b << "\n";
通常,在有符号/无符号比较和数学运算中,无符号获胜(因此,值会隐式地转换为无符号数),这又会导致意外;
more in general, in signed/unsigned comparisons and mathematical operations unsigned wins (so the signed value is casted to unsigned implicitly) which, again, leads to surprises;
unsigned a = 10;
int b = -2;
if(a < b) std::cout<<"a < b\n"; // prints "a < b"
无符号语义通常会出现问题,因为您希望索引在边界条件下变为负数
in common situations (e.g. iterating backwards) the unsigned semantics are often problematic, as you'd like the index to go negative for the boundary condition
// This works fine if T is signed, loops forever if T is unsigned
for(T idx = c.size() - 1; idx >= 0; idx--) {
// ...
}
此外,价值不能假设负值主要是稻草人; 您可以避免检查负值,但是由于隐式的有符号-无符号转换,它不会停止任何错误-您只是在怪罪。如果用户使用 size_t
将负值传递给您的库函数,则它将变成一个很大的数字,如果不是更糟的话,这也是错误的。
Also, the fact that an unsigned value cannot assume a negative value is mostly a strawman; you may avoid checking for negative values, but due to implicit signed-unsigned conversions it won't stop any error - you are just shifting the blame. If the user passes a negative value to your library function taking a size_t
, it will just become a very big number, which will be just as wrong if not worse.
int sum_arr(int *arr, unsigned len) {
int ret = 0;
for(unsigned i = 0; i < len; ++i) {
ret += arr[i];
}
return ret;
}
// compiles successfully and overflows the array; it len was signed,
// it would just return 0
sum_arr(some_array, -10);
对于优化部分:带符号类型在这方面的优势被高估了;是的,编译器可以假设永远不会发生溢出,因此在某些情况下它可以变得更聪明,但是通常这不会改变游戏规则(因为通常,环绕式语义在当今的体系结构中免费提供);最重要的是,像往常一样,如果您的探查器发现某个特定区域是瓶颈,则可以对其进行修改以使其运行更快(如果发现有利的话,可以在本地进行切换类型以使编译器生成更好的代码)。
For the optimization part: the advantages of signed types in this regard are overrated; yes, the compiler can assume that overflow will never happen, so it can be extra smart in some situations, but generally this won't be game-changing (as in general wraparound semantics comes "for free" on current day architectures); most importantly, as usual if your profiler finds that a particular zone is a bottleneck you can modify just it to make it go faster (including switching types locally to make the compiler generate better code, if you find it advantageous).
长话短说:我会选择签名而不是出于性能方面的考虑,而是因为在大多数常见情况下语义通常都不那么令人惊讶/敌对。
Long story short: I'd go for signed, not for performance reasons, but because the semantics is generally way less surprising/hostile in most common scenarios.
这篇关于使用size_t长度会影响编译器优化吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!