posts - 17,comments - 8,trackbacks - 0

Table: markdetails

## studid ## ## subjectid ##  ## marks ##
     A1            3                50
     A1            4                60
     A1            5                70
     B1            3                60
     B1            4                80
     C1            5                95

Table: student info

## studid ##  ## name ##
      A1          Raam
      B1          Vivek
      c1          Alex


Result: 

## studid ## ## name## ## subjectid_3 ## ## subjectid_4 ## ## subjectid_5 ##
      A1        Raam        50                60                 70
      B1        Vivek       60                80                null
      c1        Alex       null              null                95


 SQLite:

select
    u.stuid,
    u.name,
    s3.marks as subjectid_3,
    s4.marks as subjectid_4,
    s5.marks as subjectid_5
from
    student_temp u
    left outer join markdetails s3 on
        u.stuid = s3.stuid
        and s3.subjectid = 3
    left outer join markdetails s4 on
        u.stuid = s4.stuid
        and s4.subjectid = 4
    left outer join markdetails s5 on
        u.stuid = s5.stuid
        and s5.subjectid = 5

posted @ 2011-08-11 23:51 汝熹 阅读(32) 评论(0) 编辑

转自http://it.enorth.com.cn/system/2008/06/17/003409310.shtml 

这篇文章是根据SQLite官方WIKI里的内容翻译,SQLite 包括以下五个时间函数:

  1.date(日期时间字符串,修正符,修正符, ……)

  2.time(日期时间字符串,修正符,修正符, ……)

  3.datetime(日期时间字符串,修正符,修正符, ……)

  4.julianday(日期时间字符串,修正符,修正符, ……)

  5.strftime(日期时间格式,日期时间字符串,修正符,修正符, ……)

  上述五个函数需要一个日期时间字符串做参数,后面可以跟零到多个修正符参数。而strftime()函数还需要一个日期时间格式字符串做第一个参数。

  1.date()函数返回一个以“YYYY-MM-DD”为格式的日期;

  2.time()函数返回一个以“YYYY-MM-DD HH:MM:SS”为格式的日期时间;

  3.julianday()函数返回一个天数,从格林威治时间公元前4714年11月24号开始算起;

  4.strftime()函数返回一个经过格式话的日期时间,它可以用下面的符号对日期和时间进行格式化:

  %d 一月中的第几天01-31

  %f 小数形式的秒,SS.SSSS

  %H 小时00-24

  %j 一年中的第几天01-366

  %J Julian Day Numbers

  %m 月份01-12

  %M 分钟00-59

  %s 从1970-01-01日开始计算的秒数

  %S 秒00-59

  %w 星期,0-6,0是星期天

  %W 一年中的第几周00-53

  %Y 年份0000-9999

  %% %百分号

  其他四个函数都可以用strftime()函数来表示:

  1.date(…) -> strftime(“%Y-%m-%d”,…)

  2.time(…) -> strftime(“%H:%M:%S”,…)

  3.datetime(…) -> strftime(“%Y-%m-%d %H:%M:%S”,…)

  4.julianday(…) -> strftime(“%J”,…)

  日期时间字符串,可以用以下几种格式:

  YYYY-MM-DD

  YYYY-MM-DD HH:MM

  YYYY-MM-DD HH:MM:SS

  YYYY-MM-DD HH:MM:SS.SSS

  YYYY-MM-DDTHH:MM

  YYYY-MM-DDTHH:MM:SS

  YYYY-MM-DDTHH:MM:SS.SSS

  HH:MM

  HH:MM:SS

  HH:MM:SS.SSS

  now

  DDDD.DDDD

  在第五种到第七种格式中的“T”是一个分割日期和时间的字符;第八种到第十种格式只代表2000-01-01日的时间,第十一种格式的’now’表示返回一个当前的日期和时间,使用格林威治时间(UTC);第十二种格式表示一个Julian Day Numbers。

  修正符,日期和时间可以使用下面的修正符来更改日期或时间:

  NNN days

  NNN hours

  NNN minutes

  NNN.NNNN seconds

  NNN months

  NNN years

  start of month

  start of year

  start of week

  start of day

  weekday N

  unixepoch

  localtime

  utc

  前六个修正符就是简单的增加指定数值的时间和日期;第七到第十个修正符表示返回当前日期的开始;第十一个修正符表示返回下一个星期是N的日期和时间;第十二个修正符表示返回从1970-01-01开始算起的秒数;第十三个修正符表示返回本地时间。

  下面举一些例子:

  计算机当前时间

  SELECT date(‘now’)

  计算机当前月份的最后一天

  SELECT date(‘now’,’start of month’,’+1 month’,’-1 day’)

  计算UNIX时间戳1092941466表示的日期和时间

  SELECT datetime(‘1092941466’,’unixepoch’)

  计算UNIX时间戳1092941466表示的本地日期和时间

  SELECT datetime(‘1092941466’,’unixepoch’,’localtime’)

  计算机当前UNIX时间戳

  SELECT strftime(‘%s’,’now’)

  两个日期之间相差多少天

  SELECT jolianday(‘now’)-jolianday(‘1981-12-23’)

  两个日期时间之间相差多少秒

  SELECT julianday('now')*86400 - julianday('2004-01-01 02:34:56')*86400

  计算今年十月份第一个星期二的日期

  SELECT date('now','start of year','+9 months','weekday 2');

posted @ 2011-08-11 13:56 汝熹 阅读(132) 评论(0) 编辑

转自http://blog.csdn.net/zhjp4295216/article/details/5776954

 

select path || '%'  from t_category where depth = 0 and type = 0

用'||'拼接字符串

比如path是/1001/的话 那结果就是/1001/%

 

数字相加

SELECT 'A'+'B'  结果为0

SELECT "A"+"1" 结果为1

SELECT "A"+1   结果为1

SELECT 2+1 结果为3

=在“+”运算中,SQLite将字符串非数字串都当作0处理了

 

|| String Concatenation
* Arithmetic Multiply
/ Arithmetic Divide
% Arithmetic Modulus
+ Arithmetic Add
Arithmetic Subtract
<< Bitwise Right shift
>> Bitwise Left shift
& Logical And
| Logical Or
< Relational Less than
<= Relational Less than or equal to
> Relational Greater than
>= Relational Greater than or equal to
= Relational Equal to
== Relational Equal to
<> Relational Not equal to
!= Relational Not equal to
IN Logical In
AND Logical And
OR Logical Or
LIKE Relational String matching
GLOB Relational Filename matching

posted @ 2011-08-11 12:51 汝熹 阅读(128) 评论(0) 编辑

      今日突然想起讯雷说自己的界面使用MMX优化了,速度得到提升。那什么是MMX呢?

      原来MMX是由英特尔开发的一种SIMD多媒体指令集,共有57条指令,以并行方式处理多个数据元素。它最早集成在英特尔奔腾(Pentium)MMX处理器上,以提高其多媒体数据的处理能力。

      MMX技术提高了很多应用程序的执行性能,例如活动图像、视频会议、二维图形和三维图形。几乎每一个具有重复性和顺序性整数计算的应用程序都可以从MMX技术中受益。对于8位、16位和32位数据元素的处理,改善了程序的性能。一个MMX指令可一次操作8个字节,且在一个时钟周期内完成两条指令,也就是说,可在一个时钟周期内处理16个数据元素。另外,为增强性能,MMX技术为其它功能释放了额外的处理器周期。以前需要其它硬件支持的应用程序,现在仅需软件就能运行。更小的处理器占用率给更高程度的并发技术提供了条件,在当今众多的操作系统中这些并发技术得到了利用。在基于英特尔的分析系统中,某些功能的性能提高了50%~400%。这种数量级的性能扩展可以在新一代处理器中得到体现。在软件内核中,其速度得到更在的提高,其幅度为原有速度的3~5倍。

  MMX也有缺点,由于MMX的运算指令必须在数据配对整齐的时候才能使用,所以使用MMX指令要比普通的汇编指令多余许多分组配对的指令,如果运算不是特别的整齐的话,就要浪费大量的时间在数据的配对上,所以说MMX指令也不是万能的,也有其很大的缺陷。同时MMX指令在处理16位数据的时候才能发挥最大的作用,处理8位数据要有一点技巧。而处理32位数据,MMX指令几乎没有什么加速能力。(考虑分组耗时的话)

     上面的都是在网络上可以找到的关于MMX一些信息,通过这些信息,对MMX大概有一个了解,但对于知识,我们还是不能简单的接受,也要通过思考和实验验证一下,才能对MMX有更深的了解,好在在实际项目上更好的应用起来。

 

      初试MMX

 

View Code
 1 #include "stdafx.h"
 2 #include <xmmintrin.h>
 3 
 4 int _tmain(int argc, _TCHAR* argv[])
 5 {
 6     const int ARRAY_COUNT = 4000;
 7     int count = ARRAY_COUNT / 4;
 8     short __declspec(align(8)) as[ARRAY_COUNT];
 9     short __declspec(align(8)) bs[ARRAY_COUNT];
10     short __declspec(align(8)) cs[ARRAY_COUNT];
11 
12     for(int i = 0; i < ARRAY_COUNT; i++)
13     {
14         as[i] = rand() % 100;
15         bs[i] = rand() % 70;
16     }
17 
18     __m64* a;
19     __m64* b;
20     __m64* c;
21 
22     a = (__m64*)&as[0];
23     b = (__m64*)&bs[0];
24     c = (__m64*)&cs[0];
25     for(int i = 0; i < count; i++)
26     {                
27         *c++ = _m_paddsw(*a++*b++);
28     }
29 
30     return 0;
31 }

 

      在C++里面使用MMX有两种方式,一种是使用内联汇编的方式,另一种是使用C++封装好的函数,两种方式我都尝试比较过,发现性能差异很小(没感觉),所以我就直接使用第二种方式好了;要使用第二种方式,首先我们需要引用“xmmintrin.h”头文件,它包含一64位和128位数据定义和全部运算函数。

      上面的例子是有两个16位数据的数组进行相加,结果保存到第三个数组上;在数组定义的语句上,我加了一个8位对齐的声明,但从实际结果来看,这个声明没有什么影响,应该是C++基本数据没有对齐的问题。实际测试结果比普通一个个相加的时间缩短一半多一些,还蛮不错的。

 

posted @ 2011-04-09 09:49 汝熹 阅读(148) 评论(0) 编辑

    图像锐化是补偿图像的轮廓,增强图像的边缘及灰度跳变的部分,使图像变得清晰。图像平滑往往使图像中的边界、轮廓模糊,为了减少这类不利影响,利用图像锐化技术可以使图像的边缘清晰。图像锐化处理的目的是使图像的边缘、轮廓线及图像的细节变得清晰。经过平滑的图像变得模糊的根本原因是对图像进行了平均或积分运算,因此对其进行逆运算。

 

1。梯度锐化

    

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe
{
     
byte* sourceptr = (byte*)sourcedata.Scan0;  
     
byte* descptr = (byte*)descdata.Scan0;
     
int step = source.Width * 3;
     
double value;
     
for (int x = 0; x < source.Height; x++)
     {
         
for (int y = 0; y < source.Width; y++)
         {    
              value 
= Math.Sqrt((*sourceptr - *(sourceptr + step + 3)) * (*sourceptr - *(sourceptr + step + 3)) +
                      (
*(sourceptr + 3- *(sourceptr + step)) * (*(sourceptr + 3- *(sourceptr + step)));
              
*(descptr++= value > 255 ? (byte)255 : (byte)(value);
              sourceptr
++;
         }
         sourceptr 
+= sourcedata.Stride - source.Width * 3;
         descptr 
+= descdata.Stride - desc.Width * 3;
     }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

2。拉普拉斯掩膜锐化

 

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe
{
     
byte* sourceptr = (byte*)sourcedata.Scan0;  
     
byte* descptr = (byte*)descdata.Scan0;
     
int step = source.Width * 3;
     
double value;
     
for (int x = 0; x < source.Height; x++)
     {
         
for (int y = 0; y < source.Width; y++)
         {    
              value 
= Math.Abs(*(sourceptr - step) + *(sourceptr - 3+ *(sourceptr + 3+ 
                               
*(sourceptr + step) - *(sourceptr) * 4);
              
*(descptr++= value > 255 ? (byte)255 : (byte)(value);
              sourceptr
++;
         }
         sourceptr 
+= sourcedata.Stride - source.Width * 3;
         descptr 
+= descdata.Stride - desc.Width * 3;
     }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

 

posted @ 2010-09-09 15:31 汝熹 阅读(37) 评论(0) 编辑
摘要: 1。邻域平均法 噪声点像素的灰度与其临近像素的灰度显著不同,根据噪声点这一特性,可以使用邻域平均法。[代码]2。加权平均法 邻域平均处理方法是以图像模糊为代价减小噪声。有时为了突出源图像中的点(i, j)本身的重要性,对于同一尺寸的模板,不同位置的系数采用不同的数值就可以采用加权平均法实现。[代码]3。选择式掩膜平滑 邻域平均法和加权平均法在消除噪声的同时,都不可避免地带来平均化的缺憾,致使尖锐变...阅读全文
posted @ 2010-09-08 23:30 汝熹 阅读(31) 评论(0) 编辑

1。反色

 

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  
      
byte* descptr = (byte*)descdata.Scan0;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                
*(descptr++= (byte)(255 - *(sourceptr++));
                
*(descptr++= (byte)(255 - *(sourceptr++));
                
*(descptr++= (byte)(255 - *(sourceptr++));
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

2。霓虹灯

 

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  
      
byte* descptr = (byte*)descdata.Scan0;
      
int step = source.Width * 3;
      
double value;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                value 
= 2 * Math.Sqrt((*sourceptr - *(sourceptr + 3)) * (*sourceptr - *(sourceptr + 3)) +
                        (
*sourceptr - *(sourceptr + step)) * (*sourceptr - *(sourceptr + step)));
                
*(descptr++= value > 255 ? (byte)255 : (byte)(value);
                sourceptr
++;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

3。浮雕

 

 Bitmap desc = new Bitmap(source.Width, source.Height);

BitmapData sourcedata = source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  
      
byte* descptr = (byte*)descdata.Scan0;
      
int step = (source.Width + 1* 3;
      
double value;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                value 
= Math.Abs(*(sourceptr - step) - *sourceptr + 128);
                
*(descptr++= value > 255 ? (byte)255 : (byte)(value);
                sourceptr
++;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

posted @ 2010-09-08 23:18 汝熹 阅读(22) 评论(0) 编辑

将彩色的图片转换成黑白有很多种方法:

1。红色转换灰度

  Bitmap desc = new Bitmap(source.Width, source.Height);

BitmapData sourcedata = source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  //B,G,R
      sourceptr += 2;
      
byte* descptr = (byte*)descdata.Scan0;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                
*(descptr++= *sourceptr;
                
*(descptr++= *sourceptr;
                
*(descptr++= *sourceptr;
                sourceptr 
+= 3;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

2。绿色转换灰度

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  //B,G,R
      sourceptr += 1;
      
byte* descptr = (byte*)descdata.Scan0;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                
*(descptr++= *sourceptr;
                
*(descptr++= *sourceptr;
                
*(descptr++= *sourceptr;
                sourceptr 
+= 3;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

3。蓝色转换灰度

 Bitmap desc = new Bitmap(source.Width, source.Height);

BitmapData sourcedata = source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  //B,G,R
      byte* descptr = (byte*)descdata.Scan0;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                
*(descptr++= *sourceptr;
                
*(descptr++= *sourceptr;
                
*(descptr++= *sourceptr;
                sourceptr 
+= 3;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

 

4。平均转换灰度

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  //B,G,R
      byte* descptr = (byte*)descdata.Scan0;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                
*(descptr) = *(descptr + 1= *(descptr + 2= (byte)((*sourceptr + *(sourceptr + 1+ *(sourceptr + 2)) / 3);
                descptr 
+= 3;
                sourceptr 
+= 3;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

 

 

5。加权平均转换灰度

Bitmap desc = new Bitmap(source.Width, source.Height);
BitmapData sourcedata 
= source.LockBits(new Rectangle(00, source.Width, source.Height), 
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData descdata 
= desc.LockBits(new Rectangle(00, desc.Width, desc.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

unsafe
{
      
byte* sourceptr = (byte*)sourcedata.Scan0;  //B,G,R
      byte* descptr = (byte*)descdata.Scan0;
      
for (int x = 0; x < source.Height; x++)
      {
           
for (int y = 0; y < source.Width; y++)
           {
                
*(descptr) = *(descptr + 1= *(descptr + 2= (byte)(*sourceptr * 0.11 + *(sourceptr + 1* 0.58 + *(sourceptr + 2* 0.31);
                descptr 
+= 3;
                sourceptr 
+= 3;
            }
            sourceptr 
+= sourcedata.Stride - source.Width * 3;
            descptr 
+= descdata.Stride - desc.Width * 3;
       }
}
source.UnlockBits(sourcedata);
desc.UnlockBits(descdata);

 

 

 

 

 

 

 

 

posted @ 2010-09-08 22:31 汝熹 阅读(104) 评论(0) 编辑

      ALock并发线程的最大个数为一个已知的界限N,同时也要为每个锁分配一个与该界限大小相同的数组。 就算一个线程每次只访问一个锁,同步L个不同对象也需要O(LN)大小的空间。

CLHLock

Code

       类QNode的布尔型Locked属性记录了每个线程的状态。如果Locked为true,则对应的线程要么已经获得到锁,要么正在等待锁;如果Locked为false,则对应的线程已经释放了锁。线程被顺序地排入“隐式”链表,每个线程通过一个线程局部变量myPred指向前驱线程,公共的tail保存着最近加入到队列的结点。

      若要获得锁,线程将自己的myNode的Locked设为true,表示该线程准备获得锁。随后线程对tail调用Interlocked.Exchange方法,把自身的前驱myPred指向队尾,并将自身设置为新队尾。最后线程就在myPred的Locked上旋转,直到myPred释放锁。若要释放锁,线程将其Locked设为false。

      CLHLock让每个线程在不同的存储单元上旋转,这样当一个线程释放它的锁时,只能使其后继的cache无效。该算法比ALock所需要的空间少(同步L个不同对象只需要O(L + N)的空间),且不需要知道可能使用锁的线程数量。也提供了先来先服务的公平性。
posted @ 2009-10-23 22:32 汝熹 阅读(227) 评论(0) 编辑
摘要: 在BackoffLock算法中有两个问题:1.cache一致性流量:所有线程都在同一个共享存储单元上旋转,每一次成功的锁访问都会产生cache一致性流量(尽管比TASLock低);2.临界区利用率低:线程延迟过长,导致临界区利用率低下。 可以将线程组织成一个队列来克服这些缺点。在队列中,每个线程检测其前驱线程是否已完成来判断是否轮到自己。让每个线程在不同的存储单元上旋转,从而降低cache一致性流...阅读全文
posted @ 2009-10-22 23:35 汝熹 阅读(159) 评论(0) 编辑