读Linux内核kfifo

内核无锁队列kfifo 内核无锁队列kfifo的工作原理 阅读详情

内核kfifo简约高效,匠心独运,有一下特点:

  • 保证缓冲区大小为2的次幂,不是的向上取整为2的次幂。
  • 使用无符号整数保存输入(in)和输出(out)的位置,在输入输出时不对in和out的值进行模运算,而让其自然溢出,并能够保证in-out的结果为缓冲区中已存放的数据长度。
  • 将需要取模的运算用 & 操作代替( a % size = (a & (size − 1)) ), 这需要size保证为2的次幂。
  • 使用内存屏障(Memory Barrier)技术,实现单消费者和单生产者对kfifo的无锁并发访问,多个消费者、生产者的并发访问还是需要加锁的(本文不涉及)。

以下为删改后可运行的代码:

// kfifo.h
#ifndef _LINUX_KFIFO_H
#define _LINUX_KFIFO_H

#include <stddef.h>


typedef int gfp_t;

struct __kfifo {
    unsigned int    in;
    unsigned int    out;
    unsigned int    mask;
    unsigned int    esize;
    void        *data;
};

extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
    size_t esize);

extern void __kfifo_free(struct __kfifo *fifo);

extern int __kfifo_init(struct __kfifo *fifo, void *buffer,
    unsigned int size, size_t esize);

extern unsigned int __kfifo_in(struct __kfifo *fifo,
    const void *buf, unsigned int len);

extern unsigned int __kfifo_out(struct __kfifo *fifo,
    void *buf, unsigned int len);

extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
    void *buf, unsigned int len);

#endif

// kfifo.c
#include "ringbuffer.h"
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

#define min(a, b)            (((a) < (b)) ? (a) : (b))

static bool is_power_of_2(unsigned long n)
{
    return (n != 0 && ((n & (n - 1)) == 0));
}

/*
 * internal helper to calculate the unused elements in a fifo
 */
static inline unsigned int kfifo_unused(struct __kfifo *fifo)
{
    return (fifo->mask + 1) - (fifo->in - fifo->out);
}

int __kfifo_alloc(struct __kfifo* fifo, unsigned int size,
        size_t esize)
{
    /*
     * round down to the next power of 2, since our 'let the indices
     * wrap' technique works only in this case.
     */
    // size = roundup_pow_of_two(size);

    assert(is_power_of_2(size));

    fifo->in = 0;
    fifo->out = 0;
    fifo->esize = esize;

    if (size < 2) {
        fifo->data = NULL;
        fifo->mask = 0;
        // return -EINVAL;
    }

    fifo->data = malloc(size * esize);

    if (!fifo->data) {
        fifo->mask = 0;
        // return -ENOMEM;
    }
    fifo->mask = size - 1;

    return 0;
}


void __kfifo_free(struct __kfifo *fifo)
{
    free(fifo->data);
    fifo->in = 0;
    fifo->out = 0;
    fifo->esize = 0;
    fifo->data = NULL;
    fifo->mask = 0;
}


int __kfifo_init(struct __kfifo *fifo, void *buffer,
        unsigned int size, size_t esize)
{
    size /= esize;

    // size = roundup_pow_of_two(size);

    assert(is_power_of_2(size));

    fifo->in = 0;
    fifo->out = 0;
    fifo->esize = esize;
    fifo->data = buffer;

    if (size < 2) {
        fifo->mask = 0;
        // return -EINVAL;
    }
    fifo->mask = size - 1;

    return 0;
}


static void kfifo_copy_in(struct __kfifo *fifo, const void *src,
        unsigned int len, unsigned int off)
{
    unsigned int size = fifo->mask + 1;
    unsigned int esize = fifo->esize;
    unsigned int l;

    off &= fifo->mask;
    if (esize != 1) {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);

    memcpy(fifo->data + off, src, l);
    memcpy(fifo->data, src + l, len - l);

}

unsigned int __kfifo_in(struct __kfifo *fifo,
        const void *buf, unsigned int len)
{
    unsigned int l;

    l = kfifo_unused(fifo);
    if (len > l)
        len = l;

    kfifo_copy_in(fifo, buf, len, fifo->in);
    fifo->in += len;
    return len;
}


static void kfifo_copy_out(struct __kfifo *fifo, void *dst,
        unsigned int len, unsigned int off)
{
    unsigned int size = fifo->mask + 1;
    unsigned int esize = fifo->esize;
    unsigned int l;

    off &= fifo->mask;
    if (esize != 1) {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);

    memcpy(dst, fifo->data + off, l);
    memcpy(dst + l, fifo->data, len - l);
}


unsigned int __kfifo_out_peek(struct __kfifo *fifo,
        void *buf, unsigned int len)
{
    unsigned int l;

    l = fifo->in - fifo->out;
    if (len > l)
        len = l;

    kfifo_copy_out(fifo, buf, len, fifo->out);
    return len;
}


unsigned int __kfifo_out(struct __kfifo *fifo,
        void *buf, unsigned int len)
{
    len = __kfifo_out_peek(fifo, buf, len);
    fifo->out += len;
    return len;
}

计算缓冲区中甚于空闲长度

static inline unsigned int kfifo_unused(struct __kfifo *fifo)
{
    return (fifo->mask + 1) - (fifo->in - fifo->out);
}
  • 此处fifo->mask + 1 即为缓冲区长度,这个好理解。
  • fifo->in - fifo->out 为已经写入长度

    • 当in > out 时很好理解。
      这里写图片描述
      这里写图片描述
      • 还有一种情况,就是in写满缓冲区尾部,折回到开头并且unsigned int 溢出,out不溢出。此时 in < out , in - out 还为已经写入长度?
        这里写图片描述

    答案是 in – out 为负数(又将溢出),in – out 的值还是为buffer中数据的长度。
    证明代码:

unsigned char a = 1;
unsigned char b = 254;
unsigned char c = a-b;
printf(" %u \n",c);

(以上图片来自https://www.linuxidc.com/Linux/2016-12/137938.htm)

c++ 简单实现


#include <stdio.h>

class RingBuffer
{
  public:
    RingBuffer(unsigned int size);
    ~RingBuffer();

    unsigned int get(void *pbuf, unsigned int len);
    unsigned int put(const void *pbuf, unsigned int len);
//for debug
    void print()
    {
        for(int i=0; i<mask_+1; i++)
        {
            printf("%c \n",data_[i]);
        }
    }
  private:
    unsigned int in_;
    unsigned int out_;
    unsigned int mask_;
    unsigned char *data_;

    unsigned int used()
    { return in_ - out_;}

    unsigned int unused()
    { return mask_ + 1 - used();}
};
#include "ringBuffer.h"
#include <string.h>
#include <stdlib.h>

#include <assert.h>

#include <algorithm>
#include <iostream>
/*
*   a % b = (a & (b − 1))
*/

namespace
{
inline bool is_power_of_2(unsigned long n)
{
    return (n != 0 && ((n & (n - 1)) == 0));
}

}

RingBuffer::RingBuffer(unsigned int size)
    : in_(0),
      out_(0),
      mask_(size - 1),
      data_(new unsigned char[size])

{
    assert(is_power_of_2(size) && size >= 2);
}

RingBuffer::~RingBuffer()
{
    delete[] data_;
}

unsigned int RingBuffer::get(void *pbuf, unsigned int len)
{
    unsigned char *buf = static_cast<unsigned char *>(pbuf);
    // 读取数据长度不能超过 已有数据长度
    len = std::min(len, used());

    __sync_synchronize();
    //对 out_ 取模
    unsigned int off = out_ & mask_;
    //mask_ + 1 - off == out_到缓冲区尾部的距离
    unsigned int l = std::min(len, mask_ + 1 - off);
    //先取后面out_到缓冲区尾部的数据,长度为l
    memcpy(buf, data_ + off, l);
    //再取剩余在缓冲区头部的数据,长度为len-l,如果len-l为0,则不会拷贝
    memcpy(buf + l, data_, len - l);

    __sync_synchronize();
    //直接加len,当unsinged int 溢出时自动归0
    out_ += len;

    return len;
}

unsigned int RingBuffer::put(const void *pbuf, unsigned int len)
{
    unsigned char *buf = static_cast<unsigned char *>(const_cast<void *>(pbuf));
    //写入数据长度不能超过 甚于空间
    len = std::min(len, unused());

    //TODO 缓冲区自动扩容

    __sync_synchronize();
    unsigned int off = in_ & mask_;
    // mask_ + 1 - off = in_ 到缓冲区尾部的距离
    unsigned int l = std::min(len, mask_ + 1 - off);

    memcpy(data_ + off, buf, l);
    memcpy(data_, buf + l, len - l);

    __sync_synchronize();
    in_ += len;

    return len;
}
无锁环形队列—linux内核数据结构 阅读详情

相关推荐

linux内核之无锁缓冲队列kfifo原理(结合项目实践)

Linux kernel里面从来就不缺少简洁,优雅和高效的代码,只是我们缺少发现和品味的眼光。在Linux kernel里面,简洁并不表示代码使用神出鬼没的超然技巧,相反,它使用的不过是大家非常熟悉的基础数据结构,但是kernel开发者能从基础的数据结构中,提炼出优美的特性。 kfifo就是这样的一类优美代码,它十分简洁,绝无多余的一行代码,却非常高效。 关于kfifo信息如下: 本文分析的源代码版本: 2.6.24.4 kfifo的定义文件: kernel/kfifo.c kfifo的头文件: incl

不如敲代码的博客 8432

Linux内核数据结构 —— 无锁环形队列 ( kfifo )

Linux内核数据结构 —— 无锁环形队列 ( kfifo )

qq_23174771的博客 7528

KFIFO_Test.zip

这段时间在写一个基于PCIE实现FPGA与上位机通信,利用多线程实现读写同步,本次使用到了KFIFO无锁队列,实现了kfifo的简单测试。

内核数据结构 —— 内核队列 (kfifo)

内核队列介绍 FIFO 先入先出队列是最常用的数据结构之一,在生产者——消费者模型中扮演了很重要的角色。 Linux 内核实现了一种称之为 kfifo 的内核队列,用于满足对数据有先入先出的场景。 对于通用的 fifo 而言,需要提供最基本的几个接口: 队列的分配 队列的初始化 队列的释放 队列的数据入列 队列的数据出列 队列判满 队列判空 有了上述几组接口,我们才能够算是真正...

StephenZhou 8103

大学生智能车竞赛初次尝试经验分享--1(硬件绘制电路,pcb部分)

本人机械电子专业大二暑假参加全国大学生智能车竞赛,之前参加过一些其他类型的比赛有一点基础,由于之前疫情影响所以做智能车比赛断代了,没有学长带也没有思路,从一开始的一头雾水逐渐摸索出我感觉比较实用的经验。 一.首先是硬件的准备工作: 1.硬件部分与要自己设计需要的电路制成pcb。推荐使用Altium Designer20,AD比较常用所以有多实用的教学视频,另外需要自己了解布线规则,包括信号线,电源线常用的宽度 一些电源电路,驱动电路建议用multisim仿真,没有问题再进行制版 单片机有关的需要仿真

weixin_52679034的博客 9834

【一步到位】Android Studio 实现安卓连接阿里云物联网云平台

最新版本目前是Android Studio Iguana | 2024.1.2,你可以到官网上去找之前的版本,手上有工作项目的不要去轻易尝试,说不定你就编译失败了,失败了也不要担心,解决就可以了。

m0_73799445的博客 1万+

linux内核kfifo(二)

一、kfifo概述 kfifo是一种"First In First Out "数据结构,它采用了前面提到的环形缓冲区来实现,提供一个无边界的字节流服务。采用环形缓冲区的好处为,当一个数据元素被用掉后,其余数据元素不需要移动其存储位置,从而减少拷贝提高效率。更重要的是,kfifo采用了并行无锁技术,kfifo实现的单生产/单消费模式的共享队列是不需要加锁同步的。 struct kfifo { unsigned char *buffer; /* the buffer holding th

木牛的博客 1798

腾讯云DBA面试(一面)

在第二阶段,根据RM返回的结果,如果涉及分布式事务的所有RM都返回可以提交, 则TM给RM发送commit的命令,每个RM实现自己的提交,同时释放锁和资源,然后RM反馈提交成功, TM完成整个分布式事务;根据事务所处的阶段,可以回滚到具体的版本,实现一致性。1.并发执行的事务,在prepare阶段,redo log先写文件缓存,第一个领头的事务,在等待n个事务后, 在第一个事务去刷写磁盘时,会把同组的其他的事务,也一起刷写到磁盘上,这样就减少了刷盘的次数,降低了磁盘的IOPS。分布式锁是怎么实现的?

u012565458的博客 1977

读Linux内核(4.9.9)之环形缓冲区实现kfifo

kfifo实现了环形缓冲区(RingBuffer),提供了无锁的单生产/单消费模式的共享队列;也就是如果只有一个写入者,一个读取者,是不需要锁的。 对于多个写入者,一个读取者,只需要对写入者上锁。 反之,如果有多个读取者,一个写入者,只需要对读取者上锁。在老的内核中直接定义了kfifo结构体,在新的内核中通过了一些稍显复杂的宏进行间接定义。我们先看下kfifo的原型__kfifo :struct ...

idwtwt的专栏 2307

避坑指南:CentOS7.9安装Python3.8.16后yum报错的快速修复方法

本文详细解析了在CentOS7.9系统安装Python3.8.16后导致yum报错的原因,并提供了快速修复方法。通过修改yum配置文件指向Python2解释器,以及使用alternatives工具管理多版本Python,有效解决兼容性问题。同时推荐使用虚拟环境隔离开发环境,避免影响系统稳定性。

weixin_26908317的博客 496

【无标题】 Python自动化法律文书撰写

Jinja2是一个功能强大的模板引擎,支持丰富的语法和功能。除了条件判断和循环语句外,Jinja2还支持过滤器、宏、继承等高级特性,非常适合处理复杂的文书模板。

master_chenchen的博客 2063

【Linux】无锁队列kfifo --研读(适合一读一写线程并发操作)

原文:https://blog.csdn.net/linyt/article/details/53355355 Linux kernel里面从来就不缺少简洁,优雅和高效的代码,只是我们缺少发现和品味的眼光。在Linux kernel里面,简洁并不表示代码使用神出鬼没的超然技巧,相反,它使用的不过是大家非常熟悉的基础数据结构,但是kernel开发者能从基础的数据结构中,提炼出优美的特性。 kfifo就是这样的一类优美代码,它十分简洁,绝无多余的一行代码,却非常高效。 关于kfifo信息如下: 本文分析的

我的笔记本 619

F280049C_HRPWM_死区时间高精度控制与MEP技术实战解析

本文深入解析了F280049C的HRPWM模块及其基于MEP技术的死区时间高精度控制。通过实测数据与TI官方代码对比,详细阐述了DBREDHR和DBFEDHR寄存器的配置技巧、精度优化方法及常见问题调试,为电源管理和电机控制应用提供了实用的实战指南。

yolo5detector的博客 217

数据结构之内核队列kfifo

kfifo概述 据wiki介绍,环形缓冲区(ring buffer),也称作圆形队列(circular queue),圆形缓冲区(circular buffer),循环缓冲区(cyclic buffer),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。 圆形缓冲区的一个有用特性是:当一个数据元素被用掉后,其余数据元素不需要移动其存储位置。相反,一个非圆形缓冲区(例如一...

u011298001的博客 3872

QT实现ftp服务器(附完整源码)

QT实现ftp服务器(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1783

【汇编实战开发笔记】一段汇编代码如何“反编译”成C代码?

介绍了一种由汇编代码得到C代码的方法

一个专注于嵌入式IoT领域的架构师,深耕IoT领域多年,深度掌握IoT领域的相关技术栈,包括但不限于RTOS内核的实现及其移植、硬件驱动移植开发、网络通讯协议开发、编译构建原理及其实现、底层汇编及编译原理、编译优化及代码重构、嵌入式IoT系统的架构设计等。 1万+

【高并发】多线程之无锁队列|无锁队列kfifo|性能优化

目录 多线程之无锁队列|性能优化 队列操作模型 并发无锁处理 无锁队列kfifo kfifo概述 kfifo功能描述 kfifo_alloc 分配kfifo内存和初始化工作 __kfifo_put和__kfifo_get巧妙的入队和出队 kfifo_get和kfifo_put无锁并发操作 总结 多线程之无锁队列|性能优化 队...

小鱼菜鸟的博客 815

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Linux中kfifo数据结构的精妙之处:即使溢出仍然正确

kfifo是linux内核中的环形缓冲区,实现了先进先出的队列数据结构。以下为kfifo的数据结构定义(内核版本2.6.33.20): [cpp] view plaincopy struct kfifo {          unsigned char *buffer;  // 环形缓冲区的大小          unsigned int size;      // 环形缓

btoh_workstation 900

深度学习工具包 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")

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

巧夺天工的kfifo(修订版)

原文:https://blog.csdn.net/linyt/article/details/53355355 Linux kernel里面从来就不缺少简洁,优雅和高效的代码,只是我们缺少发现和品味的眼光。在Linux kernel里面,简洁并不表示代码使用神出鬼没的超然技巧,相反,它使用的不过是大家非常熟悉的基础数据结构,但是kernel开发者能从基础的数据结构中,提炼出优美的特性。  kfi...

znHD的博客 546

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Linux---kfifo

Linux kernel里面从来就不缺少简洁,优雅和高效的代码,只是我们缺少发现和品味的眼光。在Linux kernel里面,简洁并不表示代码使用神出鬼没的超然技巧,相反,它使用的不过是大家非常熟悉的基础数据结构,但是kernel开发者能从基础的数据结构中,提炼出优美的特性。 kfifo就是这样的一类优美代码,它十分简洁,绝无多余的一行代码,却非常高效。关于kfifo信息如下: 本文分析的原代

all8023的专栏 872

kfifo 一读一写无锁缓冲区中的memory barrier

Linux kernel实现了一个kfifo,支持一读一写线程的无锁操作。具体代码见kernel/kfifo.c。在2.6稍高一点的版本里都会涉及到memory barrier。本文稍微解释一下memory barrier。 先看一下简单的两行代码: 26 bool flag = true; 27 int tmp = 10; 26,27在现代的多核处理器里...

weixin_30763397的博客 205

KFIFO无锁队列

linux内核中实现了以非常漂亮的无锁队列,在只有一个读者和一个写者的情况下,无需上锁,而拥有线程安全的特性,使得性能相比于加锁方式实现的队列提升数倍KFIFO的分析可见http://blog.csdn.net/chen19870707/article/details/41083183 这位作者讲的很清楚KIFIO可以实现无锁队列,但是为什么可以实现呢,通过这种方式为什么可以线程安全?换句话说,平

wejoncy的专栏 2688

Linux驱动学习---互斥和竞争

摘要 本文介绍了Linux驱动开发中处理竞态的几种主要方法:自旋锁、seqlock和RCU。自旋锁适用于不可休眠代码,在不同系统配置下行为不同但需按多核标准使用。seqlock实现无锁读,写入者优先,读取者通过版本号验证数据一致性。RCU通过读取-复制-更新机制实现高效读取,但仅适用于读多写少场景。文章还对比了睡眠等待型(信号量/互斥锁)、原地打转型(自旋锁)和无锁型(kfifo/seqlock)同步机制的特点及适用场景,强调正确使用锁的重要性以避免死锁。

m0_64549599的博客 673

王者万象棋S1赛季四端互通安装与账号同步全攻略

跨平台游戏正成为主流,但多端互通绝非简单的“一个包装到底”。其核心在于账号体系与数据云端同步机制,确保不同设备间段位、资源、进度的一致性。理解这一原理,能帮助玩家规避安装失败、版本不同步、数据异常等常见问题。以自走棋类游戏为例,其回合制特性降低了对毫秒级操作同步的要求,更依赖后端强一致性,因此跨端切换时需注意账号区服、设备在线状态、资源包加载等细节。王者万象棋S1赛季版本即典型场景,四端(安卓、iOS、PC客户端、模拟器)虽然共享账号与对战池,但各端的下载渠道、安装包结构、更新机制差异显著,模拟器还需关注V

weixin_34150830的博客 324

环形缓冲器(转)

圆形缓冲区(circular buffer),也称作圆形队列(circular queue),循环缓冲区(cyclic buffer),环形缓冲区(ring buffer),是一种数据结构用于表示一个固定尺寸、头尾相连的缓冲区,适合缓存数据流。 目录 1 用法2 工作过程3 圆形缓冲区工作机制 3.1 读指针与写指针3.2 区分缓冲区满或者

dxmcu的专栏 841
上一篇: shared_ptr实现copy-on-write
下一篇: 面向对象模型分析(继承,多态)
惜朝_
博客等级 码龄10年 9粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值