- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有 double x
, 和 double y
.我需要把它变成 int boxnum
,它被定义为(floored)索引,其中 (x,y)
落在 WIDTH x HEIGHT
网格大小为 BOX_SIZE
.坐标超过WIDTH
被包裹起来; HEIGHT
同上.
我目前正在使用:
( (((int)(x))/BOX_SIZE)%WIDTH+ WIDTH*((((int)(y))/BOX_SIZE)%HEIGHT) )
这个语句目前占用了大约 20% 的执行时间,如果我让它对负坐标完全安全,情况会变得更糟(大约 40-50%):
( (( ((int)(x)) /BOX_SIZE)%WIDTH+WIDTH)%WIDTH
+WIDTH*(( (((int)(y)) /BOX_SIZE)%HEIGHT+HEIGHT)%HEIGHT) )
我实际上正在考虑将应用程序完全转换为定点,只是为了避免这种情况,这样我就可以屏蔽掉我想要的部分,而不是进行这种可怕的转换。
是否有更好的方法来进行这种 double->int 转换?确保0<x<WIDTH*BOX_SIZE
值得吗?和 0<y<HEIGHT*BOX_SIZE
所以我可以放弃两个余数操作? (这样做非常困难,不值得用于基准测试,除非它可能是一个重大改进)
编辑:在评论中进行适当的惩罚后,更多细节:
x
和 y
是一组(多达 10^6 个)粒子的坐标。我正在使用一种算法,该算法要求我在每个时间步对一个盒子内的所有粒子进行一些简单的求和。因此,我遍历粒子,计算粒子在哪个盒子中,然后将其用作添加到该盒子的数组索引。粒子通常移动得足够远,以至于它们过去的位置并不能指示它们 future 的位置。它们也是无序的,这意味着我无法对此做出任何假设。
WIDTH
, HEIGHT
, 和 BOX_SIZE
技术上是免费的,只要WIDTH
和 HEIGHT
是 BOX_SIZE
的偶数倍.实际上它们都是指定的编译时间,并且是带BOX_SIZE=1
的整数。 .我已经从 WIDTH=HEIGHT=4
运行了一切至 WIDTH=HEIGHT=512
,虽然我通常使用 2 的平方次方(因为为什么不呢?),WIDTH=37;HEIGHT=193
应该可以正常工作。
这种计算不可避免地会在每个粒子每个时间步执行一次;在当前的实现中,它执行了两次。我尝试缓存该值以避免重新计算,但最终基准测试的表现更差,所以我又重新计算了两次。
使用 10 particles/box * 100 WIDTH * 100 HEIGHT* 10000 steps = 1 billion particle*timesteps
进行基本测试在阴凉处跑了一分钟。
这些坐标按照它们的“常规数字”(1-1000) 的顺序排列,所以我离 double
上的任何类型的界限都不远。 .
最佳答案
您的代码的问题在于,(int)
转换导致浮点单元的舍入模式从 IEEE754 默认舍入到最接近更改为 C 标准向零舍入或标准中定义的“截断”。
请参阅 gcc 文档 here有关 IEEE754 舍入模式的更多信息。
在现代深度流水线处理器上,当更改舍入模式时必须刷新整个流水线,导致速度大幅下降,因为流水线在每次 (int)
转换时都会被清空。当您在循环中执行此操作时,您遇到的减速是典型的。
Erik de Castro Lopo(libsndfile 和 secret rabbit code 的作者)就这个问题发表了一篇非常有趣的文章。在他的音频转换例程中,浮点舍入性能至关重要,他使用 POSIX lrintf()
调用以及一些用于非 POSIX 平台的 x86 程序集为该问题提供了一组有趣的解决方案。
文章可以查here.
简短的回答是使用 C99/POSIX lrintf()
函数,或者使用一些内联汇编来执行整数截断而不改变浮点舍入模式。
关于c - 更有效的 flooring double 方法来获取数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16470305/
我有一个功能是转换 ADO Recordset 进入html: class function RecordsetToHtml(const rs: _Recordset): WideString; 该函
经过几天的研究和讨论,我想出了这种方法来收集访客的熵(你可以看到我的研究历史here) 当用户访问时,我运行此代码: $entropy=sha1(microtime().$pepper.$_SERVE
给定一个无序列表 List ,我需要查找是否存在 String与提供的字符串匹配。 所以,我循环 for (String k : keys) { if (Utils.keysM
我已经搜索过这个问题,但没有找到我正在寻找的答案。 基本上,我想将类构造函数包装在 try/except 子句中,以便它忽略构造函数内特定类型的错误(但无论如何都会记录并打印它们)。我发现做到这一点的
我有一组三个数字,我想将一组数字与另一组数字进行比较。即,第一组中的每个数字小于另一组中的至少一个数字。需要注意的是,第一组中的下一个数字必须小于第二组中的不同数字(即,{6,1,6} 对 {8,8,
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
首先介绍一下背景: 我正在开发一个带有 EJB 模块和应用程序客户端模块的企业应用程序 (ear)。我还使用 hibernate JPA 来实现持久性,并使用 swingx 来实现 GUI。这些是唯一
我正在尝试在我的上网本上运行 Eclipse 以便能够为 Android 进行开发。 您可能已经猜到了,Eclipse 非常慢,并且不容易有效地开发。 我正在使用 Linux Ubuntu 并且我还有
for row, instrument in enumerate(instruments): for col, value in enumerate(instrument):
return not a and not b ^ 我如何以更好的格式表达它 最佳答案 DeMorgan's Law , 也许? return not (a or b) 我认为在这一点上已经足够简单了
我正在尝试让 Font Awesome 图标看起来更 slim https://jsfiddle.net/cliffeee/7L6ehw9r/1/ . 我尝试使用“-webkit-text-strok
假设我有一个名为 vals 的数据框,如下所示: id…………日期…………min_date…… .........最大日期 1…………2016/01/01…………2017/01/01…………2018/
是否有更 Pythonic 的方式来做到这一点?: if self.name2info[name]['prereqs'] is None: se
我有一个函数可以将一些文本打印到它接收到的 ostream&。如果 ostream 以终端为目标,我想让它适应终端宽度,否则默认为某个值。 我现在做的是: 从 ostream 中获取一个 ofstre
这个问题在这里已经有了答案: Should a retrieval method return 'null' or throw an exception when it can't produce
我有这个 bc = 'off' if c.page == 'blog': bc = 'on' print(bc) 有没有更 Pythonic(和/或更短)的方式在 Python 中编写? 最佳
输入:一个包含 50,000 行的 CSV;每行包含 910 列值 0/1。 输出:运行我的 CNN 的数据框。 我编写了一个逐行读取 CSV 的代码。对于每一行,我将数据分成两部分,称为神经元(90
据我所知,with block 会在您退出 block 后自动调用 close(),并且它通常用于确保不会忘记关闭一个文件。 好像没有技术上的区别 with open(file, 'r+') as f
我有一个使用 Entity Framework V6.1.1 的 MVC 5 网站。 Entity Framework DbContext 类和模型最初都在网站项目中。这个项目有 3 个 DbCont
我是编程新手,在尝试通过将 tableView 和关联 View 的创建移动到单独的类并将委托(delegate)和数据源从 VC 移动到单独的类来精简我的 ViewController 时遇到了一些
我是一名优秀的程序员,十分优秀!