C:通过大量使用 sin() 来提高函数的性能

2023-12-20

我有一个 C 函数,可以根据经过的时间计算 4 个正弦值。使用 gprof,我发现这个函数使用了 100%(确切地说是 100.7%,哈哈)的 CPU 时间。

void
update_sines(void)
{
    clock_gettime(CLOCK_MONOTONIC, &spec);
    s = spec.tv_sec;
    ms = spec.tv_nsec * 0.0000001;
    etime = concatenate((long)s, ms);

    int k;
    for (k = 0; k < 799; ++k)
    {
        double A1 = 145 * sin((RAND1 * k + etime) * 0.00333) + RAND5;           // Amplitude
        double A2 = 100 * sin((RAND2 * k + etime) * 0.00333) + RAND4;           // Amplitude
        double A3 = 168 * sin((RAND3 * k + etime) * 0.00333) + RAND3;           // Amplitude
        double A4 = 136 * sin((RAND4 * k + etime) * 0.00333) + RAND2;           // Amplitude

        double B1 = 3 + RAND1 + (sin((RAND5 * k) * etime) * 0.00216);           // Period
        double B2 = 3 + RAND2 + (sin((RAND4 * k) * etime) * 0.002);         // Period
        double B3 = 3 + RAND3 + (sin((RAND3 * k) * etime) * 0.00245);           // Period
        double B4 = 3 + RAND4 + (sin((RAND2 * k) * etime) * 0.002);         // Period

        double x = k;                                   // Current x

        double C1 = 0.6 * etime;                            // X axis move
        double C2 = 0.9 * etime;                            // X axis move
        double C3 = 1.2 * etime;                            // X axis move
        double C4 = 0.8 * etime + 200;                          // X axis move

        double D1 = RAND1 + sin(RAND1 * x * 0.00166) * 4;               // Y axis move
        double D2 = RAND2 + sin(RAND2 * x * 0.002) * 4;                 // Y axis move
        double D3 = RAND3 + cos(RAND3 * x * 0.0025) * 4;                // Y axis move
        double D4 = RAND4 + sin(RAND4 * x * 0.002) * 4;                 // Y axis move

        sine1[k] = A1 * sin((B1 * x + C1) * 0.0025) + D1;
        sine2[k] = A2 * sin((B2 * x + C2) * 0.00333) + D2 + 100;
        sine3[k] = A3 * cos((B3 * x + C3) * 0.002) + D3 + 50;
        sine4[k] = A4 * sin((B4 * x + C4) * 0.00333) + D4 + 100;
    }

}

这是 gprof 的输出:

Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  Ts/call  Ts/call  name    
100.07      0.04     0.04  

我目前使用此方法获得的帧速率约为 30-31 fps。现在我认为有一种更有效的方法可以做到这一点。

正如您所注意到的,我已经将所有除法更改为乘法,但这对性能影响很小。

我怎样才能提高这个数学重函数的性能?


除了其他答案中给出的所有其他建议之外,这是一个纯粹的算法优化。

在大多数情况下,您正在计算以下形式的内容sin(k * a + b), where a and b是常数,并且k是一个循环变量。如果你还要计算cos(k * a + b),那么你可以使用 2D旋转矩阵 http://en.wikipedia.org/wiki/Rotation_matrix形成递推关系(矩阵形式):

|cos(k*a + b)| = |cos(a)  -sin(a)| * |cos((k-1)*a + b)|
|sin(k*a + b)|   |sin(a)   cos(a)|   |sin((k-1)*a + b)|

换句话说,您可以根据上一次迭代的值来计算当前迭代的值。因此,您只需要进行完整的三角计算k == 0,但其余的可以通过这个递归计算(一旦你计算了cos(a) and sin(a),它们是常数)。因此,您消除了 75% 的三角函数调用(尚不清楚是否可以为最后一组三角函数调用使用相同的技巧)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C:通过大量使用 sin() 来提高函数的性能 的相关文章

随机推荐

  • 使用 CALayers 的圆角 UIView - 只有一些角 - 如何?

    在我的应用程序中 有四个按钮 名称如下 左上方 左下方 右上 右下 按钮上方有一个图像视图 或 UIView 现在 假设用户点击左上角按钮 上面的图像 视图应在该特定角处进行圆角处理 我在将圆角应用于 UIView 时遇到一些困难 现在我正
  • 发布/订阅同一服务器集合的多个子集

    编辑 这个问题 一些答案和一些评论包含很多错误信息 看Meteor 收藏 出版物和订阅如何运作 https stackoverflow com a 21853298 1269037为了准确理解发布和订阅同一服务器集合的多个子集 如何将服务器
  • 如何将 ThreeJS Collada 加载器与 TypeScript / Angular CLI 结合使用?

    我已经安装了三个 node modules three 我已将 Collada 加载程序安装在 node modules three collada loader 这些类型似乎已经包括 Collada 加载程序的类型 node module
  • 获取由另一个函数调用的所有函数的列表

    在JavaScript中 是否可以获得由另一个函数调用的所有函数的列表 我想创建一个函数依赖关系树 以分析脚本中的函数如何相互关联 以及哪些函数需要哪些其他函数 例如 getAllCalledFunctions funcA this sho
  • 如何使带有自制库的 Xcode 项目可移植?

    我已经使用 Brew 在我的 mac 上安装了 FreeType 我的 mac 上的代码工作正常 但是当我尝试在其他 mac 上运行该项目时 我收到下面提到的链接错误 dyld Library not loaded usr local op
  • 在管道中的分类器之后使用指标

    我继续调查管道 我的目标是仅通过管道执行机器学习的每一步 将我的管道与其他用例相适应将会更加灵活和容易 所以我做什么 第 1 步 填充 NaN 值 第 2 步 将分类值转换为数字 第三步 分类器 第四步 网格搜索 第5步 添加指标 失败 这
  • 以编程方式将可拖动项移动到某个位置

    假设有一个只能在一个轴上拖动的可拖动对象 有没有办法以编程方式移动它 要么开始 要么增量 当然我可以去改变它的CSSleft属性 但这不会触发 jQuery 提供的拖动事件 我本来期待找到一个dragBy x y 可拖动的方法 这是示例 h
  • 有人可以解释一下这个 C++ 联合示例吗?

    我在 cppreference com 上找到了这段代码 这是我见过的最奇怪的 C 我有几个问题 union S std string str std vector
  • 选择合适的缓存机制

    我的设置 4 个网络服务器 静态内容服务器 NFS挂载 2 个数据库服务器 2 个 施展魔法 的服务器 另外 8 台指定为多用途机器 我正在为三种缓存机制编写一个包装器 以便可以以某种标准化的方式使用它们 文件系统 Memcached 和
  • 来自 STDIN 的 Python JSON 输入出现问题

    input json load sys stdin print input id 当我输入 id 1 并按 Enter 时 我的程序不会继续 我只是卡在输入中 在有效的 json 传递到我的 stdlin 后 如何使程序继续 当你读入时sy
  • 在 PL/SQL 中打印字母金字塔

    我有一个练习编写一个程序 打印出如下所示的字母金字塔 A ABA ABCBA ABCDCBA ABCDFDCBA 该任务还建议使用 INSTR LPAD UPPER 我想要一个包含字母表中所有字母的金字塔 然而 我发现先用数字来表示会更容易
  • hackerrank新年混沌代码优化

    我正在尝试优化我的解决方案Hackerranks 的 新年混乱 问题 https www hackerrank com challenges new year chaos problem 问题的要点是这样的 有一个由 n 个人组成的队列 标
  • 检查集合是否非空的正确“clojure 方式”是什么

    我想编写一个函数 如果给定的集合不为空 则返回布尔值 true 否则返回 false 我可以做 defn boolean seq coll or defn not empty coll 由于我是 clojure 的新手 我最初倾向于选择 2
  • Cloudant couchapp 突然失败并出现 CSP 沙箱错误

    我有一个 couchapp 多年来一直在 Cloudant 免费计划上托管 几天前 它开始失败 html css 和 img 文件加载 但没有加载任何 js 浏览器控制台错误是 Blocked script execution in htt
  • 使用 VBA 根据另一张表中列出的单词删除行 - 性能缓慢

    我有一张包含大量数据的工作表 sheet1 该数据有多个列 其中一列称为 nameColumn nameColumn 每行包含一个单词 在表 2 中 我列出了 600 个单词 我需要删除sheet1中包含nameColumn中与sheet2
  • Android 小部件按钮停止工作

    我有一个带有小部件的 Android 应用程序 其中有按钮 这段代码有效 小部件上的按钮停止工作当发生某些事情时 例如更改手机语言 我使用共享偏好设置 所以如果用户重新安装应用程序 无需卸载 按钮又可以工作了并且设置仍保持原来的设置 我注意
  • 如何为xamarin android实现推送通知

    我尝试按照教程进行操作 将通知推送到 Xamarin Android https learn microsoft com en us azure notification hubs xamarin notification hubs pus
  • 当我确实需要从两个类继承时如何处理CS1721?

    在我的 C 代码中 我想要一个CustomIdentity继承自的类System MarshalByRefObject and System Security Principal GenericIndentity类 然而 当我尝试编写这样的
  • 如何使用 AngularFire 对对象应用部分更新

    The save Angularfire 0 8 中的内容让我感到困惑 这是一个最小的示例 我的controllers js 文件中的一个片段 controller LandingPageController scope firebase
  • C:通过大量使用 sin() 来提高函数的性能

    我有一个 C 函数 可以根据经过的时间计算 4 个正弦值 使用 gprof 我发现这个函数使用了 100 确切地说是 100 7 哈哈 的 CPU 时间 void update sines void clock gettime CLOCK