24、代码级时序优化全解析

代码级时序优化全解析

在代码开发过程中,时序优化是提升程序性能的关键环节。以下将详细探讨代码级时序优化的多个方面,包括函数优化、处理器特定指令的运用以及编译器优化等内容。

1. 函数sqrt的优化

在数学函数的使用中,结果的准确性与运行时间往往需要权衡。以平方根函数 sqrt 为例,通常编译器提供的库函数在整个取值范围内尽可能保证结果的准确性,但在运行时间方面效率较低。通过适当降低精度,可以显著减少运行时间。

代码示例如下:

unsigned short sqrtFast(unsigned short x)
{
    unsigned short a,b;
    b = x;
    a = x = 0x3f;
    x = b/x;
    a = x = (x+a)>>1;
    x = b/x;
    a = x = (x+a)>>1;
    x = b/x;
    x = (x+a)>>1;
    return x;
}

该函数通过一些加法、二进制移位操作和除法来近似计算一个数的平方根。与编译器库中的 sqrt 函数相比,计算结果的精度有所降低。对于小输入值,误差较大;对于大输入值,结果往往偏大。不过,其执行速度更快。

下面是 sqrt 和 sqrtFast 函数核心执行时间(CET)的对比表:
| 函数 | CETmin | CETmax | CETø |
| ---- | ---- | ---- | ---- |
| sqrt | 114 | 646 | 569 |
| sqrtFast | 464 | 476 | 472(约快17%) |

需要注意的是,该计算包含对输入参数 x 的除法操作。如果 x 在运行时的值为零,某些处理器会触发异常或陷阱。因此,对于这类处理器,代码需要进行补充以正确处理 x = 0 的异常情况。

此外,考虑将平方根计算实现为内联函数,这样可以节省函数调用和返回的开销,同时更有效地利用缓存。

在进行函数优化时,有两个关键方面必须考虑:
- 确保优化后的变体的运行时间确实更低。许多所谓的优化可能会减少源代码行数,但生成的机器代码效率不高。因此,需要进行测量或代码模拟。
- 检查优化后的代码是否仍然提供原始功能,以及是否完全准确或存在可接受的偏差。在某些情况下,分析这些偏差所需的工作量可能很大,以至于不得不放弃代码优化过程。

2. AURIX的线性核心ID

第二代英飞凌AURIX处理器最多可配备六个CPU。使用地址为 FE1C 的特殊功能寄存器可以在运行时查询核心ID,但这些ID不是连续的。对于CPU 0到4,该寄存器返回值0到4,但CPU 5的核心ID为6。

对于大多数应用程序,软件需要为CPU提供连续的编号。通常,这个线性ID用作访问数组的索引,不连续的编号会造成阻碍。因此,需要进行转换,当输入值为0到4时返回输入值,当输入值为6时返回5。

以下是一个简单的实现代码:

#if defined __GNUC__
#include <machine/intrinsics.h>
#endif

inline unsigned char GetLinearCoreId(void)
{
#if defined __TASKING__
    unsigned char id = __mfcr(0xFE1C);
#elif defined __GNUC__
    unsigned char id = __MFCR(0xFE1C);
#else
#error "compiler not supported"
#endif
    if (id > 5) {
        return 5;
    } else {
        return id;
    }
}

int main(void){
    return (int)GetLinearCoreId();
}

在不启用优化的情况下,HighTec GCC编译器生成的汇编代码较多。而启用优化(使用 -O3 选项)后,生成的汇编代码仅需四条指令,利用了TriCore架构提供的 min 机器指令。

实际上,屏蔽高24位并不是必需的。AURIX处理器手册显示,地址为 0FE1C 的特殊功能寄存器是32位寄存器,但只有低三位表示核心ID,高29位是保留位。 min 机器指令确保 GetLinearCoreId 函数永远不会返回大于5的值。

进一步优化后的代码可以实现为宏:

#if defined __TASKING__
#define GetLinearCoreId( ) __min( __mfcr(0xFE1C), 5 )
#elif defined __GNUC__
#define GetLinearCoreId( ) ({ unsigned int coreId_;
    __asm( "mfcr %0, 0xFE1C\n\tmin.u %0, %0, 5" :
    "=d"(coreId_) ); coreId_; })
#else
#error "compiler not supported"
#endif

int main(void){
    return (int)GetLinearCoreId();
}

这个例子不仅展示了AURIX提供的特殊机器指令可以高效实现任务,还提供了代码级运行时优化的思路和方法。

3. 饱和计算

在许多计算中,要求结果进入饱和状态而不是溢出,即结果取其所能表示的最大值。同样,在发生下溢时,结果应取其所能表示的最小值。

以下是一个对两个无符号16位数字进行饱和加法的函数:

unsigned short sadd16(unsigned short a, unsigned short b)
{
    return (a > 0xFFFF - b) ? 0xFFFF : a + b;
}

编译器为AURIX生成的汇编代码使用了减法、加法、条件跳转等六条指令。

而AURIX提供了用于饱和计算的特殊机器代码指令,使用 sath 指令的实现如下:

unsigned short sadd16(unsigned short a, unsigned short b)
{
    return __sathu(a + b);
}

生成的汇编代码仅需三条机器代码指令即可实现相同的功能。这表明,尽管编译器进行了最高级别的优化,但仍可能无法找到最优实现,程序员对处理器特定指令的了解可以实现显著的优化。

4. 处理器特定指令概述

大多数微处理器的部分指令在其他微处理器中也能找到相同或相似的形式,如内存读写、寄存器内容复制、加减运算、跳转指令、子程序调用等。然而,许多处理器还提供一些不太常见的指令,如英飞凌TriCore架构中的 min 和 sat.hu 指令。

当需要在C代码中插入特定的机器代码指令时,可以使用内联汇编、编译器内置函数或编译器内置宏。例如,在获取AURIX核心ID的代码中,使用了TASKING编译器的内置函数 __mfcr 或HighTec GCC编译器的内置宏 __MFCR 。

由于大多数编译器支持多种处理器架构,特殊指令并不总是得到最优支持。在这种情况下,需要明确指示编译器使用特殊指令。为了充分利用处理器指令集的潜力,程序员必须熟悉所使用处理器的指令集,并具备选择和使用最优机器指令的能力。

5. 编译器优化

将源代码编译为机器代码有多种映射方式,编译器优化的目标是找到最有效的映射。通常,效率可以从“占用内存少”或“运行时间短”的角度来理解,在编译器手册中分别描述为“优化大小”和“优化速度”。

这两个目标并不总是相互矛盾的。例如,16位饱和加法的优化变体在大小和速度上都优于初始版本。

“Leaf-Call Optimization”是一种既能减少内存需求又能减少运行时间的优化方法。在函数末尾的函数调用被替换为跳转命令,避免了调用和返回的组合,编译器直接生成跳转指令。

以下是一个简单的示例代码:

void Function_D(void)
{
    // Do something here...
}

void Function_C(void)
{
    // Do something here...
    Function_D();
}

void Function_B(void)
{
    // Do something here...
    Function_C();
}

void Function_A(void)
{
    // Do something here...
    Function_B();
}

int main(void)
{
    Function_A();
    return 0;
}

TASKING编译器在使用 ctc.exe -O2 -o main.src main.c 调用时生成的汇编代码展示了这种优化。

在选择编译器优化时,可以通过以下几种方式:
- 编译器提供了现成的优化组合,用户只需指定大致目标(“优化大小”或“优化速度”)或优化程度。常用的优化程度开关有 -O0 (禁用所有优化)和 -O1 到 -O3 (逐渐增强的优化)。如果不选择任何优化选项,编译器默认使用 -O0 。优化选项在命令行调用编译器时传递,如果构建环境支持,还可以为每个源代码文件调整优化设置。
- 对于编译器提供的每个优化,都有一个单独的编译器开关,可以在命令行调用编译器时传递。在进行代码级运行时优化之前,应仔细研究编译器手册中描述的可用优化。
- 可以在源代码的函数级别甚至函数内部直接激活或停用个别优化。不同编译器的实现机制不同,例如TASKING编译器使用 #pragma 语句,HighTec GCC编译器可以使用 __attribute__ 来为特定函数启用优化。

需要注意的是,调试经过优化编译的软件比调试未优化的软件困难得多。随着优化数量的增加,机器代码指令与相应源代码之间的关系变得更加复杂。例如,“代码重排序”优化会重新排列机器代码指令的顺序,虽然提高了运行效率,但在调试时会造成困扰。

综上所述,代码级时序优化是一个复杂而重要的过程,需要综合考虑函数优化、处理器特定指令的使用以及编译器优化等多个方面,以实现程序性能的提升。通过合理运用这些优化方法,可以在准确性和运行时间之间找到平衡,满足不同应用场景的需求。

代码级时序优化全解析

6. 优化方法总结与流程

为了更清晰地展示代码级时序优化的过程,我们可以总结出一个优化流程:

graph LR
    A[确定优化目标] --> B[分析代码性能瓶颈]
    B --> C{是否可函数优化}
    C -- 是 --> D[进行函数优化(如sqrt、核心ID转换等)]
    C -- 否 --> E{是否可利用处理器特定指令}
    E -- 是 --> F[使用内联汇编、内置函数或宏插入特定指令]
    E -- 否 --> G{是否可编译器优化}
    G -- 是 --> H[选择合适的编译器优化选项]
    G -- 否 --> I[重新分析性能瓶颈]
    D --> J[测试优化效果]
    F --> J
    H --> J
    J --> K{效果是否达标}
    K -- 是 --> L[完成优化]
    K -- 否 --> I

在这个流程中,首先要明确优化的目标,是追求运行时间的减少还是内存使用的降低,或者两者兼顾。然后对代码进行性能分析,找出可能存在的瓶颈。根据分析结果,依次考虑函数优化、处理器特定指令的利用和编译器优化。每一步优化后都要进行测试,检查效果是否达到预期,如果未达标则需要重新分析瓶颈。

7. 不同优化场景下的选择

在实际开发中,不同的应用场景可能需要不同的优化策略。以下是一些常见场景及对应的优化建议:
| 应用场景 | 优化重点 | 具体方法 |
| ---- | ---- | ---- |
| 实时系统 | 运行时间 | 优先考虑处理器特定指令和编译器的速度优化选项,如使用AURIX的特殊指令进行饱和计算,开启编译器的 -O3 优化 |
| 资源受限系统 | 内存使用 | 选择编译器的大小优化选项,如 -Os ,同时考虑函数的内联优化以减少函数调用开销 |
| 对精度要求不高的计算 | 运行速度 | 采用近似算法,如使用 sqrtFast 替代 sqrt 函数 |

8. 优化过程中的注意事项

在进行代码级时序优化时,还需要注意以下几点:
- 兼容性 :使用处理器特定指令和编译器特定的优化选项时,要确保代码在不同的处理器和编译器版本上具有兼容性。例如,不同编译器对内置函数和宏的支持可能不同,需要进行相应的调整。
- 调试难度 :如前文所述,优化后的代码调试难度会增加。在优化过程中,建议先进行未优化代码的调试,确保功能正确后再进行优化。同时,可以保留未优化版本的代码作为参考。
- 性能测试 :优化前后都要进行严格的性能测试,以确保优化确实带来了预期的效果。测试环境应尽可能接近实际运行环境,避免因测试环境差异导致结果不准确。

9. 常见问题及解决方案

在优化过程中,可能会遇到一些常见问题,以下是对应的解决方案:
| 问题 | 原因 | 解决方案 |
| ---- | ---- | ---- |
| 优化后性能未提升 | 优化方法选择不当或存在其他性能瓶颈 | 重新分析代码,检查是否有其他未发现的瓶颈,尝试不同的优化方法 |
| 编译器不支持特定指令或优化选项 | 编译器版本过低或不支持该处理器架构 | 更新编译器版本,或者选择支持该处理器的编译器 |
| 代码兼容性问题 | 使用了特定编译器或处理器的特性 | 对代码进行修改,使其具有更广泛的兼容性,或者提供不同版本的代码以适应不同环境 |

10. 总结与展望

代码级时序优化是提升程序性能的重要手段,通过函数优化、处理器特定指令的利用和编译器优化等方法,可以在准确性和运行时间之间找到平衡。在实际应用中,要根据具体的场景和需求选择合适的优化策略,并注意优化过程中的兼容性、调试难度和性能测试等问题。

随着处理器技术的不断发展,未来可能会有更多的特殊指令和优化方法出现。开发者需要不断学习和掌握新的技术,以更好地进行代码优化,满足日益增长的性能需求。同时,自动化优化工具也可能会得到进一步发展,帮助开发者更高效地完成优化任务。

通过深入理解和运用代码级时序优化的方法,开发者可以编写出更高效、更稳定的程序,为各种应用场景提供更好的支持。

相关推荐

LCD屏幕时序参数全解析:从Pixel Clock到物理时钟的实战计算指南

本文全面解析LCD屏幕时序参数,从Pixel Clock到物理时钟的实战计算指南。详细介绍了hactive、vactive、porch值等关键参数的计算方法,以及如何通过调整这些参数优化显示效果和系统性能。特别针对MIPI DSI接口的时钟转换和多屏幕配置提供了实用解决方案。

hh234的博客 957

IIC协议实战:从时序解析到驱动AT24Cxx的代码实现

本文深入解析IIC协议时序逻辑,并提供驱动AT24Cxx系列EEPROM的实战代码实现。从起始信号、应答机制到跨页读写技巧,详细讲解IIC通信核心要点,并分享模块化驱动设计、错误处理及性能优化经验,帮助开发者快速掌握嵌入式存储开发。

weixin_33721427的博客 140

设备树背后的科学:MIPI DSI屏幕时序参数计算全解析

本文深入解析MIPI DSI屏幕时序参数在设备树中的计算原理与实践方法。详细介绍了水平/垂直时序参数的含义、像素时钟频率的核心计算公式,并结合瑞芯微平台的特殊考量,提供了lane速率计算和实际配置表示例,帮助开发者准确配置屏幕驱动参数。

view3的博客 608

PIC24FJ128GA310驱动WS2812B LED的精准时序控制实践

在嵌入式系统开发中,时序控制是驱动智能LED的核心技术。WS2812B作为集成控制电路的RGB LED,采用特殊的单线归零码协议,对微控制器的时序精度要求极高。通过PIC24FJ128GA310微控制器的高性能内核和丰富外设,开发者可以实现纳秒级精度的信号控制,满足WS2812B严格的时序规范。这种技术组合广泛应用于LED灯带控制、装饰照明和交互式灯光装置等领域。特别是在需要精确色彩表现和动态效果的场景中,掌握WS2812B的驱动原理和PIC24的硬件特性,能够实现从基础灯光控制到复杂视觉效果的全套解决方案

weixin_30414305的博客 373

DRAM时序参数全解析:从tCL到tRFC,如何优化内存性能?

本文深入解析DRAM时序参数(如tCL、tRCD、tRP等)的优化策略,从基础原理到实战调优,帮助用户提升内存性能。通过详细的第一时序和第二时序参数分析,结合不同应用场景(游戏、内容创作、服务器)的特化调优方案,实现最佳性能表现。

weixin_29279153的博客 602

【FPGA & Verilog】模24计数器实战:从设计到仿真全解析

本文详细解析了使用FPGA和Verilog实现模24计数器的全过程,从基础概念到代码实现、RTL视图分析、ModelSim仿真验证以及FPGA引脚约束。重点介绍了模24计数器的设计要点、Verilog代码优化技巧和常见问题调试方法,为数字电路设计提供了实用指导。

weixin_29194693的博客 385

LCD屏幕时序信号全解析:PCLK、VS、HS、DE到底怎么工作的?

本文深入解析了LCD屏幕驱动中的核心时序信号PCLK、VS、HS和DE的工作原理。PCLK作为像素时钟,是所有数据传输的节拍器;VS和VSYNC信号定义了帧与行的起始,构建了画面的空间坐标;而DE信号则精准地标记了有效数据的窗口。掌握这些信号的协同工作方式,是调试显示问题和优化显示性能的关键。

ll5678的博客 934

文石NoteX3国行版安装 Google Play经验分享

文石NoteX3国行版安装 Google Play经验分享。

2301_80693261的博客 7599

GPU微架构演进分析--从SIMT到Scalar-Vector-Tensor计算的混合配比与调度

GPU架构经历了从专用计算模块到统一可编程处理器的演进。传统GPU面临专用电路配比难题,Nvidia Tesla架构通过引入可编程多线程处理器实现图形与计算的统一。Fermi架构进一步向计算倾斜,随后的架构陆续加入Tensor Core等专用单元。AI时代促成了从图形处理主导向AI计算的转变,形成了Scalar+Vector+Tensor的混合计算范式。SIMT调度重要性降低,CUDA面临新挑战,RISC-V等架构可能带来新机遇。

ChipCamp的博客---https://chipcamp.blog.youkuaiyun.com/ 915

杰理蓝牙AC696X开发实战:自定义蓝牙名称与提示音配置指南

本文详细介绍了杰理AC696X蓝牙芯片开发中自定义蓝牙名称与提示音配置的完整实战指南。文章从SDK工具定位入手,逐步讲解如何通过配置工具修改蓝牙名称,并重点阐述了替换提示音的正确步骤与音频文件(如WAV格式、16kHz采样率)的详细参数要求,最后指导如何生成并验证最终固件,帮助开发者快速实现个性化设备定制。

weixin_29161719的博客 560

淘宝链接跳转微信全攻略:自建合规中转页实现私域引流

在跨平台运营中,链接跳转是连接不同生态、实现流量引导的关键技术。其核心原理是通过服务器端或前端逻辑,将用户从一个平台的链接安全引导至目标页面,同时规避平台间的访问限制。这项技术的核心价值在于打破数据孤岛,实现跨平台用户沉淀与精细化运营,广泛应用于电商引流、私域流量构建和跨平台营销等场景。本文聚焦于**淘宝短链**与**企业微信**之间的跳转难题,提供了一套基于自建中转页面的完整工程解决方案,手把手教你如何通过合规的技术手段,将淘宝流量高效、安全地引导至微信生态,并实现数据追踪与客户分流。

weixin_34185512的博客 411

DataGridView 右键菜单复制(公共)

dataGridView1.CellMouseClick += new DataGridViewCellMouseEventHandler( (sender1, e1) => { if (e1.Button == MouseButtons.Right) {

沁心渃水 2832

STM32开发 -- 4G模块开发详解(1)

这部分一直再看,资料都已经整理好了,但是一直没有汇总。接下来就详细的看一下,GSM这部分是怎么实现的。

不积跬步,无以至千里 5万+

第0章 《机器人工程师带你入门SLAM》专栏所有文章目录汇总(截止目前115篇文章),方便大家查看阅读

《机器人工程师带你入门SLAM》专栏文章汇总:优快云热销专栏已更新100+篇优质内容,涵盖SLAM技术全栈知识体系。文章分为三大类:1)基础工具与环境配置,包括Ubuntu、Git等必备技能;2)C++编程从入门到进阶,详解变量、类、模板等核心概念;3)SLAM核心库实战,深入解析ROS、Eigen、PCL等关键库的应用。专栏提供从计算机基础到项目实战的系统学习路径,并附代码实例。点击专栏主页可订阅查看全部内容,后续将保持更新。

行知SLAM 1068

【Zephyr电源与功耗专题】13_PMU电源驱动介绍

本文介绍的PMU芯片包含2路DCDC和6路LDO,在Zephyr实时操作系统下实现了完整的电源管理解决方案。

zero的博客 842

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: 60、视频中的人类动作识别与图像分类新方法
下一篇: 11、无线传感器网络与移动机器人视觉系统技术解析
html8
博客等级 码龄8年 105粉丝 1092原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值