zoukankan      html  css  js  c++  java
  • 在程序中掌控NVIDIA Optimus

    转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2052

    NVIDIA的Optimus技术可以在笔记本上兼顾耗电量和性能,并能做到自动无缝切换。但问题就在于,不想让它自动的时候,该怎么办?在ThinkPad T420s上,NV的独立显卡是NVS 4200M,feature level支持到D3D 11.0;Intel的集成显卡是HD 3000,feature level支持到D3D 10.1。(对feature level还不熟悉的朋友可以看这篇

    在BIOS中控制

    支持Optimus的平台上,在BIOS中可以找到选项,可以选择使用NV、Intel或者自动切换。但这个是静态的,每次切换都得重启,肯定不是我们想要的。

    在右键菜单中控制

    在exe文件的图标上按右键,菜单里有一个“用图形处理器运行”的项,里面可以选择NV卡或者Intel卡。有趣的是,如果你在程序中枚举adapter,总会返回两块显卡。如果这里选的是NV卡,那么两块显卡都是NV卡。如果选的是Intel卡,那么第一显卡是Intel,第二是NV。

    在驱动中控制

    在NV的驱动中,可以通过全局profile,来控制所有程序是通过NV卡或者Intel卡来执行。另外还有个per-app的profile,可以让每个程序有不同的显卡配置。但这种方式仍然不够灵活,没法在程序中使用。

    静态链接CUDA

    Intel卡没法硬件支持CUDA,所以CUDA程序必然只能到NV的卡上执行。偶然发现NV GPU Computing SDK中的CUDA程序可以自动切换到NV的卡上执行,实验了一下各种组合,发现静态链接到cudart.lib,就可以切换到NV卡。动态载入nvcuda.dll的话则无效。这种方法需要引入一个用不着的库,不但不够简洁,在非NV平台上还会有麻烦。

    枚举所有设备

    前文提到,可以在程序中枚举adapter。如果强制选择了在NV卡上建立device的结果会如何呢?我试验的结果是,这么做确实能启动NV卡,但似乎系统会自动做个拷贝之类的事情,使得渲染的过程中有个固有开销。draw call越多越明显。虽然并非最佳,但仍不失为一个方案。

    神奇的NvOptimusEnablement

    NV开发者网站上,有个关于Optimus的新文档,里面提到了在R302以上的驱动里,引入了一个启动NV卡的新方法。通过从exe中导出一个名为NvOptimusEnablement的全局变量,它为1的时候驱动就能切换到NV的显卡:

    extern "C"
    {
    _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
    }

    通过这种方式,终于可以在程序中控制使用哪块显卡,并且没有上一种方法的性能下降问题。

    另一个有趣的发现是,如果是在dll中建立设备,exe是通过lib链接到dll的话,那么一切正常:设备名为NVS 4200M、feature level支持D3D11。但如果exe是通过LoadLibrary去动态导入那个dll,就会出现设备名为Intel HD 3000而feature level支持D3D11的奇葩状况。但无论哪种方式,都是真的启用了NV卡,并且性能无损。

    总结

    前面列举了多种在Optimus平台上主动启用NV卡的办法。最后两种,尤其是最后一种,是实用的,但远非完美。希望某天NV能根据CreateDevice所在的module,而不是exe的module来决定是否切换NV卡,以及返回正确的设备名。

  • 相关阅读:
    charles 安装、破解、简单介绍
    8、postman中 转码生成python-requests接口请求代码,并定义一个获取及请求的方法
    json 序列化和反序列化(针对python数据类型)
    leetcode 35.搜索插入位置
    leetcode 27.移除元素
    js 中的数组方法
    js判断小数点后几位小数
    leetcode 15.三数之和
    leetcode 1.两数之和
    leetcode 680.验证回文字符串
  • 原文地址:https://www.cnblogs.com/gongminmin/p/2701352.html
Copyright © 2011-2022 走看看