我想为可在不同MCU(16位,32位或64位基础)上运行的应用程序编写可移植代码。
让我们考虑一下这个片段:
events = 0;
for (size_t i = 0; i < sizeof(array) / sizeof(array[0]); i++) {
if (array[i] > threshold)
events++;
}
我的问题涉及循环计数器变量的类型,这里是size_t
。
通常size_t
应该足够大以解决我系统的所有内存问题。因此,使用size_t
可能会影响我的代码在某些体系结构上的性能,因为此变量的宽度对于我拥有的数组的长度来说太大了。
有了这个假设,我最好使用uint_fast16_t
因为我知道我的array
少于65k元素。
关心这篇文章是否有意义,或者我的编译器是否足够聪明以优化它?
我认为与uint_fast16_t
相比,size_t
很少使用,而且很少使用。{/ p>
更具体地说明我的问题:
我是否通过系统地为我的循环计数器(uint_fast8_t
,uint_fast16_t
,...)使用正确的类型来改进代码的可移植性,或者我更喜欢使用size_t
,因为在在大多数情况下,它在性能方面没有差异吗?
修改
根据您的评论和评论,很明显,大多数情况下,编译器将注册循环计数器,因此在size_t
或uint_fast8_t
之间进行选择并不重要。
main: # @main
mov rax, -80
mov ecx, dword ptr [rip + threshold]
.LBB0_1: # =>This Inner Loop Header: Depth=1
[....]
.LBB0_5: # in Loop: Header=BB0_1 Depth=1
add rax, 8 # <----------- Kept in a register
jne .LBB0_1
jmp .LBB0_6
.LBB0_2: # in Loop: Header=BB0_1 Depth=1
[....]
.LBB0_6:
xor eax, eax
ret
如果循环长度变得大于内部CPU寄存器,则该问题可能成为一个真正的问题。在8位微控制器上进行512次循环。
答案 0 :(得分:1)
对于便携式代码,请使用size_t
。
对于快速代码......好吧,这取决于你的编译器和处理器。如果使用16位类型,它可能在16位处理器上运行得最快,但在64位处理器上实际上慢而不是size_t
。在衡量绩效之前,你不应该做任何事情。
我使用size_t
并且只有在存在可解决的性能问题时才会进一步考虑进行优化。
答案 1 :(得分:0)
与任何优化一样,首先为便携式常见案例编写简单代码(使用size_t)。然后使用其他类型查看平台上的程序集。 如果其中一种类型的工作速度更快或生成的代码明显更少,您可以为这些类型的访问键入一种特殊的索引类型。例如,您可以使用near,far和huge指针(以及相应的索引)的概念,除非使用固定宽度类型,否则为清晰起见。
/* The compiler for my16bitmcu, cannot detect ranges to use appropriate types */
#if defined __MY16BITMCU__ /* replace with architecture's predefined macro */
typedef uint16_t size8t, size16t; /* use uint8_t for size8t on 8bit */
typedef uint32_t size32t;
typedef uint64_t size64t;
typedef int16_t ptrdiff8t, ptrdiff16t; /* use int8_t for ptrdiff8t on 8bit */
typedef int32_t ptrdiff32t;
typedef int64_t ptrdiff64t;
#else
typedef size_t size8t, size16t, size32t, size64t;
typedef ptrdiff_t ptrdiff8t, ptrdiff16t, ptrdiff32t, ptrdiff64t;
#endif
/** example usage: sum the total of an array
** using size8t for count reduces complexity on some 8/16 bit systems
** on other systems, size8t is the same as size_t
**/
int sum_numbers(int *numbers, size8t count){
int total = 0;
while(count--) total += numbers[count];
return total;
}
答案 2 :(得分:-1)
对于MCU,请使用您知道适合阵列大小的最小类型。如果您知道该数组可能大于256字节但从不大于65536,那么function sendMail($applicationID){
$host = 'localhost';
$user = 'username';
$pass = 'password';
$db = 'database';
$conn = mysqli_connect($host,$user,$pass,$db) or die("Error ". mysqli_connect_error()). PHP_EOL;
$distributor_details = mysqli_fetch_assoc(mysqli_query($conn,"select * from distributor where status = '1' and deleted IS NULL and id = '$applicationID' limit 0,1 "));
if(isset($distributor_details['id'])){
$state=mysqli_fetch_array(mysqli_query($conn,"select * from tbl_state where id='".$distributor_details['state']."' "));
$country=mysqli_fetch_array(mysqli_query($conn,"select * from tbl_country where id='".$distributor_details['country']."' "));
/*<tr>
<th height="25">Application ID:</th><td>'.distributorNumber($distributor_details['id']).'</td>
</tr>*/
$message = '<html>
<head>
<title>Triveni Almirah</title>
</head>
<body>
<h1>Dealer/Distributor Enquiry Details</h1>
<table cellspacing="0" style="border: 2px dashed #3c8dbc; width: 100%; height: auto;">
<tr style="background-color: #e0e0e0;">
<th height="25">Name:</th><td>'.stripslashes(strtoupper($distributor_details['fname'])).'</td>
</tr>
<tr>
<th height="25">Email Id:</th><td>'.$distributor_details['email'].'</td>
</tr>
<tr style="background-color: #e0e0e0;">
<th height="25">Mobile:</th><td>'.$distributor_details['mobile'].'</td>
</tr>
<tr>
<th>Address:</th><td>'.strtoupper($distributor_details['city']).'</td>
</tr>
<tr>
<th height="25">Comments:</th><td>'.$distributor_details['comment'].'</td>
</tr>
<tr style="background-color: #e0e0e0;">
<th height="25">Posted Date:</th><td>'.date("d-m-Y",strtotime($distributor_details['post_date'])).'</td>
</tr>
</table>
</body>
</html>';
$headers = "MIME-Version: 1.0;\n";
$headers .= "Content-type: text/html; charset=iso-8859-1;\n";
$headers.='From:HIRDESH - VASHISHTHA <noreply@domain.com>' . "\r\n".PHP_EOL;
//$headers.='CC: abcd48@gmail.com' . "\r\n".PHP_EOL;
//$port = 587;
//$auth = true;
//echo $message; die;
mail("data@domain.com","Distributorship Enquiry",$message,$headers);
}
return true;
}
确实是最合适的类型。
这里的主要问题是具有扩展闪存(> 64kb)的16位MCU,提供24或32位地址宽度。这是许多16苦的常态。在这样的系统上,uint_fast16_t
将是32位,因此将是一种慢速类型。
如果不考虑8或16位苦味的可移植性,那么我会使用size_t
。
根据我的经验,许多嵌入式编译器不够智能,无法优化代码使用比上述类型更小的类型,即使它们可以在编译时减去数组大小。