我正在阅读Agner Fog的一本手册,作为64位操作系统(超过32位)的优势,他说:
函数参数在寄存器中而不是在堆栈中传输.这使函数调用更有效.
他是说堆栈不用于传递函数参数(64位操作系统)吗?
我遇到了一些关于JVM/JIT活动的参考文献,其中在编译字节码和解释字节码之间似乎有所区别.特定注释声明字节码被解释为前10000次运行并在此后编译.
"编译"和"解释"字节码有什么区别?
我不认为我完全理解currying,因为我无法看到它可以提供任何巨大的好处.也许有人可以用一个例子来启发我,说明它为何如此有用.它真的有好处和应用,还是仅仅是一个过度赞赏的概念?
我正在阅读关于volatile关键字的这个问题的答案:
这个人说:
防止重新排序的解决方案是使用内存屏障,该内存屏障向编译器和CPU指示在该点上不能重新排序内存访问.在易失性变量访问周围放置这些障碍可确保即使非易失性访问也不会在易失性访问中重新排序,从而允许我们编写线程安全的代码.
但是,内存障碍还可以确保在达到屏障时执行所有挂起的读/写操作,因此它有效地为我们提供了我们自己需要的所有内容,从而使得volatile不必要.我们可以完全删除volatile限定符.
这个"内存障碍"在C++中是如何实现的?
编辑:
有人可以给出一个简单的代码示例吗?
我最近看到以下帖子:
内存分配器的级别不低于malloc.(默认分配器通常直接或间接调用malloc)
分配器只允许您指定不同的分配策略.例如,您可以使用一个调用malloc一次的分配器来检索大型内存池,然后对于后续分配请求,它只返回该池的一小部分.
或者您可以将它用作钩子,以允许您在每次分配或释放内存时执行一些额外的任务.
至于你的第二个问题,malloc是你可以走的最低而不会失去便携性.malloc通常使用某些特定于操作系统的内存分配函数来实现,因此仍然是较低级别.但这与你的主要问题无关,因为C++分配器是一个更高级别的抽象.
来自:C++:内存分配器
我的问题是 - malloc如何在以下操作系统中实现?
什么是OS特定的函数被称为/ malloc()的实现?
一直在阅读Agner Fog的"Intel,AMD和VIA CPU的微架构"和第34页,他描述了"返回地址预测":
http://www.agner.org/optimize/microarchitecture.pdf
3.15返回(除P1外的所有处理器)
返回使用更好的方法.每次执行调用指令时,一个称为返回堆栈缓冲区的后进先出缓冲区会记住返回地址,并使用它来预测相应返回的去向.当从几个不同的位置调用相同的子例程时,此机制可确保正确预测返回指令.
鉴于返回地址仍然存储在堆栈中,我有点不清楚对此的需求是什么?
那么如果还有这种技术,在堆栈上存储返回地址的目的是什么?堆栈存储值是否仅在此预测技术不起作用时使用?
如果MESI协议阻止其他内核写入"独占"拥有的数据,那么x86 LOCK前缀的目的是什么?
我对LOCK提供的内容和MESI提供的内容感到有些困惑?
我理解MESI协议是关于确保内核都看到一致的内存状态,但据我所知,它还可以防止内核写入另一个内核已经写入的内存?
我想要一个类型的类成员std::thread::id,我也可以使它无效,然后检查它是否已设置.
"取消"此类型然后检查是否已设置的最佳方法是什么?
我正在将一个{string, MyStruct}对象插入到unordered_map中,稍后迭代unordered_map并选择擦除该元素.但是,在擦除元素之前,我有一个断言,它显示unordered_map为空.
这是我的插入内容:
my_umap.insert(std::make_pair(key.toString(), my_struct));
Run Code Online (Sandbox Code Playgroud)
该结构包含一个记录插入时间的成员.然后我定期检查地图并删除已经在unordered_map中的元素太长时间:
for(auto it = my_umap.begin(); it != my_umap.end(); ++it){
MyStruct& myStruct = it->second;
const bool deleteEntry = myStruct.ts.IsElapsed(std::chrono::seconds(5));
if(deleteEntry){
const string& key = it->first; // Cannot access memory for 'key'
assert(my_umap.size() >= 1); // This is failing
my_umap.erase(key);
}
}
Run Code Online (Sandbox Code Playgroud)
我在gdb中运行代码,断言失败.当我查询key它的值时说
无法访问内存
当我查询my_umap它的大小时,表示大小为零.
如果unordered_map的大小为零,for循环如何检测元素?没有其他线程访问此容器.我想unordered_map::insert()将对象复制到容器中,所以删除的原始对象应该无关紧要?
尝试编写一个方法,从std :: map中删除第一个(最低键控的)N个项目.试过这个:
void EraseNMapElements(const int numElementsToRemove){
const int originalSize = _map.size();
auto eraseIter = _map.begin();
std::advance(eraseIter, numElementsToRemove);
_map.erase(_map.begin(), eraseIter);
assert(_map.size() == (originalSize - numElementsToRemove)) || (0 == originalSize) || (0 == _map.size()));
}
Run Code Online (Sandbox Code Playgroud)
当元素数量超过请求删除的数量时,它可以工作.因此,如果我有五个元素,请求删除2,最后3个元素仍然存在.但是,如果我有一个元素并请求擦除2,我仍然剩下一个元素.
有没有一个简洁的方法来涵盖这个?我可以推送一个IF语句来检查numElementsToRemove大于map.size()但是必须有一个更好的解决方案吗?