清除小整数数组:用于循环memset的对比(clearing a small integer arr

2019-06-26 01:26发布

有两种方法来零出的整数/ float数组:

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;

Answer 1:

在所有的可能性,memset的()将你的编译器内联(大多数编译器把它当作一个“内在”,这基本上意味着它内联,可能除了在最低优化或除非明确禁用)。

例如,这里有一些从GCC 4.3发布说明 :

代码生成块移动(的memcpy )和块集( memset )被重写。 现在GCC可以挑选基于所述块的大小被复制和CPU进行优化的最佳算法(循环,展开的循环,与代表前缀或库调用指令)。 一个新的选项-minline-stringops-dynamically增加了。 随着未知大小的这个选项字符串操作的扩展,使得小的块由行代码复制,而对于大块用于库调用。 这导致比更快的代码-minline-all-stringops当库的实现能够使用缓存层次结构的提示。 选择特定算法启发式可以通过覆盖-mstringop-strategy 。 新近还memset从0被内联不同的值。

这可能是可能的编译器做你给替代的例子类似的东西,但我敢打赌那是不太可能。

而且它的grep -able,更显而易见,一目了然什么意图是开机(不环路是特别困难神交其一)。



Answer 2:

正如迈克尔已经指出,gcc和我猜大多数其他编译器优化这已经非常好。 例如GCC原来这

char arr[5];
memset(arr, 0, sizeof arr);

movl  $0x0, <arr+0x0>
movb  $0x0, <arr+0x4>

它没有得到任何比这更好的?



Answer 3:

有没有回答这个问题没有测量方式。 这将完全取决于编译器,CPU和运行时库实现。

memset的()可以是“代码味道”的位,因为它可以容易出现缓冲区溢出,参数逆转和具有仅清除“逐字节”不幸能力。 但是这是一个安全的赌注,这将是在所有的,但极端情况下“最快”。

我倾向于使用宏来包装是为了避免一些问题:

#define CLEAR(s) memset(&(s), 0, sizeof(s))

此回避了大小计算并除去交换的长度和vlaue参数的问题。

总之,使用memset的()“下的发动机罩”。 写你打算什么,并让有关的优化编译器担心。 大多数是在它令人难以置信的好。



Answer 4:

考虑到这个代码本身evrything已经被告知。 但是,如果你在它的计划,该计划的我不知道什么考虑,别的东西可以做到的。 例如,如果这个代码将每一段时间执行清除数组,你可以运行一个线程,不断地分配分配给全局变量零个元素的新数组,你的代码,当需要阵列被清除,仅指向。

这是第三个选项。 当然,如果您打算与至少两个核心的处理器上运行的代码,这是有道理的。 还必须对代码进行运行不止一次看到它的好处。 对于只有一次性运行,你可以声明零填充数组,然后在需要时指向它。

希望这可以帮助别人



文章来源: clearing a small integer array: memset vs. for loop