B+树 BulkLoading 多核并行设计

目录
数据库系统课程设计报告 1
B+树 BulkLoading 多核并行设计 1
Ⅰ . B+树 BulkLoading 过程理解 1
1.1 BulkLoading 的基本思想 1
1.2 结合实现理解 BulkLoading 1
1.3 BulkLoading 的利弊 2
Ⅱ . 并行设计思路 3
2.1 基本想法 3
Ⅲ . 算法流程图 4
4.1 连续分配块 5
4.2 连续写磁盘 6
Ⅴ . 关键代码描述 6
5.2 12
Ⅵ . 实验结果分析 28
6.0 并行和性能调优的代码说明 28
6.0.3 如何测试代码 29
6.1 并行实验结果代码及分析 29
6.1.1 影响因素 29
6.1.2 实验方法 29
测试代码 29
6.2 性能调优和创新优化实验结果及分析 36
6.2.1 性能调优的原因 36
6.2.2 数据量的大小 36
6.2.3 线程数 38
6.2.4 Buffer大小 38
1.3BulkLoading 的利弊
相比于通过插入节点构造B+树,BulkLoding充分利用了数据有序的特性,让每一个节点构造过程的 复杂度都为O(1),构造过程中不存在节点的分叉、合并等调整,生成B+树的过程非常快。
通过BulkLoading构造B+树也可能存在潜在的问题:因为每一个节点从左到右都是尽可能填满的, 当需要插入新节点时,B+树结构的变动可能会非常大,会产生较大的时间开销。
或许我们可以加入一个填充因子来控制BulkLoading每次为一个叶子节点填出的数据项的个数,让 叶子节点的数据项不是满的,这样可以减弱插入节点对B+树结构造成的影响。

Ⅱ . 并行设计思路
2.1基本想法
首先,需要思考的问题是在批量加载的哪些步骤可以并行,通过阅读串行代码我们可知,构建B+树 的串行过程大致为:读取数据并在内存中创建一个节点对象存放数据,然后再通过系统函数 fwrite() 将该节点中的数据写入到磁盘中。
我们考虑到,节点数据写到文件的过程由于文件指针的限制无法并行,同一时刻只能有一个线程写 磁盘,因此可以创建内存缓冲区缓冲节点数据,在获取写文件权限后将内存中节点写出。
由于写磁盘的速度低于写内存,BulkLoading 运行速度的瓶颈可能在于写硬盘,因此要充分提高
CPU和磁盘IO的并行度,来减少IO造成的护航效应。
引入互斥锁:由于写硬盘不能并行,因此需要一个互斥锁保证同一时刻只有一个线程能够将已经加 载到内存的节点数据写入硬盘。那么对于其余抢不到锁的线程,我们有三种处理思路:
一个线程在内存中写完一个节点就等待直到获取锁(堵塞);
一个线程在内存中写完所有待处理的节点再争取锁,等待直到获取锁(堵塞);
一个节点每向内存写一个节点就尝试获取锁,本文转载自http://www.biyezuopin.vip/onews.asp?id=16715如果获取失败就将块加入一个队列,如果获取成功就 磁盘写队列内所有的节点(非堵塞)。
我们采取的是类似于第三种思路的并行思路:一个节点每向内存写完 MIN_BLOCK 个节点就尝试获取锁,如果获取失败就将块加入一个长为 MAX_BLOCK 的队列,如果获取成功就磁盘写队列内所有的节点(非堵塞),如果此时队列已满就进入堵塞状态。其中 MIN_BLOCK 和 MAX_BLOCK 是两个可调的参数。
最后,在我们的并行 BulkLoading 过程中,主线程会为每一层创建若干个线程,并且只有一层的所有线程执行完工作后,返回记录线程产生的一批节点键值的数组,才会开始创建上一层的线程。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <string>
#include <set>
#include <fstream>
#include <sstream>#include "def.h"
#include "util.h"
#include "random.h"
#include "pri_queue.h"
#include "b_node.h"
#include "b_tree.h"
#include "evaluate.h"using namespace std;// print B_Tree
void print_B_Tree(BTree *trees_, char *filename)
{FILE *fp;fp = fopen(filename, "w");if (fp == NULL){printf("File can not open!");exit(0);}int start_block = trees_->root_;int end_block = trees_->root_;int newly_startblock;int newly_endblock;BIndexNode *index_child = NULL;// read root nodechar indexnode_level;int indexnode_num_entries;BIndexNode *indexnode_left_sibling;BIndexNode *indexnode_right_sibling;fprintf(fp, "root: block %d\n", start_block);index_child = new BIndexNode();index_child->init_restore(trees_, start_block);indexnode_level = index_child->get_level();indexnode_num_entries = index_child->get_num_entries();indexnode_left_sibling = index_child->get_left_sibling();indexnode_right_sibling = index_child->get_right_sibling();fprintf(fp, "\tlevel: %d \tnum_entries: %d\n", indexnode_level, indexnode_num_entries);for (int j = 0; j < indexnode_num_entries; ++j){fprintf(fp, "\t\tkey: %f\tson: %d\n", index_child->get_key(j), index_child->get_son(j));}start_block = index_child->get_son(0);end_block = index_child->get_son(indexnode_num_entries - 1);delete index_child;index_child = NULL;// index node// from root to the leaf layer to layerwhile (start_block > 1){for (int k = start_block; k <= end_block; k++){fprintf(fp, "index: block %d\n", k);index_child = new BIndexNode();index_child->init_restore(trees_, k);indexnode_level = index_child->get_level();indexnode_num_entries = index_child->get_num_entries();indexnode_left_sibling = index_child->get_left_sibling();indexnode_right_sibling = index_child->get_right_sibling();fprintf(fp, "\tlevel: %d \tnum_entries: %d\n", indexnode_level, indexnode_num_entries);for (int j = 0; j < indexnode_num_entries; ++j){fprintf(fp, "\t\tkey: %f\tson: %d\n", index_child->get_key(j), index_child->get_son(j));}if (k == start_block){newly_startblock = index_child->get_son(0);}if (k == end_block){newly_endblock = index_child->get_son(indexnode_num_entries - 1);}delete index_child;index_child = NULL;} // end for loopstart_block = newly_startblock;end_block = newly_endblock;} // end while// leaf node variableBLeafNode *leaf_child = NULL;// read root nodechar leafnode_level;int leafnode_num_entries;int leafnode_num_keys;BLeafNode *leafnode_left_sibling;BLeafNode *leafnode_right_sibling;// print leaf nodefor (int k = start_block; k <= end_block; k++){fprintf(fp, "leaf: block %d\n", k);leaf_child = new BLeafNode();leaf_child->init_restore(trees_, k);leafnode_level = leaf_child->get_level();leafnode_num_entries = leaf_child->get_num_entries();leafnode_left_sibling = leaf_child->get_left_sibling();leafnode_right_sibling = leaf_child->get_right_sibling();leafnode_num_keys = leaf_child->get_num_keys();fprintf(fp, "\tlevel: %d \tnum_entries: %d\tnum_keys: %d\n", leafnode_level, leafnode_num_entries, leafnode_num_keys);for (int j = 0; j < leafnode_num_keys; ++j){int count_entries = 0;fprintf(fp, "\t\tkey: %f\n", leaf_child->get_key(j));for (int w = count_entries; w < std::min(count_entries + 16, leafnode_num_entries); w++){fprintf(fp, "\t\t\tid: %d\n", leaf_child->get_entry_id(w));}count_entries += 16;}delete leaf_child;leaf_child = NULL;}fclose(fp);
}// -----------------------------------------------------------------------------
int main(int nargs, char **args)
{char data_file[200];char tree_file_ser[200];char tree_file_par[200];int B_ = 512; // node sizeint n_pts_ = 20000000;strncpy(data_file, "./data/dataset.csv", sizeof(data_file));strncpy(tree_file_ser, "./result/B_tree_ser", sizeof(tree_file_ser));strncpy(tree_file_par, "./result/B_tree_par", sizeof(tree_file_par));printf("data_file   = %s\n", data_file);printf("tree_file_ser   = %s\n", tree_file_ser);printf("tree_file_par   = %s\n", tree_file_par);Result *table = new Result[n_pts_];ifstream fp(data_file);string line;int i = 0;while (getline(fp, line) && i <= n_pts_ - 1){string number;istringstream readstr(line);getline(readstr, number, ',');table[i].key_ = atof(number.c_str());getline(readstr, number, ',');table[i].id_ = atoi(number.c_str());i++;}fp.close();timeval start_t;timeval end_t;printf("开始运行,并行线程数:20,内存缓冲大小:500,数据量:%d\n", n_pts_);BTree *trees_ = new BTree();trees_->init(B_, tree_file_ser);gettimeofday(&start_t, NULL);if (trees_->bulkload(n_pts_, table))return 1;gettimeofday(&end_t, NULL);float run_t1 = end_t.tv_sec - start_t.tv_sec +(end_t.tv_usec - start_t.tv_usec) / 1000000.0f;printf("串行运行时间: %f  s\n", run_t1);print_B_Tree(trees_, "./result/ser_res");delete trees_;trees_ = new BTree();trees_->init(B_, tree_file_par);gettimeofday(&start_t, NULL);if (trees_->parallelBulkLoad(n_pts_, table, 20, 500))return 1;gettimeofday(&end_t, NULL);run_t1 = end_t.tv_sec - start_t.tv_sec +(end_t.tv_usec - start_t.tv_usec) / 1000000.0f;printf("并行运行时间: %f  s\n", run_t1);print_B_Tree(trees_, "./result/par_res");if (table != NULL){delete[] table;table = NULL;}char systemCmd[1024];printf("进行结果正确性验证\n");strncpy(systemCmd, "diff ", 1024);strcat(systemCmd, "./result/par_res ");strcat(systemCmd, "./result/ser_res");printf("%s\n", systemCmd);system(systemCmd);printf("开始进行结果测试...\n");// 参数测试// evaluate();return 0;
}














基于C语言的B+树BulkLoading多核并行设计相关推荐

  1. R语言rpartb包树回归模型构建:基于前列腺prostate数据集

    R语言rpartb包树回归模型构建:基于前列腺prostate数据集 决策树是一种机器学习的方法.决策树的生成算法有ID3, C4.5和C5.0等.决策树是一种树形结构,其中每个内部节点表示一个属性上 ...

  2. R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集

    R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集 目录 R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集

  3. 基于Erlang语言的视频相似推荐系统 | 深度

    作者丨gongyouliu 来源 | 转载自大数据与人工智能(ID:ai-big-data) [导语]:作者在上一篇文章<基于内容的推荐算法>中介绍了基于内容的推荐算法的实现原理.在本篇文 ...

  4. 基于Java语言构建区块链(四)—— 交易(UTXO)

    基于Java语言构建区块链(四)-- 交易(UTXO) 2018年03月11日 00:48:01 wangwei_hz 阅读数:909 标签: 区块链比特币 更多 个人分类: 区块链 文章的主要思想和 ...

  5. 基于Java语言构建区块链(六)—— 交易(Merkle Tree)

    基于Java语言构建区块链(六)-- 交易(Merkle Tree) 2018年04月16日 10:21:35 wangwei_hz 阅读数:480更多 个人分类: 区块链比特币bitcoin 最终内 ...

  6. 论文浅尝 - ACL2022 | 基于多语言语义解耦表示的跨语言迁移方法实现多语言阅读理解...

    论文作者:吴林娟,天津大学,研究方向为自然语言理解 论文链接:http://arxiv.org/abs/2204.00996 代码地址:https://github.com/wulinjuan/SSD ...

  7. 基于Go语言实现高并发推荐系统架构设计

    猜你喜欢 0.[免费下载]2021年12月热门报告盘点1.史上最全推荐系统传统算法合集2.推荐系统模型:多场景下的星型CTR预估模型3.新一代Rank技术在阿里巴巴推荐系统中的应用实践4.预训练模型在 ...

  8. 【数据结构(C语言)】数据结构-树

    树 文章目录 树 一.基本概念 1.树的定义 2.树的节点 3.树的性质 4.基本操作 二.二叉树 1.二叉树的特点 2.特殊二叉树 3.性质 4.存储结构 (1)二叉链表 (2)三叉链表 5.线索化 ...

  9. 组件分享之后端组件——基于Golang语言的游戏服务器框架leaf

    组件分享之后端组件--基于Golang语言的游戏服务器框架leaf 背景 近期正在探索前端.后端.系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件专题,后续该专题将包含各类 ...

最新文章

  1. 选什么专业,最容易拿下互联网大厂 Offer?三个支付宝新人来支招
  2. php ssd性能影响,SATA SSD有无缓存,是否影响速度性能实例
  3. 3、MySQL优化数据库结构的3种方法
  4. Linux系统软件信息内核,系统,目录,防火墙等
  5. 突发!Spring 也沦陷了。。。
  6. [atlassian]Bamboo server 和 remote agent 只支持JAVA 1.8
  7. silverlight异常
  8. 白盒测试 | 用例设计方法之条件组合覆盖
  9. 微信小程序-蓝牙设备连接-蓝牙开门
  10. SQL error OCI Error 2003 问题处理
  11. 20162327WJH程序设计与数据结构第七周总结
  12. 推荐两款超高质量的壁纸软件
  13. python输入一个英文句子、统计并输出单词数_C语言实现输入多行英文句子然后统计单词数和行数,如何输入?我的代码问题在哪里?...
  14. 信用卡 3D 认证是怎么回事
  15. 我糟糕的2019年:虽流年不利,但我心仍坚定
  16. HW机试题字符串分割
  17. linux HTB 队列限速
  18. 水滴公司更名为水滴科技集团,王慧文担任监事
  19. 基于51单片机的智能环境监测光强火焰有害气体检测proteus仿真原理图PCB
  20. css 利用阴影给字体加粗

热门文章

  1. FESTO气动阀微型插头
  2. 保存session id的几种方式
  3. linux模糊查找命令,Linux模糊查找文件应该用什么命令比较好?
  4. 乐观锁和悲观锁的底层实现原理
  5. maven安装,使用说明,及maven Repository如何使用.
  6. 行业领先公司和软件系统
  7. 华为手机哪款使用了鸿蒙操作系统,华为正式发布鸿蒙手机操作系统 哪些手机可以使用...
  8. 笔记本电脑连接上WiFi后,弹不出登录界面怎么办?
  9. 一网打尽:Java 程序员必须了解的计算机底层知识!
  10. windows server服务器性能监控