有一个 vector 容器中,存有 1 亿个 qq 号(不重复),如何快速挑选出其中奇数号码?

风空 2016-08-04 07:49:56
有一个 vector 容器中,存有 1 亿个 qq 号(不重复),如何快速挑选出其中奇数号码?
...全文
1038 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
风空 2016-10-04
  • 打赏
  • 举报
回复
一个VECTOR已经存了,怎么用多线程啊,
cocoabird 2016-08-10
  • 打赏
  • 举报
回复
多线程+hash
yangyunzhao 2016-08-10
  • 打赏
  • 举报
回复
现在普通服务器的CPU,遍历一亿次,很慢吗?
10km 2016-08-09
  • 打赏
  • 举报
回复
引用 11 楼 bluewanderer 的回复:
[quote=引用 9 楼 10km 的回复:]
呃,而且你这里还有原子操作...[/quote] 你说的没错 的确原子操作用着方便 ,其实对性能的影响挺大的,用过一次放弃了, 而且我也没用过主机内存共享模式只是知道并没采用过,之前用opencl做目标检测的时候也都是在显存中计算的,没考虑使用主机内存。 哈,其实我也就是凑个热闹,给个思路,
bluewanderer 2016-08-09
  • 打赏
  • 举报
回复
引用 9 楼 10km 的回复:
呃,而且你这里还有原子操作...
bluewanderer 2016-08-09
  • 打赏
  • 举报
回复
引用 9 楼 10km 的回复:
[quote=引用 8 楼 bluewanderer 的回复:] [quote=引用 7 楼 10km 的回复:] 1亿也没多少,可以用opencl实现放在gpu上并发执行,代码简单。 gpu最适合干这种逻辑简单的工作了。
// 允许64位整数原子操作函数
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
// 查找奇数号码的kernel函数(opencl)
__kernel void odd_filter(__global long* src_qq // 源数据缓冲区,QQ号码以long(64位整数)类型保存
                            ,__global long* out_buf,// 保存奇数的QQ号码
                            ,__global long* counter;// 缓冲区计数器,初始为0
                            ){
  // 从源缓冲区取出QQ号,判断是否为奇数,将其加入输出缓冲区
  long qq=src_qq[get_global_id(0)];
	if(qq&1){
		// 用atom_inc原子指令将计数器加+1,并返回counter被+1之前的值.这个值用于写入qq号码的下标
		out_buf[atom_inc(counter)]=qq;
	}
}
有往GPU传的功夫CPU都已经遍历完了[/quote] 可以不传到gpu内存,直接共享主机内存啊。[/quote] 除非是核显,否则即便GPU直接访问主内存也是。 内存=>CPU=>PCIE=>GPU=>PCIE=>CPU=>内存,而且GPU能直接访问的主内存是uncached,CPU直接读奇慢无比。 而CPU处理只要 内存=>CPU=>内存 GPU运算需要靠运算速度抵消额外传输的成本,而你这里运算量太小。
10km 2016-08-09
  • 打赏
  • 举报
回复
引用 8 楼 bluewanderer 的回复:
[quote=引用 7 楼 10km 的回复:] 1亿也没多少,可以用opencl实现放在gpu上并发执行,代码简单。 gpu最适合干这种逻辑简单的工作了。
// 允许64位整数原子操作函数
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
// 查找奇数号码的kernel函数(opencl)
__kernel void odd_filter(__global long* src_qq // 源数据缓冲区,QQ号码以long(64位整数)类型保存
                            ,__global long* out_buf,// 保存奇数的QQ号码
                            ,__global long* counter;// 缓冲区计数器,初始为0
                            ){
  // 从源缓冲区取出QQ号,判断是否为奇数,将其加入输出缓冲区
  long qq=src_qq[get_global_id(0)];
	if(qq&1){
		// 用atom_inc原子指令将计数器加+1,并返回counter被+1之前的值.这个值用于写入qq号码的下标
		out_buf[atom_inc(counter)]=qq;
	}
}
有往GPU传的功夫CPU都已经遍历完了[/quote] 可以不传到gpu内存,直接共享主机内存啊。
bluewanderer 2016-08-09
  • 打赏
  • 举报
回复
引用 7 楼 10km 的回复:
1亿也没多少,可以用opencl实现放在gpu上并发执行,代码简单。 gpu最适合干这种逻辑简单的工作了。
// 允许64位整数原子操作函数
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
// 查找奇数号码的kernel函数(opencl)
__kernel void odd_filter(__global long* src_qq // 源数据缓冲区,QQ号码以long(64位整数)类型保存
                            ,__global long* out_buf,// 保存奇数的QQ号码
                            ,__global long* counter;// 缓冲区计数器,初始为0
                            ){
  // 从源缓冲区取出QQ号,判断是否为奇数,将其加入输出缓冲区
  long qq=src_qq[get_global_id(0)];
	if(qq&1){
		// 用atom_inc原子指令将计数器加+1,并返回counter被+1之前的值.这个值用于写入qq号码的下标
		out_buf[atom_inc(counter)]=qq;
	}
}
有往GPU传的功夫CPU都已经遍历完了
10km 2016-08-09
  • 打赏
  • 举报
回复
1亿也没多少,可以用opencl实现放在gpu上并发执行,代码简单。 gpu最适合干这种逻辑简单的工作了。
// 允许64位整数原子操作函数
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
// 查找奇数号码的kernel函数(opencl)
__kernel void odd_filter(__global long* src_qq // 源数据缓冲区,QQ号码以long(64位整数)类型保存
                            ,__global long* out_buf,// 保存奇数的QQ号码
                            ,__global long* counter;// 缓冲区计数器,初始为0
                            ){
  // 从源缓冲区取出QQ号,判断是否为奇数,将其加入输出缓冲区
  long qq=src_qq[get_global_id(0)];
	if(qq&1){
		// 用atom_inc原子指令将计数器加+1,并返回counter被+1之前的值.这个值用于写入qq号码的下标
		out_buf[atom_inc(counter)]=qq;
	}
}
lm_whales 2016-08-05
  • 打赏
  • 举报
回复
QQ 不是字符串吗?最后一位数是1,3,5,7,9 就是奇数了 也就是说,只需要检测一个字节 如果用整型也只需要判断一个Bit 然后开多线程跑一下 8 核的,开8~16个线程,分段查找就是了 4核 4~8 个线程
mLee79 2016-08-05
  • 打赏
  • 举报
回复
弄台量子计算机, 这样就可以在 O(N^(1/2)) 下遍历 O(N) 的空间, 这样大概就只要 1W 次操作就可以了...
paschen 版主 2016-08-05
  • 打赏
  • 举报
回复
多线程并行运算
赵4老师 2016-08-05
  • 打赏
  • 举报
回复
仅供参考:
//文件1中的内容排序并去重,结果保存到文件2中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0
int MAXLINES=10000,MAXLINES2;
char *buf,*buf2;
int c,n,hh,i,L;
FILE *f;
char ln[MAXCHARS];
int ignore_case=0;
int icompare(const void *arg1,const void *arg2) {
   return stricmp((char *)arg1,(char *)arg2);
}
int compare(const void *arg1,const void *arg2) {
   return strcmp((char *)arg1,(char *)arg2);
}
int main(int argc,char **argv) {
    if (argc<3) {
        printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");
        printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);
        return 1;
    }
    if (argc>3) ignore_case=1;//若存在命令行参数3,忽略大小写
    f=fopen(argv[1],"r");
    if (NULL==f) {
        printf("Can not find file %s!\n",argv[1]);
        return 1;
    }
    buf=(char *)malloc(MAXLINES*MAXCHARS);
    if (NULL==buf) {
        fclose(f);
        printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);
        return 2;
    }
    n=0;
    hh=0;
    i=0;
    while (1) {
        if (NULL==fgets(ln,MAXCHARS,f)) break;//
        hh++;
        L=strlen(ln)-1;
        if ('\n'!=ln[L]) {//超长行忽略后面内容
            printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);
            while (1) {
                c=fgetc(f);
                if ('\n'==c || EOF==c) break;//
            }
        }
        while (1) {//去掉行尾的'\n'和空格
            if ('\n'==ln[L] || ' '==ln[L]) {
                ln[L]=0;
                L--;
                if (L<0) break;//
            } else break;//
        }
        if (L>=0) {
            strcpy(buf+i,ln);i+=MAXCHARS;
            n++;
            if (n>=MAXLINES) {
                MAXLINES2=MAXLINES*2;
                if (MAXLINES2==1280000) MAXLINES2=2500000;
                buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);
                if (NULL==buf2) {
                    printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);
                    printf("WARNING: Lines >%d ignored.\n",MAXLINES);
                    break;//
                }
                buf=buf2;
                MAXLINES=MAXLINES2;
            }
        }
    }
    fclose(f);
    if (n>1) {
        if (ignore_case) qsort(buf,n,MAXCHARS,icompare);
        else qsort(buf,n,MAXCHARS,compare);
    }
    f=fopen(argv[2],"w");
    if (NULL==f) {
        free(buf);
        printf("Can not create file %s!\n",argv[2]);
        return 2;
    }
    fprintf(f,"%s\n",buf);
    if (n>1) {
        if (ignore_case) {
            hh=0;
            L=MAXCHARS;
            for (i=1;i<n;i++) {
                if (stricmp((const char *)buf+hh,(const char *)buf+L)) {
                    fprintf(f,"%s\n",buf+L);
                }
                hh=L;
                L+=MAXCHARS;
            }
        } else {
            hh=0;
            L=MAXCHARS;
            for (i=1;i<n;i++) {
                if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {
                    fprintf(f,"%s\n",buf+L);
                }
                hh=L;
                L+=MAXCHARS;
            }
        }
    }
    fclose(f);
    free(buf);
    return 0;
}
060 2016-08-05
  • 打赏
  • 举报
回复
一个vector 存放1亿个QQ号都是很大问题 假设每个QQ为64位整型数字,每个QQ号为8字节,一亿个QQ号为,800M。 如果使用逐个push_back,在构造这1亿的QQ号的vector时,就要耗费很大的时间,vector要多次扩展、分配、释放内存,并复制内存。如果有这个功夫,在构造vector、push_backQQ号时,就可以判断奇偶数。判断奇偶数,应该比push_back还要快。
ztenv 版主 2016-08-04
  • 打赏
  • 举报
回复
1、多线程分区处理这1亿条数据,并且根据cpu核 数控制线程数量,当线程工作完成后再分配新的任务。 2、将1亿条数据分散到集群上去做,每台机器重复1的步骤 期待下面大神出现。

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧