2014年3月13日星期四

How to Select a DSP Processor

How to Select a DSP Processor

This article will be useful if you have already decided that you need a DSP processor to handle your computationally-intensive signal processing application in real-time, but need some help selecting a DSP processor. It will guide you through some of the characteristics of DSP processors that you can choose from to help you narrow-down the choice.
For this discussion it is assumed that you are interested in stand-alone DSP processor chips, and not on DSP cores that you will embed on your own ASIC.

Floating-Point vs. Fixed-Point

You will need to decide if you need floating-point support from the DSP processor or not. If your application does not make use of floating-point variables, then you don’t need a floating-point unit. If your application does use floats, you can still convert the algorithms to fixed-point arithmetic. This is a time-consuming job, but allows you to save the cost of a floating-point unit on your DSP processor. If you leave floating-point operations in your program and compile it for a processor with no floating-point unit, it will use emulation libraries that are extremely slow.
In general all algorithms can be implemented in fixed-point arithmetic, and fixed-point implementations run a bit faster than floating-point implementations of the same algorithm. The advantage of floating-point is that it saves development time. But having a floating-point unit will make your DSP processor bigger and more expensive.
Note that floating point units in DSP processors will provide support for single-precision floating-point operations only. Double-precision operations will still use emulation libraries and will run very slowly.

32-Bit Vs. 16-Bit

The vast majority of DSP processors today are 32-bit. There are still some 16-bit DSP processors offered, which tend to be smaller, cheaper and consume less power than 32-bit processors.
To know if you need a 32-bit processor, you must first determine what the dynamic range of your data is. Dynamic range is the difference between the lowest and the highest values that you need to represent in a variable, including fractional bits. Voice applications usually work with 12-bit data, while CD-quality audio is 16-bits. In addition to the basic data size, you will need some extra bits to hold sums (the sum of two 16-bit numbers requires 17 bits). So practically speaking, 16-bit DSP processors are useful mostly for voice signal processing applications.
Even if your data fits comfortably inside of 16 bits, you might still prefer a 32-bit processor because of the optimization opportunities it provides. You can store two 16-bit data elements on a single 32-bit variable, and perform operations on them in parallel. If your application has 8-bit data (like video and image processing), you may be able to operate on 4 elements at a time on a 32-bit DSP. When perform multiplications of 16-bit values, the intermediate result is a 32-bit value. Manipulating intermediate multiplication results is done more efficiently on a 32-bit architecture than on a 16-bit one.

Multi-Core

A popular choice for embedded systems is to use a dual-core chip, where one of the cores is a DSP processor, and the other is a general-purpose processor. This arrangement suits many applications that require a DSP processor for number-crunching, but also need to run a lot of general code, like a full operating system, or a web browser. If your application will involve only a small amount of general-purpose code, then a single-core DSP might be good enough (you can run a simple UI and network interface inside the DSP). But if you need to run a complex operating system like Linux, you should consider a dual-core system on chip.
Another reason for multiple cores on a chip is to increase the total performance. Some applications are so computationally complex that a single DSP processor core is not enough. There are DSP chips with 2 to 4 DSP cores in them. Note that partitioning your application into multiple cores may require a substantial architecture effort.

VLIW

VLIW stands for Very-Large Instruction Word. This is a type of computer architecture that can execute multiple instructions every cycle, and therefore can reduce the execution time of complex programs. The number of parallel instructions issued on VLIW DSP processors varies from 4 to 8. Theoretically, an 8-way VLIW processor can execute 8 times as many operations per second than a regular (scalar) processor, but in practice the amount of speedup is limited by the available parallelism in the program. In average VLIW processors can execute 2 to 4 times faster than scalar DSPs, but manual optimization is required to fully exploit this feature.

On-Chip Memory

System memory (like DRAM) is much slower than the processor. When a program needs to read data from memory, the whole CPU will stall until the memory read completes. To alleviate this, processors utilize fast on-chip memory that can be read or stored in a single cycle. You still may need to move data from main memory, but once it is on-chip, the program will run very efficiently.
On-chip memories can either be arranged as caches, or as user-programmable memories. Cache memory will hold a copy of anything that is read from main memory, so subsequent accesses are done from the cache. Stores to main memory get trapped by the cache, and only get copied back to main memory when the cache is running out of space. On user-programmable on-chip memories, data needs to be explicitly moved in and out of them. Once on-chip, data accesses can be done without any stalls.
Most applications will require some amount of on-chip memory to maintain the DSP processor running at full speed. Figuring-out how much on-chip memory you need will require some careful analysis of your application and some benchmarking (simulation).

Speed

There is a wide range of CPU speeds for DSP processors, from about 100 MHz, to about 1 GHz. Faster processors will tend to consume more power and dissipate more heat, so you will want to select a DSP processor that is just powerful enough for your application.
The best way to determine if your application will fit on a given DSP processor is to benchmark it. This is the process of executing a set of programs that is representative of your application on a cycle-accurate simulator of your target platform.

Cost

DSP processor prices range from less than $10 to about $100. A 32-bit processor will be more expensive than a 16-bit. Having a floating-point unit will cost more. Larger caches or on-chip memories will also be more expensive. Adding VLIW or increasing the CPU speed will also add to the cost.
If your volumes are going to be high, you will want to carefully select the processor that just meets your needs. This is not an easy task, as you won’t know how fast your application will execute until it’s fully ported and optimized. However, it is still possible to estimate by using benchmarks.
Inband Software can help you select the right DSP processor for your application. We can help you interpret third-party benchmark data, and run detailed benchmark simulations specific to your application, and then recommend one DSP processor that is just right for your needs.

2014年3月6日星期四

UNICODE 下的 CString 与 char 之间的转换

CString 与 char 之间的转换
CString是MFC为我们提供的String类。
如果在UNICODE字符集下使用该类型,气元素为TCHAR也就是所谓的宽字节。 这种情况下往往有些函数需要char *这时候就要用到char与TCHAT之间的转换。 这里我们讲解最简单的一种方法。
利用MFC的CStringA类的构造函数来将这两种类型相互转换。
UNICODE字符集下:
CString转换为char*
CString strW = TEXT(“宽字节字符串TCHAR”); CStringA strA(strW);
//这里通过CStringA的构造函数将strW转换为了strA,strA的元素师char类型的。 char * p = strA.GetBuffer();  
char* 转化为CString
char * p = “char类型的数据”; CStringA strA(p); //转换为CStringA CString strW(strA);

SQLite之数据插入、更新和删除

本节内容如何向SQLite表中插入,更新和删除数据。实现这些操作的SQL语句分别为INSERT,UPDATEDELETE。这些语句是SQL数据操作语言(DML)中的一部分。

插入数据

INSERT语句用于向表中插入数据。我们这里有一个已经创建好的表Books,先看看创建这个表的SQL语句结构和表中的数据。
1
2
3
4
5
6
7
8
sqlite> .schema Books
CREATE TABLE Books(Id integer PRIMARY KEY,Title text,Author text,
Isbn text default 'not available');
sqlite> SELECT * FROM Books;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
表Books有四列,字段名分别为Id,Title,Autor和Isbn,其中Id定义为INTEGER PRIMARY kEY,这表示Id为主键,其值是唯一标示一行数据的,同时Id的值是自动增加的,这意味着SQLite库为增加一个新的Id。
1
2
3
4
5
6
7
8
sqlite> INSERT INTO Books(Id,Title,Author,Isbn)
   ...> VALUES(4,'Visual C++程序开发','明日科技','978-7-115-20107-2');     
sqlite> SELECT * FROM Books;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|Visual C++程序开发|明日科技|978-7-115-20107-2
上面我们向表Books插入一行新的数据。
1
2
3
4
5
6
7
8
9
sqlite> INSERT INTO Books(Title,Author,Isbn)
   ...> VALUES('21天学通Linux C编程','马玉军等','978-7-12110622-4');
sqlite> SELECT * FROM Books;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|Visual C++程序开发|明日科技|978-7-115-20107-2
5|21天学通Linux C编程|马玉军等|978-7-12110622-4
这里我们向表中插入一行新的数据,但我们没有指定Id的值,可以看到没指定Id的值时,Id的值是自动递增的。
1
2
3
4
5
6
7
8
9
sqlite> INSERT INTO Books VALUES(6,'PHP开发宝典','刘欣等','978-7-111-38093-1');
sqlite> SELECT * FROM Books;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|Visual C++程序开发|明日科技|978-7-115-20107-2
5|21天学通Linux C编程|马玉军等|978-7-12110622-4
6|PHP开发宝典|刘欣等|978-7-111-38093-1
上面的插入语句我们在表名后没有指定任何列名。在这种情况下我们需要指定所有的列值。
1
sqlite> .nullvalue NULL
.nullvalue NULL告诉SQLite以NULL代表空值。所以SQLite默认情况下以NULL代替空字符串。
1
2
3
4
5
6
7
8
9
10
11
sqlite> .nullvalue NULL
sqlite> INSERT INTO Books(Id,Title) VALUES(7,'红高粱');
sqlite> SELECT * FROM Books;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|Visual C++程序开发|明日科技|978-7-115-20107-2
5|21天学通Linux C编程|马玉军等|978-7-12110622-4
6|PHP开发宝典|刘欣等|978-7-111-38093-1
7|红高粱|NULL|not available
上面SQL插入语句省略了后两个列值。这些列会被默认值或NULL填充。Author列没有默认值,因此以NULL替代。我们在创建表时指定Isbn列的默认值为'not available',因此这里会用该值来替代。
1
2
3
4
5
6
7
8
9
10
11
12
13
sqlite>  INSERT INTO Books VALUES(4,'过得刚好','郭得纲','978-7-550-21422-4');
Error: PRIMARY KEY must be unique
sqlite> INSERT OR REPLACE INTO Books
   ...> VALUES(4,'过得刚好','郭得 纲','978-550-21422-4);
sqlite> SELECT * FROM Books;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|过得刚好|郭得纲|978-550-21422-4
5|21天学通Linux C编程|马玉军等|978-7-12110622-4
6|PHP开发宝典|刘欣等|978-7-111-38093-1
7|红高粱||not available
这里我们向已经存在的行插入新的数据,结果会提示错误。这是因为Id是主键,其值是唯一的,不能有重复。这种情况下我们想插入数据,可以使用INSERT OR REPLACE语句,这样可以将已经存在的行的数据进行替换,当然使用UPDATE语句也可以实现同样功能。
我们可以使用INSERT语句一次性向表中插入多行数据。下面我们创建一个表Ints,并向表中一次插入五行数据。
1
2
3
4
5
6
7
8
9
10
sqlite> CREATE TABLE Ints(Id INTEGER PRIMARY KEY,Val INTEGER);
sqlite> INSERT INTO Ints(Val) VALUES (1),(2),(3),(4),(5);
sqlite> SELECT * FROM Ints;
Id                    Val                
--------------------  --------------------
1                     1                  
2                     2                  
3                     3                  
4                     4                  
5                     5   
这是Ints表中的所有数据。
我们可以在一个SQL语句中将INSERT和SELECT语句结合起来一起使用。我们先创建一个和Books表结构一样的表Books2。
1
2
3
4
5
sqlite> .schema Books
CREATE TABLE Books(Id integer PRIMARY KEY,Title text,Author text,
Isbn text default 'not available');
sqlite> CREATE TABLE Books2(Id integer PRIMARY KEY,Title text,Author text,
Isbn text default 'not available'); 
1
2
3
4
5
6
7
8
9
10
sqlite> INSERT INTO Books2 SELECT * FROM Books;
sqlite> SELECT * FROM Books2;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
2|鸟哥的Linux私房菜|鸟哥|978-7-115-22626-6
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|过得刚好|郭得纲|978-550-21422-4
5|21天学通Linux C编程|马玉军等|978-7-12110622-4
6|PHP开发宝典|刘欣等|978-7-111-38093-1
7|红高粱||not available
我们将Books中的所有数据插入到表Books2中。

删除数据

DELETE语句用于从表中删除数据。首先我们从表中删除一行数据。我们使用先前创建的表Books2。
1
2
3
4
5
6
7
8
9
sqlite> DELETE FROM Books2 WHERE Id = 2;
sqlite> SELECT * FROM Books2;
Id|Title|Author|Isbn
1|C Primer Plus|Stephen Prata|978-7-115-13022-8/TP
3|OpenGL编程指南|Dave Shreiner|978-7-111-29450-4
4|过得刚好|郭得纲|978-550-21422-4
5|21天学通Linux C编程|马玉军等|978-7-12110622-4
6|PHP开发宝典|刘欣等|978-7-111-38093-1
7|红高粱||not available
我们将Id为2的行删除。查看表中的所有数据,第二行数据已经被删除。
1
sqlite> DELETE FROM Books2;
该语句将表中的所有数据删除。

更新数据

UPDATE语句用于修改表中指定行的列值。如果我们想将Books表中的'郭德纲'改为'于谦',我们可以使用下面的语句来实现。
1
2
3
4
sqlite> UPDATE Books SET Author='于谦' WHERE Id = 4;
sqlite> SELECT * FROM Books WHERE Id = 4 ;
Id|Title|Author|Isbn
4|过得刚好|于谦|978-550-21422-4
可以看出Id为4的行中列Author的数据已经被成功修改。
这一节我们主要介绍如何向表中插入、删除和修改数据。