计算地图:提前计算价值

2024-03-26

我有一个计算地图 http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapMaker.html#makeComputingMap%28com.google.common.base.Function%29 (with 软价值观 http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapMaker.html#softValues%28%29)我用它来缓存昂贵的计算结果。

现在我遇到一种情况,我知道某个特定的键可能会在接下来的几秒钟内被查找。该密钥的计算成本也比大多数密钥更高。

我想在最小优先级线程中提前计算该值,以便最终请求该值时它已经被缓存,从而提高响应时间。

执行此操作的好方法是什么:

  1. 我可以控制执行计算的线程(特别是其优先级)。
  2. 避免重复工作,即计算只进行一次。如果计算任务已经在运行,则调用线程将等待该任务,而不是再次计算该值(FutureTask实现这个。对于 Guava 的计算地图,如果您只调用,这是正确的get但如果你把它与调用混合起来就不会了put.)
  3. “提前计算值”方法是异步且幂等的。如果计算已经在进行中,它应该立即返回,而无需等待该计算完成。
  4. 避免优先级倒置,例如如果高优先级线程请求该值,而中优先级线程正在执行不相关的操作,但计算任务在低优先级线程上排队,则高优先级线程不得处于饥饿状态。也许这可以通过暂时提高计算线程的优先级和/或在调用线程上运行计算来实现。

如何在所有涉及的线程之间进行协调?


附加信息
我的应用程序中的计算是图像过滤操作,这意味着它们都是 CPU 密集型的。这些操作包括仿射变换(范围从 50μs 到 1ms)和卷积(最多 10ms)。当然,不同线程优先级的有效性取决于操作系统抢占较大任务的能力。


您可以通过使用带有 ComputedMap 的 Future 来安排后台计算的“仅一次”执行。 Future 代表计算值的任务。未来由 ComputedMap 创建,同时传递给执行服务 http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/concurrent/ExecutorService.html用于后台执行。执行器可以配置自己的线程工厂 http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/concurrent/ThreadFactory.html创建低优先级线程的实现,例如

class LowPriorityThreadFactory implements ThreadFactory
{
   public Thread newThread(Runnable r) {
     Tread t = new Thread(r);
     t.setPriority(MIN_PRIORITY);
     return t;
   }
}

当需要该值时,高优先级线程会从映射中获取 future,并调用 get() 方法来检索结果,并在必要时等待计算结果。避免优先级反转 http://en.wikipedia.org/wiki/Priority_inversion您向任务添加一些额外的代码:

class HandlePriorityInversionTask extends FutureTask<ResultType>
{
   Integer priority;  // non null if set
   Integer originalPriority;
   Thread thread;
   public ResultType get() {
      if (!isDone()) 
         setPriority(Thread.currentThread().getPriority());
      return super.get();
   }
   public void run() {
      synchronized (this) {
         thread = Thread.currentThread();
         originalPriority = thread.getPriority();
         if (priority!=null) setPriority(priority);
      } 
      super.run();
   }
   protected synchronized void done() {
         if (originalPriority!=null) setPriority(originalPriority);
         thread = null;
   }

   void synchronized setPriority(int priority) {
       this.priority = Integer.valueOf(priority);
       if (thread!=null)
          thread.setPriority(priority);
   }
}

这负责将任务的优先级提高到调用线程的优先级get()如果任务尚未完成,则在任务完成时将优先级返回到原来的优先级,无论正常还是其他。 (为了简单起见,代码不会检查优先级是否确实更高,但这很容易添加。)

当高优先级任务调用 get() 时,future 可能还没有开始执行。您可能会想通过对执行程序服务使用的线程数设置较大的上限来避免这种情况,但这可能是一个坏主意,因为每个线程都可以以高优先级运行,从而消耗与之前一样多的 cpu操作系统将其关闭。池的大小可能应该与硬件线程的数量相同,例如池的大小为Runtime.availableProcessors()。如果任务尚未开始执行,而不是等待执行程序安排它(这是优先级反转的一种形式,因为高优先级线程正在等待低优先级线程完成),那么您可以选择从当前执行器并在仅运行高优先级线程的执行器上重新提交。

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

计算地图:提前计算价值 的相关文章

随机推荐

  • SQL Server 输出子句

    我有点困惑为什么我似乎无法使用下面的语句获得插入行的 新身份 SCOPE IDENTITY 只是返回 null declare WorkRequestQueueID int declare LastException nvarchar MA
  • 图像的色调效果 - iOS

    我只是想知道 是否有可能为图像制作色调效果 但不使用OpenGl ES 最好使用CALayer 我花了一些时间寻找答案 但仍然一无所获 tnx 您是在谈论对图像进行着色吗 一种快速方法 尽管可能不是最好的方法 为此您需要一个自定义解决方案
  • 从 GSL 库中获取 C gsl_fit_linear() 函数中线性回归的 p 值

    我正在尝试用 C 语言重现 R 中的一些代码 因此我尝试使用以下函数来拟合线性回归gsl fit linear 功能 在 R 中 我将使用 lm 函数 它使用以下代码返回拟合的 p 值 lmAvgs lt lm c 1 23 11 432
  • 使所有新目录具有777权限

    我有一个脚本 运行时会在其中创建一个目录 home test 然后在其中写入一些文件 当我运行这个脚本时 它工作得很好 但是 当我从 perl 脚本调用它时 ret home testscript py 它没有权限 因此无法创建该文件夹 或
  • 有没有可用于将 32 位/64 位可执行文件打包在一起的工具? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我真的很喜欢 SysInternals 实用程序 例如 Process Explorer 处理 64 位兼容性的方式 看起来 32 位可执
  • 在 Unix 上连接文本文件中的多个字段

    我该怎么做 File1看起来像这样 foo 1 scaf 3 bar 2 scaf 3 3 File2看起来像这样 foo 1 scaf 4 5 foo 1 boo 2 3 bar 2 scaf 1 00 我想做的是找到同时出现的线条Fil
  • 用 NaN 对矩阵进行排序,提取索引向量并将 NaN 移到末尾

    mockup 3 5 nan 2 4 nan 10 nan 如何在忽略 NaN 的情况下按降序对这个向量进行排序 所得向量的长度必须与mockup 即我需要将所有 NaN 放在末尾 结果应该是这样的 mockupSorted 10 5 4
  • 远程编辑谷歌文档

    我正在尝试向我的网站添加一项功能 如下所示 单击按钮会将文本附加到 Google 文档 显然 我需要在驱动器中创建一个 Apps 脚本 问题是如何从我的网站触发 Apps 脚本 您可以假设我是驱动器 文档的所有者 因此有权以我喜欢的任何方式
  • 在 Swift 中将字符串转换为 CGFloat

    我是 Swift 新手 如何将字符串转换为 CGFloat I tried var fl CGFloat str as CGFloat var fl CGFloat CGFloat str var fl CGFloat CGFloat st
  • 弃用离线访问权限后在 Facebook 上注销/切换用户

    通过脸书弃用离线访问权限 https developers facebook com roadmap offline access removal 5 月 1 日起 Web 应用程序可以轻松延长 OAuth 访问令牌的持续时间 60 天 但
  • JavaScript 中的 setTimeout 是否接受真实(浮点)延迟时间_

    我只是在看JavaScript 计时事件 http www w3schools com js js timing asp 那里说 第二个参数表示从现在开始多少毫秒后您要执行第一个参数 现在 我知道在 JavaScript 中 浮点数和整数都
  • 如果左侧包含 null 并且右侧包含值,则在 sql 中向左移动单元格

    在 Sql 中 我得到如下格式的结果 我总共有 6 列 第一行第 6 列包含该值 第二行第 5 和第 6 列包含该值 但如果前一列不包含该值 我需要检查每个单元格 这意味着我需要在第一列中包含该值 实际结果 a b c d e f 1 1
  • Nodejs、multer、aws S3

    如何应用 uuid 和日期 以便存储在数据库中的文件名和存储在 S3 存储桶中的文件名相同 在当前的实现中 即使帖子是在几小时后发布的 uuid 和日期也始终相同 有人可以帮忙吗 真的很感激 const s3 new AWS S3 acce
  • 基于定义的时间间隔(bin)的时间序列平均值

    这是我的数据集的示例 我想每 10 秒根据时间 即 ts 计算一次 bin 平均值 您能否提供一些提示以便我可以继续 就我而言 我想平均每 10 秒的时间 ts 和 Var 比如我会得到Var和ts从0到10秒的平均值 我将得到另一个 Va
  • 锐化图像以检测纸上印有“X”对象的边缘/线条

    我正在使用 python 和 opencv 我的目标是检测用树莓派相机拍摄的图像中的 X 形碎片 该项目是我们预先打印井字游戏板 并且每次将新棋子放置到板上时都必须对板进行成像 带有墨水印章 然后输出表明什么类型的棋子 如果有的话 位于井字
  • awk -cut 如何删除带有字段分隔符的第二列

    我有一个 csv 文件 其中的数据如下 o 022344527 o lonyfoe o Joe o Joe o Otieno 我正在尝试删除第二列 Output o lonyfoe o Joe o Joe o Otieno 有任何想法吗 这
  • Scala 中的有效标识符字符

    我觉得很困惑的一件事是知道我可以在方法和变量名称中使用哪些字符和组合 例如 val 1 legal val 1 illegal val 1 legal val 1 legal val 2 1 illegal val 2 1 legal va
  • cuda简单应用程序适用于32位而不适用于64位

    我的简单 cuda helloworld 应用程序在 Windows 10 上使用 Visual Studio 2015 社区构建 32 位时运行良好 但是 如果我在 64 位中构建它 则不会执行 GPU 特斯拉K40c 工具包 CUDA
  • 在 application.yml 中设置根日志记录级别

    我将 application properties 与 Spring Boot 1 3 M1 一起使用 并开始将其转换为 yaml 文件 因为它变得越来越复杂 但我在将其转换为 yaml 时遇到问题 logging level WARN l
  • 计算地图:提前计算价值

    我有一个计算地图 http guava libraries googlecode com svn trunk javadoc com google common collect MapMaker html makeComputingMap