小编Akt*_*tau的帖子

击败或满足OS X memset(和memset_pattern4)

我的问题是基于另一个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)

c optimization performance assembly simd

12
推荐指数
1
解决办法
1497
查看次数

使用PostgreSQL 9.3在CTE UPSERT中生成DEFAULT值

我发现使用可写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)

sql postgresql merge upsert sql-insert

10
推荐指数
1
解决办法
1787
查看次数

Akka在回复非Actor代码时避免包装未来

我正在与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函数,但我担心这不会被视为非演员代码的"响应"

scala future akka

6
推荐指数
1
解决办法
3341
查看次数

矢量化的strlen逃脱阅读未分配的记忆

在研究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字节的内存.为什么允许这样做?我开始寻找并发现访问数组越界有多危险?

例如,这证实了它绝对不是一件好事,未分配的内存可能未被映射.然而,必须有一些东西使这项工作.我的一些假设:

  • OSX不仅保证其分配是16字节对齐的,而且还保证分配的"量子"是16字节的块.换句话说,分配5个字节实际上将分配16个字节.分配20个字节实际上将分配32个字节.
  • 当你编写asm时读取数组的结尾本身并没有坏处,因为它不是未定义的行为,只要它在界限内(在页面内?).

究竟是什么原因?

编辑:刚刚找到为什么我获得了未分配内存的读写权限?,这似乎表明我的第一个猜测是正确的.

编辑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 macos assembly memory-management libc

6
推荐指数
2
解决办法
461
查看次数

SQL查询在C++应用程序中最小化/缓存

我正在用C++/Qt编写一个项目,它能够连接到QtSQL支持的任何类型的SQL数据库(http://doc.qt.nokia.com/latest/qtsql.html).这包括本地服务器和外部服务器.

但是,当有问题的数据库是外部的时,查询的速度开始成为一个问题(慢UI,...).原因是:存储在数据库中的每个对象都是延迟加载的,因此每次需要属性时都会发出查询.平均大约20个这些对象将显示在屏幕上,每个对象显示约5个属性.这意味着对于我显示的每个屏幕,大约有100个查询被执行.查询在数据库服务器本身上执行得非常快,但是通过网络运行的实际查询的开销很大(整个屏幕以秒为单位).

我一直在考虑解决问题的几种方法,最重要的方法似乎是(据我所知):

  1. 减少查询次数
  2. 更快地进行查询

解决(1)

  • 我可以找到某种方法来延迟实际获取属性(启动事务),然后当程序员写入endTransaction()时,数据库会尝试一次性获取所有内容(使用SQL UNION或循环...) .这可能需要相当多的修改懒惰对象工作,但这样的,如果人们评论说,这是一个不错的解决方案,我认为这可能是优雅的制定.如果这个解决方案加速了一切,那么甚至可能不需要精心设计的缓存方案,从而节省了很多麻烦
  • 我可以尝试通过在一个查询中为所有请求的对象提取属性数据来预加载属性数据,从而有效地使它们变得非惰性.当然,在这种情况下,我将不得不担心过时的数据.如何在不向外部数据库发送一个查询的情况下检测过时数据?(注意:发送查询以检查每个属性检查的陈旧数据将提供最佳情况下的0x性能增加,并且当实际发现数据过时时,最差等级2x性能下降)

应对(2)

例如,通过保持数据库的本地同步副本运行,可以使查询更快.但是,我在客户端计算机上运行的可能性并不大,例如与服务器上的数据库类型完全相同.因此,本地副本例如是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)

c++ sql qt lazy-evaluation database-caching

5
推荐指数
1
解决办法
1759
查看次数

使用LuaJIT编写脚本并有选择地沙盒化FFI

在尝试并见证了我可以将Lua和LuaJIT集成到我的游戏引擎中的难以置信的轻松之后,我确信这是我想要使用的脚本语言.我想将它用于我的AI,单位描述,地图触发器等等.(尽可能真的).这个问题不仅适用于gamedev,我可以想象创建一个可编写脚本的编辑器或窗口管理器,它可以加载外部脚本(例如:使用python和包控制的sublime文本)

但现在我有一个难题:我非常感谢LuaJIT FFI提供的易用性,以便绑定到我的引擎,但我不想提供FFI的免费统治来映射作者.通过FFI进行lua-to-c调用的令人难以置信的速度(当JITted时)也是我真正想要的.

理想情况下,我会编写自己的包装器Lua文件,用FFI绑定到我的引擎,并导出一个很好的模块供地图作者和模拟器使用.我的替代方案是编写一个vanilla lua模块,这可能但更麻烦和更慢.

我在编译luajit时无法禁用FFI,因为显然我想自己使用它,但我没有看到如何在每个脚本或每个模块的基础上限制FFI.显然,FFI需要在我加载模块的lua_State中处于活动状态(之后我无法开始加载用户修改的脚本).那我该怎么办?它甚至可能吗?

编辑:在我看来,理想的工作流程是:

  1. 打开卢安州
  2. 加载所有模块(luaL_openlibs()),FFI也被预加载
  3. 加载我的.lua模块,使用FFI(这是引擎绑定,它们是可信文件,因此可以使用FFI)
  4. 禁用选择本机模块和函数:os,ffi,...(这是缺少的步骤)
  5. 执行用户提供的脚本(这些是不可信的,我不希望他们访问FFI)
  6. 可选:寻找一种方法来重新加载lua模块以实现快速编辑循环,这将涉及重新启用FFI和其他模块.(不知道怎么做)

注意:我知道这仍然不是一个完美的(甚至是好的沙盒),正如Mike Pall已经在他的一些邮件中指出的那样,但我仍然不想让地图作者访问FFI.

security lua sandbox ffi luajit

5
推荐指数
1
解决办法
2097
查看次数

OSX 的 x86-64 汇编 libc 例程去哪儿了?

首先,一些指向 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,但就像那个邮件列表海报一样,我无法在源代码树中找到它。

编辑: …

c macos libc

5
推荐指数
0
解决办法
640
查看次数