GPGPU OpenCL 精确字符串查找

简介: 字符串查找是信息安全、信息过滤领域的重要操作,尤其是对大文本的实时处理。这篇作为实例,使用GPU OpenCL进行精确模式串查找。 1.加速方法   (1)将少量常量数据,如模式串长度、文本长度等,保存在线程的private memory中。

字符串查找是信息安全、信息过滤领域的重要操作,尤其是对大文本的实时处理。这篇作为实例,使用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):

 1 int compare(__global const uchar* text, __local const uchar* pattern, uint length){
 2     for(uint l=0; l<length; ++l){
 3         if (text[l] != pattern[l]) 
 4         return 0;
 5     }
 6     return 1;
 7 }
 8 
 9 __kernel void
10     StringSearch (
11       __global uchar* text,        //Input Text
12       const uint textLength,        //Length of the text
13       __global const uchar* pattern,    //Pattern string
14       const uint patternLength,        //Pattern length
15       const uint maxSearchLength,    //Maximum search positions for each work-group
16       __global int* resultCount,    //Result counts (global)
17       __global int* resultBuffer,    //Save the match result
18       __local uchar* localPattern)    //local buffer for the search pattern
19 {  
20 
21     int localIdx = get_local_id(0);
22     int localSize = get_local_size(0);
23     int groupIdx = get_group_id(0);
24 
25     uint lastSearchIdx = textLength - patternLength + 1;
26     uint beginSearchIdx = groupIdx * maxSearchLength;
27     uint endSearchIdx = beginSearchIdx + maxSearchLength;
28     if(beginSearchIdx > lastSearchIdx) 
29     return;
30     if(endSearchIdx > lastSearchIdx) 
31     endSearchIdx = lastSearchIdx;
32 
33     for(int idx = localIdx; idx < patternLength; idx+=localSize)
34         localPattern[idx] = pattern[idx];
35     barrier(CLK_LOCAL_MEM_FENCE);
36     
37     for(uint stringPos=beginSearchIdx+localIdx; stringPos<endSearchIdx; stringPos+=localSize){
38     if (compare(text+stringPos, localPattern, patternLength) == 1){
39             int count = atomic_inc(resultCount);
40             resultBuffer[count] = stringPos;
41         //printf("%d ",stringPos);
42         }
43     barrier(CLK_LOCAL_MEM_FENCE);
44     }
45 }

3.2.tool.h 、tool.cpp

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

3.3 StringSearch.cpp

  1 #include <CL/cl.h>
  2 #include "tool.h"
  3 #include <string.h>
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <iostream>
  7 #include <string>
  8 #include <fstream>
  9 using namespace std;
 10 
 11 
 12 int main(int argc, char* argv[])
 13 {
 14     cl_int    status;
 15     /**Step 1: Getting platforms and choose an available one(first).*/
 16     cl_platform_id platform;
 17     getPlatform(platform);
 18 
 19     /**Step 2:Query the platform and choose the first GPU device if has one.*/
 20     cl_device_id *devices=getCl_device_id(platform);
 21 
 22     /**Step 3: Create context.*/
 23     cl_context context = clCreateContext(NULL,1, devices,NULL,NULL,NULL);
 24 
 25     /**Step 4: Creating command queue associate with the context.*/
 26     cl_command_queue commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL);
 27 
 28     /**Step 5: Create program object */
 29     const char *filename = "string_search_kernel.cl";
 30     string sourceStr;
 31     status = convertToString(filename, sourceStr);
 32     const char *source = sourceStr.c_str();
 33     size_t sourceSize[] = {strlen(source)};
 34     cl_program program = clCreateProgramWithSource(context, 1, &source, sourceSize, NULL);
 35 
 36     /**Step 6: Build program. */
 37     status=clBuildProgram(program, 1,devices,NULL,NULL,NULL);
 38 
 39 
 40     /**Step 7: Initial input,output for the host and create memory objects for the kernel*/
 41     string textStr;    //StringSearch_Input.txt
 42     convertToString("StringSearch_Input.txt", textStr);
 43     const char *    text = textStr.c_str();
 44     int        textlen=strlen(text);
 45 
 46     char *    pattern="info";
 47     int        patternlen=strlen(pattern);
 48     int        maxSearchLength=256*64;
 49     int    *    resultCount=new int[1];
 50     *resultCount=0;
 51     int    *    result=new int[textlen];
 52         memset(result,0,sizeof(int)*textlen);
 53 
 54     cl_mem    textBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(char)*textlen,(void *)text, NULL);    //global memory
 55     cl_mem    patternBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_COPY_HOST_PTR ,sizeof(char)*patternlen, (void *)pattern, NULL);
 56     cl_mem    resultCountBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_COPY_HOST_PTR ,sizeof(int), (void *)resultCount, NULL);
 57     cl_mem    resultBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY|CL_MEM_COPY_HOST_PTR ,sizeof(int)*textlen, (void *)result, NULL);
 58 
 59     /**Step 8: Create kernel object */
 60     cl_kernel kernel = clCreateKernel(program,"StringSearch", NULL);
 61 
 62     /**Step 9: Sets Kernel arguments.*/
 63     status = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&textBuffer);    //global
 64     status = clSetKernelArg(kernel, 1, sizeof(int), &textlen);        //private
 65     status = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&patternBuffer);    //global
 66     status = clSetKernelArg(kernel, 3, sizeof(int), &patternlen);    //private
 67     status = clSetKernelArg(kernel, 4, sizeof(int), &maxSearchLength);    //private
 68     status = clSetKernelArg(kernel, 5, sizeof(cl_mem), (void *)&resultCountBuffer);    //global
 69     status = clSetKernelArg(kernel, 6, sizeof(cl_mem), (void *)&resultBuffer);    //global
 70     status = clSetKernelArg(kernel, 7, sizeof(char)*patternlen, NULL);    //local
 71 
 72     /**Step 10: Running the kernel.*/
 73     cl_event enentPoint;
 74     int globalWorkItem=textlen/64;
 75 
 76     if(textlen%64 != 0)
 77         globalWorkItem++;
 78     size_t groupNUm[1]={globalWorkItem};
 79     size_t localNUm[1]={256};
 80 
 81     status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, groupNUm, localNUm, 0, NULL, &enentPoint);
 82 
 83     clWaitForEvents(1,&enentPoint); ///wait
 84     clReleaseEvent(enentPoint);
 85     int    count=0;
 86     status = clEnqueueReadBuffer(commandQueue, resultCountBuffer, CL_TRUE, 0, sizeof(int), &count, 0, NULL, NULL);
 87     cout<<"\nNumber of matches:"<<count<<endl;
 88 
 89     /**Step 12: Clean the resources.*/
 90     status = clReleaseKernel(kernel);//*Release kernel.
 91     status = clReleaseProgram(program);    //Release the program object.
 92     status = clReleaseMemObject(resultBuffer);//Release mem object.
 93     status = clReleaseMemObject(textBuffer);//Release mem object.
 94     status = clReleaseMemObject(resultCountBuffer);//Release mem object.
 95     status = clReleaseMemObject(patternBuffer);//Release mem object.
 96     status = clReleaseCommandQueue(commandQueue);//Release  Command queue.
 97     status = clReleaseContext(context);//Release context.
 98 
 99     free(devices);
100     free(result);
101     free(resultCount);
102 
103     getchar();
104     return 0;
105 }
View Code

 

 

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

相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
相关文章
人工智能 自然语言处理 安全
378 0
|
2月前
|
人工智能 IDE API
阿里云百炼Coding Plan深度解析:Pro套餐、接入配置与省钱订阅指南
阿里云百炼Coding Plan是面向开发者打造的AI编程专属订阅服务,聚焦代码生成、调试、重构、单元测试等全开发场景,采用固定包月+定额调用次数模式,解决按量计费账单不可控、多模型切换需要多套API、工具适配繁琐等行业痛点。2026年平台完成产品迭代,Lite基础版全面停止新购与续费,当前仅保留Pro高级版作为唯一可用套餐。本文从产品定位核心能力、套餐计费规则、多工具接入实操、成本优化技巧、与Token Plan差异、适用人群选型六个维度完整拆解,帮助开发者快速上手、控制编码AI使用成本。
780 2
|
2月前
|
人工智能 安全 BI
年轻人开始告别“左右滑社交交友经济”:2026社交交友App源码必须内置的6大吸金玩法
2026年的社交交友赛道,底层逻辑正在发生根本性重构——泛流量已不值钱,精准的情绪价值和真实的连接才值钱。
|
1月前
|
人工智能 JSON JavaScript
开发者指南:如何高效导出豆包AI对话记录并进行智能体数据迁移
本文探讨了将豆包AI对话记录完整导出的技术思路,分析了DOM渲染机制带来的挑战,并介绍了浏览器脚本、自动化框架、浏览器扩展等实现路径。重点说明了数据预加载、格式化与JSON/Markdown导出的通用流程,以及导出数据在模型微调、跨平台迁移中的后续利用方法,同时强调了数据安全与合规使用注意事项。
553 0
|
1月前
|
人工智能 IDE 数据挖掘
阿里云Qwen3.7-Max大模型使用活动:每晚22点到次日8点,Qoder与Meoo客户使用Qwen3.7-Max享2折、Plus享4折!
阿里云"Night Plan"夜间优惠计划于每晚22:00至次日08:00,为Qoder和秒悟Meoo用户提供旗舰模型超低折扣:Qwen 3.7-Max享2折、Qwen 3.7-Plus享4折,最高节省80%成本。Qoder全系产品已接入Qwen3.7,覆盖QoderWork CN办公与Meoo创意场景。配套订阅方案灵活多样:Qoder CN个人版59元/月,Teams版99元/月;AI Coding入门套餐69元/月、专业版257元/月,实现工具与算力一站式配置。秒悟Meoo另赠1万积分及每日2000积分,让开发者与创作者零压力享受顶级算力。
|
2月前
|
存储 监控 芯片
硬盘健康检测指南:固态硬盘与机械硬盘的状态判断与维护
本指南详解硬盘健康检测与故障预防:涵盖HDD/SSD故障机理差异、S.M.A.R.T.参数深度解读、坏道类型识别与检测方法,以及Windows自带工具与DiskGenius实操步骤。强调定期检测可提前预警,为数据备份争取关键时间。(239字)
|
4月前
|
人工智能 测试技术 调度
移动端 RPA 的架构重构:基于多模态视觉大模型的自动化调度系统压测复盘
本文复盘企业级移动端RPA重构实践,介绍如何以“侠客工坊”AI数字员工平台替代传统坐标录制方案:基于多模态大模型实现视觉语义决策、高并发多机型调度、零代码编排、异常自愈及MCP协议集成,显著提升自动化鲁棒性与运维效率。
358 10
|
4月前
|
存储 SQL 关系型数据库
InnoDB 索引性能天花板:聚簇 & 二级索引存储本质拆解,覆盖索引零回表优化全攻略
本文深入剖析MySQL InnoDB索引底层原理,详解数据页结构、聚簇索引与二级索引差异,揭示“回表”这一性能杀手的本质,并系统阐述覆盖索引的设计原则与实战优化方法,助开发者实现查询性能百倍提升。
458 4
|
文字识别 iOS开发 MacOS
【uTools】uTools下载安装图文教程(国产良心软件)
uTools是一款极简、插件化的国产效率工具,通过Alt+Space呼出搜索框,快速调用OCR、翻译、截图等数百款免费插件。“一切皆插件”设计支持高度自定义,适配Windows/macOS/Linux,提升多场景办公效率。(239字)
|
5月前
|
人工智能 弹性计算 自然语言处理
阿里云学生专属算力包:AI时代下大学生的“数字装备”新选择
阿里云学生专属算力包,19元享高性价比云端AI资源,含练手/毕设/科创三档套餐。配套“AI简历”个人主页,支持视频、交互Demo与GitHub直链,5分钟自然语言一键部署,助力大学生用作品说话,提升就业竞争力。
807 7