SharedApplication: Linux Shared Memory Wrapper in C++, Lockfree Queue

Introduction

SharedApplication is a class used for sharing data between processes, support malloc between multi-process and could be derived to create multi-process data structure.

SharedQueue is a lockfree queue with fixed capacity, derived from the SharedApplication. Easy to use.

Code

Github:https://github.com/mhy12345/SharedApplication

Usage

SharedApplication

Create a SharedApplication instance with a unique APPKEY. The APPKEY is used to tell the operating system which Shared Memory you are going to alloc.

Then, we can do some basic configuration to our application.

Set the size of the memory you are going to alloc, and this must called before start. If it wasn’t called, then the default size will be 1024 bytes.

Some other configurations are also available.

After the configurations, you can start the sApp, simple write:

Then, in you program, you can use malloc to alloc memory.

In other process, if you use the same APPKEY, and use same order of malloc, and same size, then the contents in the memory allocated should be synchronized.

Shared Queue

The SharedQueue is a private inherited form the SharedApplication, means you can just replace SharedApplication with SharedQueue.

In the main function, you can use  sQueue like a normal queue.

Attentions

  • In the SharedApplication, make sure you alloc each memory block using the same order and size
  • The destructive function must be called, otherwise the shared memory cannot be deleted.

SharedApplication: 共享内存操作原理

共享内存是Linux里面一个进程通讯的实现机制,通过系统API将同一块内存块挂载在到两个进程的内存地址空间中,从而实现共享内存的操作。

对于一块共享内存,我们用Key和Id进行标识,Key为用户自定义的一个值,不同进程倘若使用了同一个Key,即视为他们需要同一块共享内存。通过Key,用户可以向系统申请开一个指定大小的共享内存,并返回这块内存的内部标识Id,之后的挂载操作都需要用Id进行制定。

有关共享内存的API都封装在了<sys/shm.h>文件中,具体有

通过自定义Token新建共享内存,并返回标识符: appId = shmget(TOKEN,size,0666)

通过标识符挂在已经建好的共享内存到本地内存空间: ptr = shmat(appId,NULL,0)

取消挂载: shmdt(ptr)

删除共享内存: shmctl(appId,IPC_RMID,NULL)

每一次需要共享内存,强行调用这些语句看起来比较的繁琐,因此我希望写一个共享内存的操控框架,使得每次只需要极少的代码,就可自动完成诸如共享内存挂载,新建等要求。这也是SharedApplication的编写背景。

 

无锁数据结构设计 之 内存顺序实际表现

这是mhy12345的无锁数据结构教程的第四篇,在详解了C++内存顺序之后,谈谈C++内存顺序在实际运行中的一些影响。

从原理上出发看看C++内存顺序的含义:是由于计算机缓存等内存结构性质导致的线程间单原子变量读写互相不可见的情形。

不过,稍微仔细想想,发现这其实只是一种理论概率上的情形。

首先在考虑内存顺序的误差时,我们先举一个锁的例子——

锁,是为了防止线程之间的资源竞争,

假设一个线程在1%的时间需要独占某一个资源,两个没有加锁的线程产生了竞争导致程序崩溃的概率1%

则,在某一时刻,两个线程同时占有某资源且发生崩溃的概率应为10^{-6}

别看这概率很小,但是我们的程序是若干时点的概念,我们若将时点设为10^6个(这个数应该是有一段程序运行间线程期望切换次数决定的),则发生崩溃的概率为

    \[(1-10^{-6})^{10^6}-1 = 63%\]

因此我们发现,对于线程而言,加锁确实是必不可少的。

不过确实给我们一个提示:为什么我们一定要研究理论上那一丁点的小概率事件呢?假设我告诉你崩溃的概率只有10^-20,那我们还需不需要加锁呢?

我们在开始

 

mhy的量化笔记 之 基于LSTM的股市趋势预测

思路

经过一段时间对LSTM的学习,大概了解了LSTM的运作规律。因此尝试运用LSTM预测股市走势。

参考:文章A  文章B

这篇文章是对于该方法的一种初步尝试,然而问题显而易见。

  1. 该算法将指数数据未经任何处理就丢到了LSTM里面,这是“不可能”学习出任何知识的。由于神经网络类机器学习算法是基于线性组合以及非线性函数,因此能够学习出“较大”,“正”,“上升”这一类描述,但无法学习出“区间最大值”,“日线高点出现”,“指数线交叉”。所以我们需要做的应该是将这类信息人工处理后丢入LSTM!

尝试1:上证指数K线4值

直接输入上证K线的open,close,high,low,预测1/5/10日收盘价涨跌.

正确率最后能够到达65%左右。

奇怪的是用GRU和LSTM效果没有显著的差别,感觉远期的信息并没有被学习进去……

全部都学成跌了,当然没有差别咯……算了一下,MCC相关系数仅有0.02,等于随机预测.

由于之前使用的是涨跌幅的log的平方和作为loss函数,可能确实在精度上也会有问题。

是不是将label设为涨跌幅log平方的符号函数会更好一些呢?

最后,模型准确率平均在51%左右,且在训练过程中有时候会跳到49%,相关性也会在有些时候呈现负相关,具体来说就是没有训练处结果。

尝试2:加入更多数据

测试数据

随机选择股票

000416 000996 600096 600291 600695 000416 000996 600096 600291 600695 000951 300143  600155 600354 600785

收集2010-2017的日线数据进行分为训练集与测试集。

指标选择

由最初的四个数据拓展到更多的指标

  • open 开盘价
  • close 收盘价
  • high 最高价
  • low 最低价
  • volume 成交量
  • sh 上证指数
  • sz  深证成指
  • hs300 沪深300
  • cyb 创业板指数
  • ma_5 5日均线
  • ma_10 10日均线
  • ma_20 20日均线
  • ma_60 60日均线
  • macd_dif macd短线
  • macd_ema macd长线
  • macd_macd macd柱状线
  • rsi rsi指数
  • adx adx指数
  • cci cci指数

将指数分组进行归一化,例如将ochl和均线值统一进行归一化,指数独自归一化。

分类函数

之前是将误差平方和作为loss函数,后来发现这在二分类问题中非常的不优美。

对于典型的二分类问题

loss =- (X * log(X’) + (1-X)*log(1-X’))

作为误差函数会更加容易收敛。

分组训练

之前的分组训练是直接取相邻区间,仔细想想确实bug非常严重,本身分batch就是为了防止出现边界数据,导致将梯度影响错误的方向。这里我们改成使用随机batch_size个数据使得训练表现好了一些

优化指标

之前指标发现实际上大盘数据对于一只股票并没有太大的用处,因为我不知道这个股票的类型,因此考虑增加:

  • is_sh 是否为沪市
  • is_sz 是否为深市
  • is_cyz 是否为创业板

至此,已经可以将模型准确率提高至53%

修改分类函数

将之前的二分类改为三分类,其中表示随机波动的分类0产生的所有结果不计入loss函数。准确率提高至55%,不过这个55%的含义与之前不同,这里计算的只是非零分类的准确率。

 

Tushare数据自动缓存

tushare是一个财经数据获取库,内置若干财经数据的获取爬虫,将各种数据的爬取封装在了一起。但是tushare有一个很大的缺点,就是其抓取的数据无法缓存在本地。故考虑实现一组自己的api用以缓存tushare数据。

这是python中获取tushare数据的典型例子,我们考虑实现一个简单的装饰函数,将函数调用以及调用的参数进行记忆化!

这里面data_cacher函数包装后的ts.api增加了将返回值保存为以“函数名”、“参数”命名的文件中,供下次调用直接使用。

最后,如何实现data_cacher函数呢?直接上代码:

 

 

[Pikapika]科技文献的脉络梳理-网页展示的编写

基于Flask编写

既然后端数据处理使用了python,最开始的想法是通过python-flask写网页,也因此学习了flask,但是因为实际写后端的时候没有网,于是乎重新回到了自己比较熟悉的nodejs

基于Nodejs编写

网站demo:http://pikapika.mhy12345.xyz:3000

运用d3的数据图形化的库,展示词云与结构树,过程参见http://blog.mhy12345.xyz/2017/05/18/nodejs学习笔记/

词云

使用d3项目https://www.jasondavies.com/wordcloud/,由其中demo的browserify.js生成。

 

结构树

结构树https://bl.ocks.org/mbostock/4063570,直接把里面的js代码搬下来就好了。当然,需要各种修改以适应这里的情况,不过这些细节就不用说了。

 

[Pikapika]科技文献的脉络梳理-构建查询Wiki的数据结构

首先我们需要实现的是一个能够查询Wiki的数据结构,而有如下几种处理方式

  1. 直接的爬虫抓取及其优化
  2. 调用现成python库(基于wiki的api)
  3. 下载离线版wikipedia

直接使用爬虫抓取wikipedia

如果直接使用python的urllib库调用的话,由于网络延迟等问题,效率大概是3sec/search

这里粘贴一个爬取百度百科的代码,wiki可以肯定比百度百科慢,毕竟在墙外面……

 

接着考虑使用更加高效的爬取框架scrapy

代码架构比较复杂,但是搜索的速度可以提升至1sec/search,其原理大概是通过异步的方式解决网络延迟的问题,但是基础的长达3sec的网络延迟还是必定会存在的,不过对于我们的分析还是过于慢了

Python库实现wiki查询

python有一个叫做wikipedia的库,其核心是通过wikipedia的公开api实现查询。还是很慢……

离线Wiki数据查询

离线数据下载主页:https://en.wikipedia.org/wiki/Wikipedia:Database_download

具体来说我下载的离线数据在这里:https://dumps.wikimedia.org/other/static_html_dumps/current/zh/

其中html.lst文件列举了所有文件名,wikipedia-zh-html.tar.7z文件就是实际的数据集,解压后11G,最棒的是解压后发现居然已经帮我把trie树建出来了!

但是,问题来了,虽然在个人的mac上面文件名非常正常,但是把它弄到ubuntu下面就完全不可看,大概就是一堆问号的情况。事实上这只是ssh上去的显示问题,还是可以用程序访问的。

不过速度嘛……

[Pikapika]科技文献的脉络梳理-概述

离散大作业我和wxz希望能够做一个科技文献的脉络梳理的小程序,输入一篇科技文献(可以是html或者纯文本),通过关键词查询等方式实现文献脉络的整理。

其中我们计划的是通过pagerank算法,引入wiki外部语料库建模,提取出科技文献的脉络。

实际上,由于效率的问题,我们并没有使用wiki外部资料库,单纯使用了pagerank。

而demo的展示通过网页实现:http://pikapika.mhy12345.xyz:3000,不过我并不准备长时间维护这个网站,所以说上不去很正常……