我的问题是基于另一个SO问题:为什么_mm_stream_ps会产生L1/LL缓存未命中?
在阅读并被它吸引之后,我试图复制结果并亲眼看看哪个更快:天真循环,展开的幼稚循环,_mm_stream_ps(展开),_mm_store_ps(展开)以及最后但并非最不重要memset_pattern4.(最后一个采用4字节模式,例如浮点数,并在目标数组上填充它,这应该与所有其他函数相同,但它可能是OS X独有的).
我已确保将数组的开头对齐在高速缓存行(64字节,我检查过),并在参数中传递数组以及上一个问题中提到的任何其他性能调整.
有人想在gamedev上知道同样的事情:http://www.gamedev.net/topic/532112-fast-memset/
该线程的结论反映了我自己:当目标数组小于最大(L3)缓存时,_mm_store_ps速度快于_mm_stream_ps.目标数组越大,_mm_stream_ps速度越快.我不完全确定为什么__mm_store_ps在第一种情况下速度更快,因为我从不在缓存中使用这些值,但我知道为什么_mm_stream_ps在后一种情况下胜出.它适用于这种情况:将字节写入内存,您不需要立即(或永远).
以下是使用gcc 4.8编译的目标数组比L3缓存大256倍(在我的情况下为1.5GB)的一些结果:
gcc-4.8 stream.c -o stream -std=c11 -O3 -g3 -ftree-vectorize -march=native -minline-all-stringops && ./stream
bench L3-MASS, array 1610612736 bytes (402653184 floats, 0 remainder, 0x104803040 pointer)
warm up round...
6% ( 20.81148 ms) : MEMSET CHEAT
8% ( 28.49419 ms) : MEMSET PATTER
100% ( 371.40385 ms) : NAIVE NORMAL
54% ( 202.01147 ms) …Run Code Online (Sandbox Code Playgroud) 我发现使用可写CTE模拟PostgreSQL中的upsert是一个非常优雅的解决方案,直到我们在Postgres中获得实际的upsert/merge.(见:https://stackoverflow.com/a/8702291/558819)
但是,有一个问题:如何插入默认值?NULL当然,使用将无助于NULL显式插入NULL,与MySQL不同.一个例子:
WITH new_values (id, playlist, item, group_name, duration, sort, legacy) AS (
VALUES (651, 21, 30012, 'a', 30, 1, FALSE)
, (NULL::int, 21, 1, 'b', 34, 2, NULL::boolean)
, (668, 21, 30012, 'c', 30, 3, FALSE)
, (7428, 21, 23068, 'd', 0, 4, FALSE)
), upsert AS (
UPDATE playlist_items m
SET (playlist, item, group_name, duration, sort, legacy)
= (nv.playlist, nv.item, nv.group_name, nv.duration, nv.sort, nv.legacy)
FROM new_values nv
WHERE …Run Code Online (Sandbox Code Playgroud) 我正在与Akka 2制作一个小型缓存演员并让演员不要阻止我在期货中执行所有计算.然而问题是这个actor还需要与不在actor中的代码进行交互,因此我需要使用"ask"模式来获取值.
我的问题是,在使用ask模式时,如何避免将计算的Future包含在另一个Future中?
例如
val f = myCache ? GetOrCalc("myKey", myCalculation) // this will be a Future[Future[...]] but I would like a Future[...]
// meanwhile, inside the actor
def receive = {
case GetOrCalc(key, calculation) =>
if (keyNotExists) sender ! Future { calculation() } // calculation() is long-running
else sender ! cacheMap(key)
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我可以使用Future.pipeTo函数,但我担心这不会被视为非演员代码的"响应"
在研究OSX 10.9.4的strlen实现时,我注意到它总是比较一个16字节的块并向前跳过到接下来的16个字节,直到它遇到'\0''.相关部分:
3de0: 48 83 c7 10 add $0x10,%rdi
3de4: 66 0f ef c0 pxor %xmm0,%xmm0
3de8: 66 0f 74 07 pcmpeqb (%rdi),%xmm0
3dec: 66 0f d7 f0 pmovmskb %xmm0,%esi
3df0: 85 f6 test %esi,%esi
3df2: 74 ec je 3de0 <__platform_strlen+0x40>
Run Code Online (Sandbox Code Playgroud)
0x10 十六进制是16个字节.
当我看到它时,我想知道:这个记忆也可以不被分配.如果我已经分配了一个20字节的C字符串并将其传递给strlen它,它将读取36字节的内存.为什么允许这样做?我开始寻找并发现访问数组越界有多危险?
例如,这证实了它绝对不是一件好事,未分配的内存可能未被映射.然而,必须有一些东西使这项工作.我的一些假设:
究竟是什么原因?
编辑:刚刚找到为什么我获得了未分配内存的读写权限?,这似乎表明我的第一个猜测是正确的.
编辑2:愚蠢的是,我已经忘记了尽管Apple似乎已经删除了大多数asm实现的源代码(OSX的x86-64汇编libc例程在哪里?),但是它留下了strlen:http://www.opensource .apple.com /源极/ libc的/ libc的-997.90.3/x86_64的/串/ strlen.s
在评论中我们发现:
// returns the length of the string s (i.e. the …Run Code Online (Sandbox Code Playgroud) 我正在用C++/Qt编写一个项目,它能够连接到QtSQL支持的任何类型的SQL数据库(http://doc.qt.nokia.com/latest/qtsql.html).这包括本地服务器和外部服务器.
但是,当有问题的数据库是外部的时,查询的速度开始成为一个问题(慢UI,...).原因是:存储在数据库中的每个对象都是延迟加载的,因此每次需要属性时都会发出查询.平均大约20个这些对象将显示在屏幕上,每个对象显示约5个属性.这意味着对于我显示的每个屏幕,大约有100个查询被执行.查询在数据库服务器本身上执行得非常快,但是通过网络运行的实际查询的开销很大(整个屏幕以秒为单位).
我一直在考虑解决问题的几种方法,最重要的方法似乎是(据我所知):
例如,通过保持数据库的本地同步副本运行,可以使查询更快.但是,我在客户端计算机上运行的可能性并不大,例如与服务器上的数据库类型完全相同.因此,本地副本例如是SQLite数据库.这也意味着我无法使用特定于数据库供应商的解决方案.我有什么选择?什么在这种情况下对人们有效?
我主要担心的是:
什么是最小化查询成本的好方法?良好的意义某种组合:可维护,易于实现,而不是特定的aplication.如果它选择任何2,那么就这样吧.我想听听人们谈论他们的经历以及他们为解决这些问题所做的工作.
正如你所看到的,我已经想到了一些问题和处理它的方法,但是我不知道什么才是合理的方法.由于很可能涉及很多工作并且对程序中的许多层进行了密集的更改(希望尽可能少),我想在此之前向所有专家询问,然后再就此事做出最终决定.我也可以忽略一个非常简单的解决方案,在这种情况下,指向它的指针将非常感激!
假设所有相关的服务器端调优都已完成(例如:MySQL缓存,最佳索引,......)
*注意:我已经检查过类似问题但没有完全满足我的问题的用户的问题:对我的用例的复制方案的建议?和本地数据库缓存的最佳实践?例如)
如果需要任何其他信息来提供答案,请告诉我,我会及时更新我的问题.对于任何拼写/语法错误道歉,英语不是我的母语.
我的代码看起来像的一个小例子(当然简化):
QList<MyObject> myObjects = database->getObjects(20, 40); // fetch and construct object 20 to 40 from the db
// ...some time later
// screen filling time!
foreach (const MyObject& …Run Code Online (Sandbox Code Playgroud) 在尝试并见证了我可以将Lua和LuaJIT集成到我的游戏引擎中的难以置信的轻松之后,我确信这是我想要使用的脚本语言.我想将它用于我的AI,单位描述,地图触发器等等.(尽可能真的).这个问题不仅适用于gamedev,我可以想象创建一个可编写脚本的编辑器或窗口管理器,它可以加载外部脚本(例如:使用python和包控制的sublime文本)
但现在我有一个难题:我非常感谢LuaJIT FFI提供的易用性,以便绑定到我的引擎,但我不想提供FFI的免费统治来映射作者.通过FFI进行lua-to-c调用的令人难以置信的速度(当JITted时)也是我真正想要的.
理想情况下,我会编写自己的包装器Lua文件,用FFI绑定到我的引擎,并导出一个很好的模块供地图作者和模拟器使用.我的替代方案是编写一个vanilla lua模块,这可能但更麻烦和更慢.
我在编译luajit时无法禁用FFI,因为显然我想自己使用它,但我没有看到如何在每个脚本或每个模块的基础上限制FFI.显然,FFI需要在我加载模块的lua_State中处于活动状态(之后我无法开始加载用户修改的脚本).那我该怎么办?它甚至可能吗?
编辑:在我看来,理想的工作流程是:
注意:我知道这仍然不是一个完美的(甚至是好的沙盒),正如Mike Pall已经在他的一些邮件中指出的那样,但我仍然不想让地图作者访问FFI.
首先,一些指向 OSX 的 Libc 代码的有用链接:
在那里,可以看到 Libc 825.40.1 (OSX 10.8.5) 仍然具有像 memcpy 这样的函数的公共 asm 实现。尤其是在x86_64/string/bcopy_sse42.s. 但是,从 997.1.1 (OSX 10.9) 版本开始,它们中的大部分似乎都消失了。不过还是留了几个x86_64/string。可以在这里看到:http : //www.opensource.apple.com/source/Libc/Libc-997.90.3/x86_64/string/。
其他人的来源是否已关闭?查看 OSX 10.8 和 10.9 之间的差异并不表明它们可能已移至源代码树内部的位置。
在调试 OSX 10.9 上运行的二进制文件时,很难错过对_platform_memmove. 事实上,如果我们查看bcopy.c的源代码,我们会看到:
#include <platform/string.h>
void bcopy(const void *src, void *dst, size_t n) {
_platform_memmove(dst, src, n);
}
Run Code Online (Sandbox Code Playgroud)
所以也许这会产生一些有用的东西。然而由于某种原因,我找不到(_)platform_memmove,要么是缺乏grepping能力,要么是宏观技巧。有人可以帮我找到吗?
编辑:我尝试寻找platform/string.h,但就像那个邮件列表海报一样,我无法在源代码树中找到它。
编辑: …