我正在解决一个问题,它涉及非常快速地排序10个数字(int32).我的应用程序需要尽可能快地对10个数字进行数百万次排序.我正在对数十亿个元素的数据集进行采样,每次我需要从中挑选10个数字(简化)并对它们进行排序(并从排序的10个元素列表中得出结论).
目前我正在使用插入排序,但我想我可以实现一个非常快速的自定义排序算法,针对10个数字的特定问题,这将超过插入排序.
有没有人知道如何处理这个问题?
诚然,我不明白.假设您的内存中包含长度为1个字节的内存字.为什么不能在未对齐地址的单个内存访问中访问一个4字节长的变量(即不能被4整除),因为对齐地址就是这种情况?
我正在创建一张桌子,这让我很奇怪.
如果我存储,比如拥有制造商的汽车(fx宝马,奥迪等),如果我将制造商存储为int或varchar,它会对查询速度产生任何影响.
也是
SELECT * FROM table WHERE make = 5 AND ...;
Run Code Online (Sandbox Code Playgroud)
更快/更慢
SELECT * FROM table WHERE make = 'audi' AND ...;
Run Code Online (Sandbox Code Playgroud)
或者速度会或多或少相同?
问题
很长一段时间我的印象是,使用嵌套std::vector<std::vector...>来模拟N维数组通常很糟糕,因为内存不保证是连续的,并且可能有缓存未命中.我认为最好使用平面矢量并从多个维度映射到1D,反之亦然.所以,我决定测试它(最后列出的代码).这非常简单,我定时读取/写入嵌套的3D矢量与我自己的1D矢量3D包装器.我用两者编译了代码,g++并且打开clang++了-O3优化.对于每次运行,我都改变了尺寸,因此我可以很好地了解这种行为.令我惊讶的是,这些是我在我的机器MacBook Pro(Retina,13英寸,2012年末),2.5GHz i5,8GB RAM,OS X 10.10.5上获得的结果:
g ++ 5.2
dimensions nested flat
X Y Z (ms) (ms)
100 100 100 -> 16 24
150 150 150 -> 58 98
200 200 200 -> 136 308
250 250 250 -> 264 746
300 300 300 -> 440 1537
Run Code Online (Sandbox Code Playgroud)
clang ++(LLVM 7.0.0)
dimensions nested flat
X Y Z (ms) (ms)
100 100 100 -> 16 18
150 150 150 -> 53 61
200 …Run Code Online (Sandbox Code Playgroud) 想象一下,我们在内存中分散了1000个相同类型的对象(它们是在不同时间创建的,其他对象是在其间创建的).
我们有一个数组,它包含对1000个对象中每个对象的引用.
如果我们按顺序遍历数组,那么将预取到CPU的高速缓存中的是什么?只有数组所包含的引用或这些引用才会被解引用,并且对象也会被加载到缓存中?
Java(JVM)是否实现了某种软件预取?如果没有,是否有提供软件预取的库?
我对内存系统遵循的策略有一个基本的问题.
考虑具有私有L1和L2缓存的核心.在L2缓存之后,我们有一条总线,在该总线上运行一致性流量.现在,如果从L2高速缓存中清除地址(X)的高速缓存行,是否有必要从L1高速缓存中逐出该地址?
驱逐的原因可能是它有助于维持一致性协议的不变性[如果l2中的一行显示无效,则此核心不包含此地址].
根据包括Wikipedia在内的一些资料,实现二叉树的两种最常用的方法是:
第二个显然在内存使用和引用的位置方面优越。但是,如果您希望以某种可能使树不平衡的方式从树中插入和移除,可能会导致问题。这是因为此设计的内存使用量是树深度的指数函数。
假设您要支持此类插入和删除。如何实现树,以便树遍历可以充分利用CPU缓存。
我正在考虑为节点创建对象池并将它们分配到数组中。这样,节点将彼此靠近->因此具有良好的参考位置。
但是,如果节点的大小与缓存行的大小相同,这有意义吗?
如果您的L1行大小为64字节,并且访问的第一个成员std::vector<std::uint8_t>(64),则可能会在L1缓存中包含向量的全部内容。这意味着您可以非常快速地访问任何元素。但是,如果元素的大小与缓存行的大小相同怎么办?由于L1,L2和L3高速缓存的高速缓存行可能不会有很大差异,因此,似乎没有办法在此提供参考位置的帮助。我错了吗?还有什么可以做的?
这似乎是一个奇怪的问题..
假设缓存行的大小为64字节.此外,假设L1,L2,L3具有相同的高速缓存行大小(此后称它是英特尔的Core i7的情况下).
内存上有两个对象A,B其(物理)地址相隔N个字节.为简单起见,我们假设A它位于缓存边界上,也就是说,它的地址是64的整数倍.
1)如果N<64,当ACPU取出时,B也会读入缓存.因此,如果B需要,并且高速缓存行尚未被驱逐,CPU将B在很短的时间内获取.大家都很开心.
2)如果N>> 64(即远大于64),当A被CPU取出时,B不会被读入缓存行A.所以我们说"CPU不喜欢追逐指针",这是避免堆分配基于节点的数据结构的原因之一std::list.
我的问题是,如果N> 64但是仍然很小,比如N= 70,换句话说,A并且B不适合一个缓存行但不是太远,当A由CPU加载时,取出B需要相同数量的时钟当N大于64 时,它会花费多少个周期?
改写 - 当A加载时,让t表示提取的时间B,t(N = 70)远小于或几乎等于t(N = 9999999)?
我问这个问题是因为我怀疑t(N = …
如果我有这门课:
class MyClass{
short a;
short b;
short c;
};
Run Code Online (Sandbox Code Playgroud)
我有这段代码对上面的内容执行计算:
std::vector<MyClass> vec;
//
for(auto x : vec){
sum = vec.a * (3 + vec.b) / vec.c;
}
Run Code Online (Sandbox Code Playgroud)
我知道CPU只从L1缓存加载它需要的数据,但是当L1缓存从L2缓存检索数据时,它会加载整个“缓存行”(其中可能包括它不需要的几个字节的数据) 。
L2 缓存从 L3 缓存加载多少数据,L3 缓存从主内存加载多少数据?它是根据页面定义的吗?如果是的话,根据不同的 L2/L3 缓存大小,这个答案会有何不同?
caching ×4
performance ×3
c++ ×2
cpu-cache ×2
algorithm ×1
alignment ×1
binary-tree ×1
cpu ×1
java ×1
jvm ×1
jvm-hotspot ×1
memory ×1
memory-size ×1
optimization ×1
postgresql ×1
prefetch ×1
select ×1
sorting ×1
sql ×1
vector ×1