2019-01-18 12:36:44

新的硬件?

居然这么久没更新了。从上次因为感受到了cuda的威力,想等新硬件而暂停开发以来,过了2年了。

一开始因为既然已经几个月没更新了,就不更了吧。结果最后拖了2年。

最近半年终于陆陆续续配好了机器,过几周有空更新篇配机记录。

除此之外这段时间也有在各到各处学习各种东西,丰富了domain knowledge,也跟随了下最近的新技术,还顺便把日语N1等级考了下(玩玩。

既然配好了机器,下面开发再开。


量化投资, 程序开发, 日常
2017-01-23 23:47:46

在Windows下安装支持GPU的TensorFlow

以前TensorFlow在Windows下安装要用Docker,麻烦不说, 最关键是不支持用GPU,用GPU快非常多

如果你喜欢玩游戏的话,那么太好了,正好有显卡可以帮你加速。 但是玩游戏系统肯定是Windows啊,所以要么浪费显卡要么重启切换系统。

现在不用了,可以在Python3.5下直接Windows里安装,完美。

阅读更多...
程序开发
2016-12-21 09:25:40

后来使用协程优化了下cuda的回测,让cuda和cpu并行,但提升不明显,果然只用单核的话cpu还是瓶颈,只能想办法利用多核了。

由于我比较讨厌线程锁之类的东西,所以一直以来结构是多进程的。但cuda用多进程运行太麻烦,要linux下开MPS服务,不得已开始着手修改成多线程方式。

之后c++11下面多线程开发意外的顺手,没几步就搞定了,还只用了3个锁,主要得益于thread_local说明符和barrier机制,完成后测试下来虽然一年的回测时间快了1倍到了0.025秒,可以25秒测1000次,但gpu利用率还是没用满。

这之后应该还能优化,可惜windows下工具不全,测不出哪里的问题,我不打算继续弄了,等买gtx1080后再说吧。


程序开发, 量化投资
2016-12-16 08:20:23

Linux 4.9内核的bbr好爽啊

代理服务器升到了Linux 4.9内核,开启google的bbr算法, 上啥国外网站都是满速啦,真是太棒了。

大致记录下安装过程。

阅读更多...
程序开发, 日常
2016-12-16 00:09:16

优化了我好几天,现在1年回测速度从0.4秒提高到了0.04秒,这才像样,但gpu占用率还是有空一半,应该还有些优化余地。

之前主要0.3秒的消耗都在cpu对结果排序上面,现在把排序也移到了cuda中进行。 本来觉得少量的排序移到cuda中也不会有什么改进,但实际效果还是超出预期了。

最后结果看下来cuda的计算中,反而排序占计算量第一了,其次是显存内存间copy的消耗,最后才是信号的计算消耗。不过即便如此还是比cpu快了30倍。而且越复杂的信号,提升的倍数越多。

Lua和c结合做这些真的是非常流畅,接下去尝试用Lua的协程和cuda的异步结合,让gpu计算时cpu也同时做工作。

然而cuda这么给力,导致我以前写的东西可能需要进行重构,我打算借这个机会,休息一段时间,学习学习新东西,再继续开动,正好用来等新设备更新。


程序开发, 量化投资
2016-12-08 07:29:25

使用cuda计算的回测系统已写完,比想象中的工作量要少,得益于原来结构灵活。

目前还没优化,执行沪深所有1年的回测0.4秒,原本是单核1.2秒,已经提升了3倍。但我的24核服务器跑是0.2秒,和多核还是没法比。

性能方面还有问题,现在如果同时执行多个回测时,gpu经常要等cpu完成工作,导致gpu占用率10%不到。这方面得想办法, 先让cpu的工作尽可能提升效率,减少gpu的调用间隔;如果还不行要开多进程来进行cpu的工作,这是代码量最多的。

老实说有点麻烦的是,因为装gpu的电脑为了玩游戏是windows的,不高兴再去装Linux双系统切换,我也没gpu直通的虚拟机,这代码只能windows中运行了,很多Linux的调试工具将无法使用。

只有攒一台专门的gpu服务器了,但是现在攒还不划算,cpu还是老样子没什么进步,得等AMD的zen出来,Intel才会挤牙膏挤出新的cpu,等吧。


程序开发, 量化投资
2016-11-26 19:38:01

cuda 8.0正式版之前发布了,这周从玩游戏中抽空搭出来了基本的框架。

由于做游戏的时候已熟练使用shader,虽然cuda没用过,但很快上手了,写出来测了下有种确实能加速不少的预感?

#!/bin/sh
C:\>test_cuda.exe
GPU Device 0: "GeForce GTX 970" with compute capability 5.2

CUDA device [GeForce GTX 970]
  CUDA Capability Major/Minor version number:    5.2
  Total amount of global memory:                 3383/4096 MBytes (4294967296 bytes)
  (13) Multiprocessors, (128) CUDA Cores/MP:     1664 CUDA Cores
  GPU Max Clock rate:                            1253 MHz (1.25 GHz)
  Memory Clock rate:                             3505 Mhz
  Memory Bus Width:                              256-bit
  Memory Bandwidth:                              224.32 (GB/sec)

start copy data...
Added 409396 datas,  Total amount of global memory:                 3373/4096 MBytes
copy used time: 0.022
exec 409496 times float add: used time: 0.085
start clean cuda memory 0....
start clean cuda memory 1....
start clean cuda memory 2....

40w个float数据做加法总共0.1秒完成,包括发起进程,以及计算结果复制到内存。这么看的话ma计算时间非常值得期待,比之前能快多少呢?过几天写完它看看。 虽然用shader的时候就知道gpu计算能力很强,但shader那些东西本来就不会在cpu中计算,所以缺少比较没有直接的观感。

另外要抱怨在windows下这sdk有点难用,不知道是我的用法问题还是他的bug,thrust的vector各种工作不正常。

比如debug下调用device_vector::insert会报一堆警告,release没有,有点莫名。这还算好的。 再来是调用device_vector::resize会直接nsight跳出exception,妈蛋我还什么都没做呢?而且还看不到到底是什么异常。

最后放弃thrust的vector,全部cudamemcpy,神清气爽,不仅各种问题没了,代码也简洁了,有种蛋疼我之前在干嘛的感觉。

EDIT: 好吧,我把所有选项试下来知道resize报异常的原因了: 因为我在编译中加了 --default-stream per-thread ,去掉就好了。 但不知道为什么,因为我的代码有显示同步,不应该因为异步的原因异常。


程序开发
2016-10-20 12:03:32

这个博客程序是我基于一个微型Blog系统示例 LuaWeb(github) 改的。

他的设计是每次提交markdown文件到git时,通过git钩子把markdown信息写入redis,然后网页每次从redis里取出博客日志, 显示出来。通过git代替后台管理系统的想法不错,我喜欢,就拿来改了。

我改成了git钩子放在服务器上,而不是本地执行。加了discqus评论功能,加了翻页功能,加了tag,加了样式等等自己用。

markdown是一种可以转换成html的文本格式,他文本的可读性和转成html的可读性近似,写起来很方便。 然后给网页加上hljs来显示代码高亮,这样就完美了。

不过我是前端外行,所以网页部分都是乱写的。


程序开发
2016-06-09 09:59:51

之前为玩游戏配的GTX970显卡,虽然玩游戏是用上了,但平日gpu一直闲着,这么大的计算力一直闲着,岂不是很浪费,想要利用上。

最近1080显卡问世,跑分比970要高1倍,打算入手,由此不得不先着手解决这更大的计算力利用不上的问题,不然买来只玩游戏浪费啊(更需要借口告诉我没乱花钱)。

一直在考虑如何把核心的公式系统移植到cuda进行并行计算,虽然现在已经能利用多核cpu并行的跑,但cpu的特点是延迟低而不是计算力,大概比较的话,gpu的计算能力要高40-100倍。不然怎么每秒渲染60帧图像呢。 但我这里移植并行计算会牵涉到最大的问题:

数据源不能直接使用,因为金融产品的数据有复权问题,而且需要用定点复权功能来避免前视偏差,不然你会很惨, 所以每算一列数据(时间)之前的数据都会变化。

这等于本来可以按行和列直接进行并行计算,但现在只能按行进行,列则一个个计算,预计性能会下降不少。 还有些空间换时间的方法,不知道显存是否够用,还要实际写时计算下。

另外正好cuda 8.0 rc刚刚推出了,说支持vs2015了,果断下了装上。一编译,坑爹啊!vs2015 update2 不支持!


程序开发, 量化投资
2016-06-09 03:53:12

试了下Win10内嵌的Ubuntu

一直没更新,玩了一年的游戏,大脑非常满足。特别是坎巴拉太空计划,虽然对于宇宙理论知识都有,但玩了后对太空直观的感受依然很颠覆。

最近装了Win10 Insider版,为了WSL(Windows Subsystem for Linux),试了下,非常赞,cygwin可以扔了。

WSL等于在windows中内嵌了一个ubuntu,但不是虚拟机而是本机。本机意味着,你在WSL里开了www服务器,可以直接chrome里用localhost连接上,方便多了。

更吊的是,WSL是直接运行linux的ELF格式的可执行文件,所以apt-get也能正常工作,你linux里编译的二进制也可以直接拿来WSL用。

阅读更多...
程序开发
2016-06-09 03:45:24

在windows下用WSL编译运行openresty

EDIT: 之前写了篇如何在cygwin下编译openresty,但现在没必要了,所以有了这篇如何用Bash on Windows编译。

如果你的开发机是windows,想要用openresty的话,你需要在windows下编译openresty。cygwin编译会遇到各种问题,启动也不方便,现在我们可以用Bash on Windows(Windows Subsystem for Linux)来做的更好。

阅读更多...
程序开发
2015-09-01 14:20:22

之前纯Lua写的试下来,还是不满意效率,最终还是拿起了c语言,先重写了核心数据部分。

Lua主要慢在hash表上,因为它所有结构都是hash表,除非你用数组。

这导致如果考虑效率就不能保存复杂的结构,而我为了效率,很多地方强行用了数组,代码就丑陋了。

实在忍不下去了打算用c语言,但是就算c语言内部很快,一旦要从lua调用,调用上依然会消耗很多cpu时间,导致效率还是很低。

好在luajit有FFI这个东西,用c写了测试代码然后用FFI结合,试了试看效率果然提升很多,抛弃纯Lua的理念,用c重写核心。

FFI调用C的数据测试下来几乎没有损失,而且我可以通过ffi直接返回c指针给lua,然后lua可以直接调用和操作指针,效率一下子就上来了。 这种效率让我能在Lua里用共享内存的指针了,多个lua间共享这一份数据,这样多进程计算时也能不增加内存消耗,实在是美妙。

现在初步效果是:之前的2000个商品MA100计算,耗时0.006秒。


程序开发
2015-04-23 13:49:24

果然厕所可以帮助人回忆和思考,想到了一种方法,忙了一晚上做完,优化了近一倍速度。

不再直接用io读取数据库文件,而是采用memory mapped file,取文件其中一段要读取的区域直接映射到内存,并设为共享,供各个进程使用。 这个方法和文件一样,不会增加内存用量,但速度确实提升了,讨厌的fseek在瓶颈列表上再也看不到了。 只有50行C代码和50行Lua代码,使用boost的file_mapping和mapped_region。

root@ubuntu:~# ./luajitrun.sh testma100.lua
0.234   sec
0.257   sec
0.249   sec

接下去应该只能靠cache继续加速了,试了下用cache能达到0.002秒,内存是快不过对大容量的数据库不适合...


程序开发
2015-04-22 09:12:20

失败,纠结了一段时间,发现MA100执行0.5秒的效率没有超乎要求,准确的说是要求又提高了。

算了下,起码要0.01秒以下,为达到这个目标,可能到时候还是要动用cache,实在不行我就要用c语言来重写了, 希望不要到这一步。

我估计如果让机器学习策略,按我的理想一个指标耗时0.01秒,那么意味着20核,初步学习最少也要算5天。 如果算上其他消耗就不止了....丫的,5天也不行,我怎么也要把这时间降到1天内。目前还没有头绪怎么做到, 现在在结构化上损失的性能太多了,如果我写死代码,估计能达到这个目标,但要写成易于扩展的,结构化的,就有很多损失了。

最近在疯狂的打GTA5和Diablo3,但因为这事一直在心头,结果玩游戏都玩的不爽,真不爽。

期间还想到了偷懒用弱缩放,提高cpu核心来解决的,我给自己定的目标是云服务器最高不要买超过200核,因为资金有限。 但和金融企业比我肯定资金上比不过,所以还是得优化,然后用少量的钱达到超过他们的计算力。


程序开发
2015-04-10 05:14:06

今天终于完成了数据库部分,这个数据库是完全自己设计的,纯Lua实现。

不通过网络而是直接文件读取,当文件有修改时也能直接立即的更新。

整个数据库打开后占用内存10M,2000个商品10年1分钟级的价格数据106G磁盘空间(随机填充的)。 所有商品算一遍任一个时间点的MA100,也就是以时间为索引,纯磁盘获取2300*100条数据,单核耗时0.6秒,完全超乎要求了。

目前返回结构化数据用了10%时间,磁盘读取用了23%时间,磁盘数据解析10%,内存申请15%,其他GC相关用了30%左右时间。 另外第一版代码耗时是1.8-2.5秒,原因是因为内建的LRU,本来想LRU来提高速度,结果发现对于这种大量的小数据来说,LRU去掉更快。

做到这个速度意味着我可以无视内存了。

root@ubuntu:~# ./luajitrun.sh testma100.lua
0.55863 sec
0.5293  sec
0.634713        sec

这个数据库做的最累的就是索引,和索引的实时更新了。整个索引不用全部读入内存,直接动态的红黑树只读需要的单项。

占用内存做的那么小还是考虑到灵活性,因为现在各家云便宜的cpu不少,但内存则相对较贵。 少量的内存意味着我可以在需要时开一堆低配的服务器进行计算,价格也能达到最低。

下面开始做数据统计测试的界面了。


程序开发, 量化投资
2015-04-04 06:12:47

Lua把数字以二进制方式写入文件并读取

我在用Lua实现自己的数据库时,有个需求是把数字以二进制的方式写入文件并读取,因为转换成文本即浪费储存空间,又不高效。 但是lua 5.1没有原生的方法来实现此需求,也没有原生的位操作(Luajit有)。5.3原生Lua有了string.pack,但碍于还没有luajit暂不考虑。

虽然也可以自己用c写一个库,更完美和高效,但这种小东西能用纯lua实现的话最好,毕竟不同的设备编译一下c代码挺烦的。 简单第一灵活第二,用纯lua实现就两样都占了。

那为什么不用Luajit的位操作?因为不一定所有时候都能用Luajit,还是必须考虑灵活性。

网上搜了下看看有没有人已经做了,结果不是不全就是有各种bug,因此自己改写了下,支持带符号(负数)的整形,以及double浮点数。 其他程序如C也可以直接读取到内存,不过要注意下字节顺序。

阅读更多...
程序开发
2015-03-14 09:48:57

openresty lua_code_cache 文档中文

看兴趣时不时翻译些openresty的主要功能的文档

lua_code_cache

语法: *lua_code_cache on | off*

默认值: *lua_code_cache on*

可用在上下文: http, server, location, location if

阅读更多...
程序开发
2015-03-12 00:55:03

Openresty介绍和架设记录

Openresty是一个http服务器端包和环境,可以用lua写基于http的程序。 我们的手游服务器就是完全基于Openresty的, 用下来1核1G的服务器至少支撑2000人在线。

金融行业内部的系统并不需要写成http应用,理论上直接用Luajit就行了,但我为了更方便的和各种网络结合, 比如抓取网页数据和消息、直观的显示统计后的分析图表、通过网页方便我在任何地方操作,等等。因此决定一开始就基于http写了。

Openresty是我在游戏开发过程中已经非常熟悉的东西了,速度快,http相关的功能也很到位。

Ubuntu架设记录,安装openresty:

阅读更多...
程序开发, 量化投资, 自动交易
2015-03-11 17:30:18

记录下Redis服务器在Ubuntu的架设,官方文档已经写的很全,所以这只是根据我自己需求做的一键shell。

#!/bin/bash
#编译redis
wget http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make

#生成必要的目录和复制过去配置文件
sudo cp src/redis-server /usr/local/bin/
sudo cp src/redis-cli /usr/local/bin/
sudo mkdir /etc/redis
sudo mkdir /var/redis
sudo cp utils/redis_init_script /etc/init.d/redis_6379
sudo cp redis.conf /etc/redis/6379.conf
sudo mkdir /var/redis/6379

#改下配置文件
sudo vi /etc/redis/6379.conf
#把daemonize设为yes
sudo sed -i 's/daemonize no/daemonize yes/g' /etc/redis/6379.conf
#把dir设为/var/redis/6379
sudo sed -i 's/dir .\//dir \/var\/redis\/6379/g' /etc/redis/6379.conf
#有需要的话还要改bind的ip

#设置为开机自动启动
sudo update-rc.d redis_6379 defaults

搞定,最后别忘记添加 vm.overcommit_memory = 1 到 /etc/sysctl.conf 并重启,可以让数据库申请更多内存。


程序开发
2015-03-11 13:08:53

Lua 开发环境对比

研究了下Lua的开发工具,之前一直使用的是文本编辑器+高亮,或idea加lua插件。

后来得知了eclipse官方开发了一个lua IDE叫LDT,看上去这个官方的非常顺手:

阅读更多...
程序开发, 量化投资
2015-03-11 12:49:27

今天找了台服务器建立一个代码Git版本库,用于存放自己的所有工作文件,作为开发前的首要准备工作。

你肯定不希望你的代码没有备份丢失,版本库可以帮你; 你会喜欢上能清楚地看到每次改了些什么,随时回退; 最后你的代码可以自动部署,写完了你的自动交易系统就用新版本工作了,多美好!

最后别忘记给服务器磁盘加密,你不会希望机房人员能查看到你工作成果的。

架设Git服务器端的命令:

#!/bin/bash
#添加git用户
sudo adduser git
ssh-copy-id user@host
#加密磁盘,执行后会问你要密码,先输入git用户的账号密码,再输入加密密码,之后只要
#每次重启后登陆下git用户就自动加载加密磁盘了
ecryptfs-setup-private -u git --noautoumount
sudo chown -R git:git /home/git/Private
sudo chown -R git:git /home/git/.Private
sudo chown -R git:git /home/git/.ecryptfs

#开设git库
cd /home/git/Private
sudo git init --bare code.git
sudo chown -R git:git code.git

然后就好了,可以用了,地址是:git@host:/home/git/Private/code.git


程序开发, 量化投资
2015-03-11 08:37:37

近期思考了下怎么开发量化投资系统,打算先开发出有效的统计系统,然后再研究程序自动交易, 因为自动交易肯定是难度最低的,而找出有效的交易模式是最不确定的。不过自动交易开发最有成就感,时刻勾引着我去开发。

第一个问题,选择什么语言开发?

由于我之前做网络游戏的全栈开发,接触过的也许和金融相关的知识:大规模高并发的处理、数据库开发、NPC行为树、决策机制、tcp/网络、概率,统计,线代。

不知道金融行业普遍的技术水品怎么样,不过一直作为IT业内技术领先的游戏行业,在技术开发上优于金融业还是有信心的。

客户端网络游戏大都使用C、C++作为主要开发语言,用Lua作为配置语言,或黏合C代码。但我打算完全使用LuaJit。

Lua是一种脚本语言,但是非常轻量,因此执行也非常快。Lua本身编译后只有20K,只有lua.exe和lua.dll两个文件。 和Lua相比所有其他语言都显得很笨重(特别是某些J开头的语言)。简单还带来很多好处,像学习成本低(我们都是让游戏策划写Lua的,可想而知)。

但如果因此你把Lua当作玩具就错了,Lua的语法很优雅,有Lisp的感觉,所以Torch才会那么的简洁; 更重要的是有LuaJIT这个实现,本身就很快了,有了它,使Lua变成了最快的脚本语言,没有之一,因为基本上是C级别的效率了。

Lua真的有公司作为核心使用么?国外早就开始使用Lua作为整个服务器端的主要语言,而不再是粘合或配置使用,其中我估计暴雪Wow就是。 我们自己从2009年开始就使用Lua作为服务器端的主要语言(超过95%),之后几年连客户端Lua代码也超过80%了。 我确定11年游戏业都还没这么超前, 因为那年和盛大合作时,问过他们都表示没不敢用动态语言写游戏服务器。大概14年后,很多公司开始转为用动态语言写游戏服务器了, 而且追求性能的游戏人们,首选果然就是Lua了。

总结下,为什么选择LuaJit? 因为:

  • 代码执行速度快,C级别,Lua的诞生有一部分就是故意针对Python的低效
  • 通过工具可以很简单的发现代码效率问题点,优化非常有效,速度更快
  • 可直接用ffi几乎无损性能的黏合C库,不用做额外工作
  • 代码优雅,调试方便,时间节约

基本上所有原因都是效率,有人说没必要那么讲究效率,那只是你没尝过效率的好处。 如果你有足够的计算力,可以直接无脑用大量计算碾压其他的那些量化系统,所以计算力就是一切! 再加上可以自己写cuda库,我目标是自己写的能达到业内最高的速度。

至少金融行业会越来越需要效率,而低效率闻名的Python只是在拖后腿而已。 举个例子,经常拿来比较的2500万次3*log(x) + cos(x) ^ 2计算,我电脑上python是15秒,纯Lua是6秒,而LuaJIT是0.76秒。从python里调用c库执行都要1.7秒。 虽说需要性能的地方你可以用c库来解决,但你冷不丁一个小地方就要用C库的感觉是什么?用了C库结果速度还没LuaJIT快的感觉是什么?不是吃屎是什么?用LuaJIT你可以真正只关心核心功能的效率。 20-30倍啊,科学栈多又怎么样?和这些相比,自己一个个重写根本不是事,反正用到的也就几个,只写自己需要的就行了。

你看到的这个博客就是Lua开发的。

然后是第二个问题,数据怎么处理?是否要用数据库?

考虑到分析是最重要的,对于分析系统我打算完全自己开发一套定制的数据库,以不用全部读到内存,并最大化速度为目标。 虽然以天为单位,这个可以简单的全部读到内存,然后处理。但我打算要能够处理以分钟为单位的数据。 记得哪个大牛说过最好的数据库就是定制的数据库。

数据源方面,国内我是用券商的FTP数据源;国外则是券商提供了获取的API。

分析系统以外的部分使用Redis,绝不使用糟糕的sql。这也是游戏行业的习惯。

Redis本身就是内存数据库,但相比直接内存读取,读取数据库还是要经过网络传输,慢几千倍(参考 每个程序员都应该知道的延迟数)。 所以数据库更多的作用是持久化,等到自动交易系统开发时,自动交易系统自己的数据用Redis来储存。

这么看来网络游戏行业还真是领先其他行业至少10年啊,在nosql概念还没出来前,网络游戏就讨厌sql尽量不用。在大家还 在用早期apache那种1连接1线程模式时,网络游戏就已遇到大量用户导致的c10k问题,普及epoll或iocp了。 最近lua又普及到人工智能行业了,不知道游戏行业最先喜爱的Lua是否能在将来带到所有其他行业去。


程序开发, 量化投资