字符串查找是信息安全、信息过滤领域的重要操作,尤其是对大文本的实时处理。这篇作为实例,使用GPU OpenCL进行精确模式串查找。

1.加速方法

  (1)将少量常量数据,如模式串长度、文本长度等,保存在线程的private memory中。

  (2)将模式串保存在GPU的local memory中,加速线程对模式串的访问。

  (3)将待查找的文本保存在global memory中,使用尽可能多线程访问global memory,减小线程平均访存时间。

  (4)每个work-group中的线程操作文本中一段,多个work-group并行处理大文本。

2.同步

  (1)work-group内,使用CLK_LOCAL_MEM_FENCE、CLK_GLOBAL_MEM_FENCE

  (2)全局使用对__global int 的原子操作,来保证每个线程将结果写到全局内存的正确位置。设备支持的操作可以通过查询设备的扩展获得,如下图,可知核函数支持原子操作、printf操作:

  

3.代码实例,大文本精确模式串搜索

3.1 核函数(string_search_kernel.cl):

 int compare(__global const uchar* text, __local const uchar* pattern, uint length){
for(uint l=; l<length; ++l){
if (text[l] != pattern[l])
return ;
}
return ;
} __kernel void
StringSearch (
__global uchar* text, //Input Text
const uint textLength, //Length of the text
__global const uchar* pattern, //Pattern string
const uint patternLength, //Pattern length
const uint maxSearchLength, //Maximum search positions for each work-group
__global int* resultCount, //Result counts (global)
__global int* resultBuffer, //Save the match result
__local uchar* localPattern) //local buffer for the search pattern
{ int localIdx = get_local_id();
int localSize = get_local_size();
int groupIdx = get_group_id(); uint lastSearchIdx = textLength - patternLength + ;
uint beginSearchIdx = groupIdx * maxSearchLength;
uint endSearchIdx = beginSearchIdx + maxSearchLength;
if(beginSearchIdx > lastSearchIdx)
return;
if(endSearchIdx > lastSearchIdx)
endSearchIdx = lastSearchIdx; for(int idx = localIdx; idx < patternLength; idx+=localSize)
localPattern[idx] = pattern[idx];
barrier(CLK_LOCAL_MEM_FENCE); for(uint stringPos=beginSearchIdx+localIdx; stringPos<endSearchIdx; stringPos+=localSize){
if (compare(text+stringPos, localPattern, patternLength) == ){
int count = atomic_inc(resultCount);
resultBuffer[count] = stringPos;
//printf("%d ",stringPos);
}
barrier(CLK_LOCAL_MEM_FENCE);
}
}

3.2.tool.h 、tool.cpp

见:http://www.cnblogs.com/xudong-bupt/p/3582780.html

3.3 StringSearch.cpp

 #include <CL/cl.h>
#include "tool.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <fstream>
using namespace std; int main(int argc, char* argv[])
{
cl_int status;
/**Step 1: Getting platforms and choose an available one(first).*/
cl_platform_id platform;
getPlatform(platform); /**Step 2:Query the platform and choose the first GPU device if has one.*/
cl_device_id *devices=getCl_device_id(platform); /**Step 3: Create context.*/
cl_context context = clCreateContext(NULL,, devices,NULL,NULL,NULL); /**Step 4: Creating command queue associate with the context.*/
cl_command_queue commandQueue = clCreateCommandQueue(context, devices[], , NULL); /**Step 5: Create program object */
const char *filename = "string_search_kernel.cl";
string sourceStr;
status = convertToString(filename, sourceStr);
const char *source = sourceStr.c_str();
size_t sourceSize[] = {strlen(source)};
cl_program program = clCreateProgramWithSource(context, , &source, sourceSize, NULL); /**Step 6: Build program. */
status=clBuildProgram(program, ,devices,NULL,NULL,NULL); /**Step 7: Initial input,output for the host and create memory objects for the kernel*/
string textStr; //StringSearch_Input.txt
convertToString("StringSearch_Input.txt", textStr);
const char * text = textStr.c_str();
int textlen=strlen(text); char * pattern="info";
int patternlen=strlen(pattern);
int maxSearchLength=*;
int * resultCount=new int[];
*resultCount=;
int * result=new int[textlen];
memset(result,,sizeof(int)*textlen); cl_mem textBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(char)*textlen,(void *)text, NULL); //global memory
cl_mem patternBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_COPY_HOST_PTR ,sizeof(char)*patternlen, (void *)pattern, NULL);
cl_mem resultCountBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_COPY_HOST_PTR ,sizeof(int), (void *)resultCount, NULL);
cl_mem resultBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_COPY_HOST_PTR ,sizeof(int)*textlen, (void *)result, NULL); /**Step 8: Create kernel object */
cl_kernel kernel = clCreateKernel(program,"StringSearch", NULL); /**Step 9: Sets Kernel arguments.*/
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void *)&textBuffer); //global
status = clSetKernelArg(kernel, , sizeof(int), &textlen); //private
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void *)&patternBuffer); //global
status = clSetKernelArg(kernel, , sizeof(int), &patternlen); //private
status = clSetKernelArg(kernel, , sizeof(int), &maxSearchLength); //private
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void *)&resultCountBuffer); //global
status = clSetKernelArg(kernel, , sizeof(cl_mem), (void *)&resultBuffer); //global
status = clSetKernelArg(kernel, , sizeof(char)*patternlen, NULL); //local /**Step 10: Running the kernel.*/
cl_event enentPoint;
int globalWorkItem=textlen/; if(textlen% != )
globalWorkItem++;
size_t groupNUm[]={globalWorkItem};
size_t localNUm[]={}; status = clEnqueueNDRangeKernel(commandQueue, kernel, , NULL, groupNUm, localNUm, , NULL, &enentPoint); clWaitForEvents(,&enentPoint); ///wait
clReleaseEvent(enentPoint);
int count=;
status = clEnqueueReadBuffer(commandQueue, resultCountBuffer, CL_TRUE, , sizeof(int), &count, , NULL, NULL);
cout<<"\nNumber of matches:"<<count<<endl; /**Step 12: Clean the resources.*/
status = clReleaseKernel(kernel);//*Release kernel.
status = clReleaseProgram(program); //Release the program object.
status = clReleaseMemObject(resultBuffer);//Release mem object.
status = clReleaseMemObject(textBuffer);//Release mem object.
status = clReleaseMemObject(resultCountBuffer);//Release mem object.
status = clReleaseMemObject(patternBuffer);//Release mem object.
status = clReleaseCommandQueue(commandQueue);//Release Command queue.
status = clReleaseContext(context);//Release context. free(devices);
free(result);
free(resultCount); getchar();
return ;
}

本文:http://www.cnblogs.com/xudong-bupt/p/3627593.html

GPGPU OpenCL 精确字符串查找的更多相关文章

  1. Linux shell】grep命令精确匹配字符串查找

    需求: 精确匹配查找某个字符串   精确匹配: 例如: 在抽取字符串“48”,返回结果包含诸如484和483等包含“48”的其他字符串,实际上应精确抽取只包含48的各行. 使用grep抽取精确匹配的一 ...

  2. vim 精确匹配查找单词【转】

    删除文件中所有的空行:g/^\s*$/d 去掉所有的行尾空格::%s/\s\+$// 整个文件特定字符串的替换:%s/old_word/new_word/g 删除从当前行开始到最后一行的所有内容:., ...

  3. 【并行计算-CUDA开发】GPGPU OpenCL/CUDA 高性能编程的10大注意事项

    GPGPU OpenCL/CUDA 高性能编程的10大注意事项 1.展开循环 如果提前知道了循环的次数,可以进行循环展开,这样省去了循环条件的比较次数.但是同时也不能使得kernel代码太大. 循环展 ...

  4. Rabin-Karp指纹字符串查找算法

    首先计算模式字符串的散列函数, 如果找到一个和模式字符串散列值相同的子字符串, 那么继续验证两者是否匹配. 这个过程等价于将模式保存在一个散列表中, 然后在文本中的所有子字符串查找. 但不需要为散列表 ...

  5. 自己动手写文件查找,字符串查找,查询jar包等工具

    文件查找——搜索当前目录下的文件 知道大概的文件名称,使用 findf FileName findf.py import argparse, re, os from os.path import jo ...

  6. 关于字符串查找 charindex ,Patindex 还有一个like

    字符串查找.在模糊朝找的情况下,其实3者的效率是差不多的.都需要一个一个取出来然后扫一遍╮(╯_╰)╭.然而用法还是会有一点儿的区别 1 charindex (查找的字符串,字符串表达式[,开始查找的 ...

  7. python 字符串查找

    python 字符串查找有4个方法,1 find,2 index方法,3 rfind方法,4 rindex方法. 1 find()方法: )##从下标1开始,查找在字符串里第一个出现的子串:返回结果3 ...

  8. Sunday算法(字符串查找、匹配)

    字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简单的 ...

  9. lintcode:strStr 字符串查找

    题目: 字符串查找 字符串查找(又称查找子字符串),是字符串操作中一个很有用的函数.你的任务是实现这个函数. 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source ...

随机推荐

  1. [实战]MVC5+EF6+MySql企业网盘实战(11)——新建文件夹2

    写在前面 上篇文章实现了创建文件夹的功能,这里面将实现单击文件夹,加载列表的功能. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网 ...

  2. EOJ 3256 拼音魔法

    模拟. 有$a$先标$a$,其次是$o$和$e$,$o$和$e$在韵母中不会同时存在.最后是$u$和$i$,这两个字母在韵母中可能同时存在,标在后面的那个.输出那些字符的话直接输出就可以了. 举几个例 ...

  3. 初识GeneXus产品

    本人由于工作原因接触了GeneXus产品,从使用到现在也有些年头了.从刚开始的不熟悉到现在使用GeneXus开发了很多项目,慢慢也总结了一些经验,当然中间也走了很多的弯路.对于在国内同样使用GeneX ...

  4. 在ASP.NET中实现图片、视频文件上传方式

    一.图片 1.在前端用<asp:FileUpload ID="UpImgName" runat="server"/>控件 2.在后台.cs中写上 p ...

  5. python 异步 select pooll epoll

    概念: 首先列一下,sellect.poll.epoll三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当se ...

  6. java8新特性——Stream API

    Java8中有两大最为重要得改变,其一时Lambda表达式,另外就是 Stream API了.在前面几篇中简单学习了Lambda表达式得语法,以及函数式接口.本文就来简单学习一下Stream API( ...

  7. 【BZOJ 4103】 4103: [Thu Summer Camp 2015]异或运算 (可持久化Trie)

    4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 474  Solved: 258 De ...

  8. Codeforces Beta Round #4 (Div. 2 Only) B. Before an Exam dp

    B. Before an Exam 题目连接: http://www.codeforces.com/contest/4/problem/B Description Tomorrow Peter has ...

  9. Octopress + GitHub Page 搭建个人博客

    Tips:博客已搬家,新地址:http://wanxudong.top 首先说明两个关键术语: Octopress Octopress是基于 Jekyll 的博客框架.他们的关系就像 jQuery 与 ...

  10. vue获取当前v-for里当前点击元素

    app.vue <template> <div id="app"> <ul > <li v-for="(item,index) ...