日度归档:2015年3月26日

测量程序执行时间-周期计数器

摘自“深入理解计算机系统”
测量程序执行时间-周期计数器
为了给计时测量提供更高的精确度,许多处理器还包含一个运行在时钟周期级的计时器。这个计时器是一个特殊的寄存器,每个时钟周期它会都会加1.可以用特殊的机器指令来读取这个计数器的值。不是所有的处理器都有这样的计数器的,而且有这样的计数器的处理器在实现细节上也各不相同。因此,程序猿无法用统一的、与平台无关的接口使用这些计数器。另一方面,只用少量的汇编代码,通常很容易就为某个特定的机器创建一个程序接口。
IA32周期计数器
到目前为止,我们已经报告的所有计时值都是用IA32周期计数器测量出来的。在IA32体系结构中,周期计数器是与P6微体系机构一起提出来的。周期计数器是一个64位无符号数。对于一个运行时钟为1GHz的处理器,只是在每1.8 * 10的10次方 或者每 570年,这个计数器才会从2的64次方-1绕回到0.另一方面,如果我们只考虑这个计数器的低32位,把它看成一个无符号整数,那么这个值大约每4.3秒就绕回。因此,我们就明白了为什么IA32的设计者会决定实现一个64位的计数器。
IA32计数器是用rdtsc(read time stamp counter,读时间戳计数器)指令来访问的。这条指令没有参数,它将寄存器%edx设置为计数器的高32位,而寄存器%eax设置为低32位,为了提供一个C程序接口,我们想把这个指令包装到一个过程中;
void access_counter(unsigned *hi,unsigned *lo);
这个过程应该将位置hi设置为计数器的高32位,将lo设置为低32位。

static unsigned cyc_hi =0;
static unsigned cyc_lo =0;

void access_counter(unsigned *hi,unsigned *lo)
{
asm(“rdtsc; movl %%edx,%0; movl %%eax,%l”
:”=r” (*hi), “=r” (*lo)
:
:”%edx”, “%eax”
);
}

void start_counter()
{
access_counter(&cyc_hi,&cyc_lo);
}

double get_counter()
{
unsigned ncyc_hi,ncyc_lo;
unsigned hi,lo,borrow;
double result;

access_counter(&ncyc_hi,&ncyc_lo);
lo = ncyc_lo-cyc_lo;
borrow =lo>ncyc_lo;
hi =ncyc_hi-cyc_hi-borrow;
result =(double)hi *(1<<30)*4+lo; if(result <0) { fprintf(stderr,"error:%0f",result); } return result; } 上面的函数可以测量两个时间点之间的时钟周期总数。

mssql如何检测一个字符串是否包含在另一个字符列表中

1 如何将一个字符串分解为单个字符

declare @a varchar(60)
set @a ='5643cv'  ---定义字符串
 
declare @i int ,  ---字符串起始位置
        @max  int, ---字符串最大长度
        @tmp  char(1) ---临时中间变量
        
set @i=1
set @max=LEN(@a)
print '当前字符串长度:  '+convert(varchar(100),@max)
 
----遍历取出单个字符验证
while @i<=@max
begin
set @tmp =''
set @tmp=SUBSTRING(@a,@i,1)
print '单个字符串:  '+@tmp
set @i=@i+1
end


2 验证字符串里面的单个字符是否为数字?


declare @a varchar(60)
set @a ='5643cv'  ---定义字符串
 
 declare @t table (k varchar(1))  ----定义符合条件数据列表 
 insert into @t values(1)
 insert into @t values(2)
 insert into @t values(3)
 insert into @t values(4)
 insert into @t values(5)
 insert into @t values(6)
 insert into @t values(7)
 insert into @t values(8)
 insert into @t values(9)
 insert into @t values(0)
 
declare @i int ,  ---字符串起始位置
        @max  int, ---字符串最大长度
        @tmp  char(1), ---临时中间变量
        @check int    ---定义验证返回值 -1 代表数据格式符合条件
set @check=1;     
set @i=1;
set @max=LEN(@a)
print '当前字符串长度:  '+convert(varchar(100),@max)


----遍历取出单个字符验证
while @i<=@max
begin
set @tmp =''
set @tmp=SUBSTRING(@a,@i,1)
print '单个字符串:  '+@tmp

 if not exists(select * from @t where k=@tmp)
 begin
 set @check=-1
 end

set @i=@i+1
end
 

select @check

3 扩展 验证字符串里面的单个字符是否符合系统验证要求?
 ----定义一个MSSQL标量函数,让MSSQL在任何地方都可以验证所的字符
 
create function tmpCheck(@a varchar(8000), ----待验证字符 
@b varchar(8000)---单个字符串集合列表
)
returns  varchar(1) 
as
begin

 declare @t1 table (k1 varchar(1))
 declare @t2 table (k2 varchar(2)) 
  
declare @i int ,  ---字符串起始位置
        @max  int, ---字符串最大长度
        @tmp  char(1), ---临时中间变量
        @check varchar(20) 
set @check='1' 
set @i=1
set @max=LEN(@a) 


----遍历取出单个字符验证
while @i<=@max
begin
set @tmp =''
set @tmp=SUBSTRING(@a,@i,1)  
insert into @t1 values(@tmp)
set @i=@i+1
end

 
set @i=1
set @max=LEN(@b) 


----遍历取出单个字符验证
while @i<=@max
begin
set @tmp =''
set @tmp=SUBSTRING(@b,@i,1)  
insert into @t2 values(@tmp)
set @i=@i+1
end

 

if exists(select * from @t1 where k1 not in (select * from @t2))
begin
set @check ='er' 

end

return  @check
end

 
---实例应用

select dbo.tmpCheck('5691841200015','1234567890')  --返回1  代表符合条件