我想在数组上写一个简单的扫描.我有一个std::vector<int> data
,我想找到元素小于9的所有数组索引,并将它们添加到结果向量.我可以用分支写这个:
for (int i = 0; i < data.size(); ++i)
if (data[i] < 9)
r.push_back(i);
Run Code Online (Sandbox Code Playgroud)
这给出了正确答案,但我想将其与无分支版本进行比较.
使用原始数组 - 并假设它data
是一个int数组,length
是它中元素的数量,并且r
是一个有足够空间的结果数组 - 我可以这样写:
int current_write_point = 0;
for (int i = 0; i < length; ++i){
r[current_write_point] = i;
current_write_point += (data[i] < 9);
}
Run Code Online (Sandbox Code Playgroud)
我如何使用向量获得类似的行为data
?
我试图了解 perf 记录的缓存未命中。我有一个最小的程序:
int main(void)
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我编译这个:
gcc -std=c99 -W -Wall -Werror -O3 -S -o test.S test.c
Run Code Online (Sandbox Code Playgroud)
我得到了一个预期的小程序:
.file "test.c"
.section .text.startup,"ax",@progbits
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.7.2-5) 4.7.2"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
只有两条指令, xorl
and ret
,程序的大小应该小于一个缓存行,所以我希望如果我运行perf -e "cache-misses:u" ./test
我应该只看到一个缓存未命中。但是,我看到的是 2 到 ~400。同样,perf -e "cache-misses" ./test
结果是 ~700 到 ~2500。
这只是一个估计计数的情况,还是缓存未命中发生的方式使对它们的推理近似?例如,如果我生成并读取内存中的一个整数数组,我是否可以推理预取(顺序访问应该允许完美预取)或者还有其他东西在起作用吗?
我有以下联盟:
union problem {
int i;
int *v;
};
Run Code Online (Sandbox Code Playgroud)
在我的系统上int
是4个字节,int*
而是8.我有一个数组,其中有10个这样的结构.在某段代码中,我碰巧知道数组的所有成员都使用int
了union.我需要将这些int复制到一个int数组中.现在,如果源数组是一个int数组,我可以memcpy
用来快速复制数据.
是否可以保证int存储在联合的低或高内存中?我希望能够在不进行迭代的情况下复制数据,因此我在考虑使用SIMD和shuffle进行循环.要做到这一点,我必须知道int实际上在union中的位置,我猜这是特定于实现的.