This commit is contained in:
Zengtudor 2024-09-20 00:28:03 +08:00
parent d978da9ac0
commit 83808fc6b4
2 changed files with 35 additions and 30 deletions

View File

@ -1,10 +1,41 @@
#include "dna.hpp" #include "dna.hpp"
void reverseComplement(char *begin, char *end)
{
//注意end是开区间不能访问end
static const std::unordered_map<char, char> complement = { //这里使用查表的方式大大提高CPU速度因为if分支CPU不容易命中缓存需要使用查表加速
{'A', 'T'}, {'a', 'T'},
{'T', 'A'}, {'t', 'A'},
{'C', 'G'}, {'c', 'G'},
{'G', 'C'}, {'g', 'C'}
};
// std::reverse(begin, end); //翻转DNA序列
// 并行翻转序列 //似乎没用
#pragma omp parallel for
for (ptrdiff_t i = 0; i < (end - begin) / 2; ++i) {
std::swap(begin[i], begin[(end - begin) - i - 1]);
}
// 并行查表替换
#pragma omp parallel for
for (ptrdiff_t i = 0; i < (end - begin); ++i) {
static int _ = (zt::print(NAME_VALUE(omp_get_num_threads()),"\n"),0); // 打印线程数量
auto it = complement.find(begin[i]);
if (it != complement.end()) {
begin[i] = it->second;
}
}
}
int main() int main()
{ {
try{ try{
//参数列表 <文件分块大小单个DNA序列最长大小>("输入文件名",输出文件名); //原理是这里定义处理函数将函数传入open_file_and_calculate在open_file_and_calculate中会调用传入的函数
dna::open_file_and_calculate<(size_t)4 * 1024 * 1024 *1024,(size_t)5e4+5>("filteredReads.txt", "reversedSequence.txt");
//参数列表 <文件分块大小单个DNA序列最长大小>("输入文件名","输出文件名",序列处理函数);
//这个函数在src/tools/dna里面
dna::open_file_and_calculate<(size_t)4 * 1024 * 1024 *1024,(size_t)5e4+5>("filteredReads.txt", "reversedSequence.txt",reverseComplement);
}catch(const std::exception &e){ }catch(const std::exception &e){
zt::eprint( zt::eprint(

View File

@ -3,6 +3,7 @@
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
#include <fstream> #include <fstream>
#include <functional>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
@ -27,33 +28,6 @@ namespace dna {
//最大DNA序列长度 //最大DNA序列长度
// const size_t MAX_SIZE_PER_DNA = 5e4+5; // const size_t MAX_SIZE_PER_DNA = 5e4+5;
// //
inline void reverseComplement(char *begin, char *end)
{
//注意end是开区间不能访问end
static const std::unordered_map<char, char> complement = { //这里使用查表的方式大大提高CPU速度因为if分支CPU不容易命中缓存需要使用查表加速
{'A', 'T'}, {'a', 'T'},
{'T', 'A'}, {'t', 'A'},
{'C', 'G'}, {'c', 'G'},
{'G', 'C'}, {'g', 'C'}
};
// std::reverse(begin, end); //翻转DNA序列
// 并行翻转序列 //似乎没用
#pragma omp parallel for
for (ptrdiff_t i = 0; i < (end - begin) / 2; ++i) {
std::swap(begin[i], begin[(end - begin) - i - 1]);
}
// 并行查表替换
#pragma omp parallel for
for (ptrdiff_t i = 0; i < (end - begin); ++i) {
static int _ = (zt::print(NAME_VALUE(omp_get_num_threads()),"\n"),0); // 打印线程数量
auto it = complement.find(begin[i]);
if (it != complement.end()) {
begin[i] = it->second;
}
}
}
class Spent{ // 使用RAII原理的自动计时器计算主函数运行时间析构时自动输出 class Spent{ // 使用RAII原理的自动计时器计算主函数运行时间析构时自动输出
@ -72,7 +46,7 @@ namespace dna {
}; };
template<size_t BUF_SIZE = (size_t)4 * 1024 * 1024 *1024 , size_t MAX_SIZE_PER_DNA = (size_t)5e4+5> template<size_t BUF_SIZE = (size_t)4 * 1024 * 1024 *1024 , size_t MAX_SIZE_PER_DNA = (size_t)5e4+5>
inline void open_file_and_calculate(std::filesystem::path input_path,std::filesystem::path output_path){ inline void open_file_and_calculate(std::filesystem::path input_path,std::filesystem::path output_path,void (*reverseComplement)(char *begin, char *end)){
//std::ios_base::sync_with_stdio(false); //加了没效果 //这里直接关掉就行了,不会影响读入,因为目前是一次性读入。开了反而会让日志输出变成全缓冲,不友好 //std::ios_base::sync_with_stdio(false); //加了没效果 //这里直接关掉就行了,不会影响读入,因为目前是一次性读入。开了反而会让日志输出变成全缓冲,不友好
// using namespace std; // 别加,刚被坑了 // using namespace std; // 别加,刚被坑了