Code Monkey home page Code Monkey logo

go-lock-free-ring-buffer's Introduction

Lock free ring buffer

Go Report Card Go Reference GitHub license GitHub release

This repo is an implementation of lock-free ring buffer built on Golang.

You can find more information about this implementation at my blog post.

Please note that v0.2.0 involved generics feature, which requires go version >= 1.18. Lower go version please choose v0.1.0.

API

Below is the API and how to use it:

type RingBuffer[T any] interface {
  Offer(T) (success bool)
  Poll() (value T, success bool)
}

We can simply call Offer() and Poll() to use it like a normal queue.

The GCShape introduced by generics feature can ensure that no heap memory allocation during Offer() and Poll(). Here is an article to explain the performance changes before and after involve generic.

When create an instance, say we want to use it to store string:

import (
  "github.com/LENSHOOD/go-lock-free-ring-buffer"
)

buffer := lfring.New[string](lfring.NodeBased, 16)

The first argument of New() is the type of ring buffer, I currently provide two implementations, they both have same behavior, but benchmark test shows that the "NodeBased" one has better performance.

The second argument capacity defines how big the ring buffer is, in consideration of different concrete type, the size of buffer maybe different. For instance, string has two underlying elements str unsafe.Pointer and len int, so if we build a buffer has capacity=16, the size of buffer array will be 16*(8+8)=256 bytes(64bit platform).

Performance

  1. Two types of lock-free ring buffer compare with go channel in different capacities

  2. Two types of lock-free ring buffer compare with go channel in different producers / consumers ratio

  3. Two types of lock-free ring buffer compare with go channel in different threads

From above performance curve, we can see that ring buffer get better performance under some specific conditions. Below image clarifies the proper use scenario of ring buffer.

As the result, ring buffer fits better in the case of producers/consumers not balance, and capacity not too big.

Above images are screenshots, check full charts here.

Unfinished features

  • Try to optimize the performance of single producer/consumer performance

    • Based on the previous result, the ratio of production/consumption speed plays a partial key role to influence ordinary channel's performance. We can move one step forward, to do some optimization at such a special case of single producer/consumer.

    • Single means no contention, so the costly CAS operation may be replaced with normal operation, and single load/store may be replaced with vectorized load/store. Furthermore, once we say vectorization, we think introduce SIMD to accelerate load/store operations.

go-lock-free-ring-buffer's People

Contributors

lenshood avatar

Stargazers

Oscar Liu avatar  avatar MS avatar hlp avatar ZRY avatar dexter avatar banshan avatar Tyr Chen avatar Lovro Mažgon avatar liuzhenwei avatar  avatar Feego avatar Harry Chen avatar kenta avatar 虫子樱桃 avatar Bo-Yi Wu avatar Ben avatar  avatar Eliah Rusin avatar CNine avatar lieon avatar Vivcharyk Myroslav avatar vamdt avatar  avatar marble avatar  avatar Sam Li avatar никита avatar Anish Mukherjee avatar  avatar SeasonLee avatar Philip Deuchler avatar Fishbone° avatar Gordon Wang avatar sfang avatar 坐和放宽 avatar rader avatar BlaCkinkGJ avatar yangchenglong avatar Tengfei Tu avatar Zeinx avatar  avatar pseudocodes avatar  avatar Mutalisk avatar MARATRIX Li avatar Fengda Huang avatar

Watchers

 avatar

Forkers

anima-os-dev

go-lock-free-ring-buffer's Issues

元素个数无法确保一致性

image 你好,这种方式区控制ring slice 元素容量,无法保证添加和读取数据的原子性。 1.如果当前只能容纳一个元素,此时2个goroutine执行Offer操作,isFull会存在2个goroutine都会条件通过,这种情况就会存在问题。

SingleProducerOffer的一点疑惑

func (r *nodeBased[T]) SingleProducerOffer(valueSupplier func() (v T, finish bool)) {
v, finish := valueSupplier()
if finish {
return
}

for r.Offer(v) { 这的作用是直到加成功为止吧?不应该是 !r.Offer吗?
}

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.