|
|
  |
WINAVR rand(), не работает RAND_MAX |
|
|
|
Apr 19 2009, 16:07
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 14-04-09
Пользователь №: 47 685

|
Цитата(Сергей Борщ @ Apr 19 2009, 18:53)  Потому что RAND_MAX никак не влияет и не может влиять на работу библиотечной функции rand(). Через эту константу разработчики библиотеки сообщают ее пользователю, в каком диапазоне функция генерит свой результат. Повлиять на генерируемый функцией результат вы можете, изменив исходный код функции и перекомпилировав библотеку. А вот привести полученный от нее результат к интересующему вас диапазону вполне возможно. Пример - код zltigo.
Быстрее будет, но вот о нормальном распределении полученных значений можно забыть. У меня в источнике есть вот это Математическое макроопределение #define RAND_MAX 0X....... наибольшее значение генерируемое rand От этого и вопросы задавал. Всем спасибо, а с каких пор зазорно стало спрашивать ? Уважаемый модератор не стоит на людей бросаться. Цитата(zltigo @ Apr 19 2009, 18:56)  Все. Финиш  товарищ устал СПАСИБО ВСЕМ.
|
|
|
|
|
Apr 19 2009, 16:15
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Сергей Борщ @ Apr 19 2009, 19:53)  Быстрее будет, но вот о нормальном распределении полученных значений можно забыть. Ну хорошо, согласен, нормальное распеределение чуть подпортил... Но тогда вот так: Код value = rand() * 10; value = value >> 15; где 15 это разрядность RAND_MAX И все равно в 10-20 раз быстрее...
|
|
|
|
|
Apr 19 2009, 16:19
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 14-04-09
Пользователь №: 47 685

|
напоследок. RAND_MAX восстанавливать с прежним значением не нужно, раз оно носит чисто информационный характер и ничего страшного не произойдет ? про машину ...здорово
Сообщение отредактировал heburashka - Apr 19 2009, 16:21
|
|
|
|
|
Apr 19 2009, 16:27
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(singlskv @ Apr 19 2009, 19:15)  Код value = rand() * 10; value = value >> 15; где 15 это разрядность RAND_MAX И все равно в 10-20 раз быстрее... Прям сейчас представил, как будет "выстрее" у AVR c 32bitным value  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 19 2009, 16:32
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 14-04-09
Пользователь №: 47 685

|
Цитата(ARV @ Apr 19 2009, 19:23)  формально - ничего страшного. но лучше восстановить, ибо кто знает, какие проекты вы будете собирать в будущем - возможно среди них попадутся те, которые используют эту константу... спасибо.
|
|
|
|
|
Apr 19 2009, 16:38
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Apr 19 2009, 20:27)  Прям сейчас представил, как будет "выстрее" у AVR c 32bitным value  . Пробуем ? Вы с %10 я с умножением таргет для однозначности например мега8. Или cлабо ?
|
|
|
|
|
Apr 19 2009, 16:44
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 14-04-09
Пользователь №: 47 685

|
singlskv спасибо за #15 пост ! наши однозначно быстрее
|
|
|
|
|
Apr 19 2009, 16:48
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(heburashka @ Apr 19 2009, 19:44)  спасибо за #15 пост ! Если-бы он еще имел какое-то отношение к сути проблемы а не к дополнительным ограничениям конкретной реализации. Похоже,что после этого поста heburashka окончательно запутался в причинах  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 19 2009, 18:53
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Apr 19 2009, 20:43)  Скорее всего лениво  . Если уж беретесь проверить,то давайте оба варианта ввиде листинга сюда. Дык запросто, хотя и лениво было... чтоб меня не обвиняли в неправильном компиляторе, поставил IAR и сделал в нем: Код #include <stdlib.h>
int A; volatile char B;
int main( void ) { long c;
A = rand(); B = A % 10; A = rand(); c = A * 20UL; B = c >> 16;
return 0; } CODE 10: A = rand(); +00000019: D016 RCALL PC+0x0017 Relative call subroutine 11: B = A % 10; +0000001A: E04A LDI R20,0x0A Load immediate +0000001B: E050 LDI R21,0x00 Load immediate +0000001C: 8100 LDD R16,Z+0 Load indirect with displacement +0000001D: D040 RCALL PC+0x0041 Relative call subroutine +0000001E: 93400066 STS 0x0066,R20 Store direct to data space 13: A = rand(); +00000020: D00F RCALL PC+0x0010 Relative call subroutine 15: B = c >> 16; +00000021: 8100 LDD R16,Z+0 Load indirect with displacement +00000022: 2F21 MOV R18,R17 Copy register +00000023: 0F22 LSL R18 Logical Shift Left +00000024: 0B22 SBC R18,R18 Subtract with carry +00000025: 2F32 MOV R19,R18 Copy register +00000026: E144 LDI R20,0x14 Load immediate +00000027: E050 LDI R21,0x00 Load immediate +00000028: E060 LDI R22,0x00 Load immediate +00000029: E070 LDI R23,0x00 Load immediate +0000002A: D046 RCALL PC+0x0047 Relative call subroutine +0000002B: 93200066 STS 0x0066,R18 Store direct to data space 17: return 0; +0000002D: E000 LDI R16,0x00 Load immediate +0000002E: E010 LDI R17,0x00 Load immediate +0000002F: 9508 RET Subroutine return @00000030: _..X_RSTACK_BASE ---- No Source ------------------------------------------------------------------------------------ +00000030: D062 RCALL PC+0x0063 Relative call subroutine +00000031: E6E4 LDI R30,0x64 Load immediate +00000032: E0F0 LDI R31,0x00 Load immediate +00000033: 8300 STD Z+0,R16 Store indirect with displacement +00000034: 8311 STD Z+1,R17 Store indirect with displacement +00000035: 9508 RET Subroutine return @00000036: ?C_FUNCALL +00000036: 0000 NOP No operation @00000037: __exit +00000037: 9588 SLEEP Sleep +00000038: CFFE RJMP PC-0x0001 Relative jump @00000039: ?C_STARTUP +00000039: EA06 LDI R16,0xA6 Load immediate +0000003A: BF0D OUT 0x3D,R16 Out to I/O location +0000003B: E000 LDI R16,0x00 Load immediate +0000003C: BF0E OUT 0x3E,R16 Out to I/O location +0000003D: E8C7 LDI R28,0x87 Load immediate +0000003E: E0D0 LDI R29,0x00 Load immediate @0000003F: ?call_low_level_init +0000003F: D051 RCALL PC+0x0052 Relative call subroutine @00000040: ?need_segment_init +00000040: 2300 TST R16 Test for Zero or Minus +00000041: F009 BREQ PC+0x02 Branch if equal +00000042: D074 RCALL PC+0x0075 Relative call subroutine @00000043: ?cstartup_call_main +00000043: DFD5 RCALL PC-0x002A Relative call subroutine +00000044: DFF1 RCALL PC-0x000E Relative call subroutine +00000045: CFF0 RJMP PC-0x000F Relative jump @00000046: ?US_DIVMOD_L02 +00000046: 2400 CLR R0 Clear Register +00000047: 2411 CLR R1 Clear Register +00000048: E0EF LDI R30,0x0F Load immediate +00000049: 1F00 ROL R16 Rotate Left Through Carry +0000004A: 1F11 ROL R17 Rotate Left Through Carry +0000004B: 1C00 ROL R0 Rotate Left Through Carry +0000004C: 1C11 ROL R1 Rotate Left Through Carry +0000004D: 1604 CP R0,R20 Compare +0000004E: 0615 CPC R1,R21 Compare with carry +0000004F: F010 BRCS PC+0x03 Branch if carry set @00000050: _..X_SRAM_TSIZE +00000050: 1A04 SUB R0,R20 Subtract without carry +00000051: 0A15 SBC R1,R21 Subtract with carry +00000052: 95EA DEC R30 Decrement +00000053: F7AA BRPL PC-0x0A Branch if plus +00000054: 1F00 ROL R16 Rotate Left Through Carry +00000055: 1F11 ROL R17 Rotate Left Through Carry +00000056: 01A0 MOVW R20,R0 Copy register pair +00000057: 9500 COM R16 One's complement +00000058: 9510 COM R17 One's complement +00000059: 9508 RET Subroutine return +0000005A: 9551 NEG R21 Two's complement +0000005B: 9541 NEG R20 Two's complement +0000005C: 4050 SBCI R21,0x00 Subtract immediate with carry +0000005D: 9508 RET Subroutine return @0000005E: ?SS_DIVMOD_L02 +0000005E: 27FF CLR R31 Clear Register +0000005F: 2355 TST R21 Test for Zero or Minus +00000060: F412 BRPL PC+0x03 Branch if plus +00000061: 60F1 ORI R31,0x01 Logical OR with immediate +00000062: DFF7 RCALL PC-0x0008 Relative call subroutine +00000063: 2311 TST R17 Test for Zero or Minus +00000064: F412 BRPL PC+0x03 Branch if plus +00000065: 95F0 COM R31 One's complement +00000066: D006 RCALL PC+0x0007 Relative call subroutine +00000067: DFDE RCALL PC-0x0021 Relative call subroutine +00000068: FDF0 SBRC R31,0 Skip if bit in register cleared +00000069: D003 RCALL PC+0x0004 Relative call subroutine +0000006A: FDF1 SBRC R31,1 Skip if bit in register cleared +0000006B: CFEE RJMP PC-0x0011 Relative jump +0000006C: 9508 RET Subroutine return +0000006D: 9511 NEG R17 Two's complement +0000006E: 9501 NEG R16 Two's complement +0000006F: 4010 SBCI R17,0x00 Subtract immediate with carry +00000070: 9508 RET Subroutine return @00000071: ?L_EC_MUL_L03 +00000071: 2422 CLR R2 Clear Register +00000072: 9F34 MUL R19,R20 Multiply unsigned +00000073: 2D30 MOV R19,R0 Copy register +00000074: 9F25 MUL R18,R21 Multiply unsigned +00000075: 0D30 ADD R19,R0 Add without carry +00000076: 9F16 MUL R17,R22 Multiply unsigned +00000077: 0D30 ADD R19,R0 Add without carry +00000078: 9F07 MUL R16,R23 Multiply unsigned +00000079: 0D30 ADD R19,R0 Add without carry +0000007A: 9F24 MUL R18,R20 Multiply unsigned +0000007B: 2D20 MOV R18,R0 Copy register +0000007C: 0D31 ADD R19,R1 Add without carry +0000007D: 9F15 MUL R17,R21 Multiply unsigned +0000007E: 0D20 ADD R18,R0 Add without carry +0000007F: 1D31 ADC R19,R1 Add with carry +00000080: 9F06 MUL R16,R22 Multiply unsigned +00000081: 0D20 ADD R18,R0 Add without carry +00000082: 1D31 ADC R19,R1 Add with carry +00000083: 9F14 MUL R17,R20 Multiply unsigned +00000084: 2D10 MOV R17,R0 Copy register +00000085: 0D21 ADD R18,R1 Add without carry +00000086: 1D32 ADC R19,R2 Add with carry +00000087: 9F05 MUL R16,R21 Multiply unsigned +00000088: 0D10 ADD R17,R0 Add without carry +00000089: 1D21 ADC R18,R1 Add with carry +0000008A: 1D32 ADC R19,R2 Add with carry +0000008B: 9F04 MUL R16,R20 Multiply unsigned +0000008C: 2D00 MOV R16,R0 Copy register +0000008D: 0D11 ADD R17,R1 Add without carry +0000008E: 1D22 ADC R18,R2 Add with carry +0000008F: 1D32 ADC R19,R2 Add with carry +00000090: 9508 RET Subroutine return @00000091: __low_level_init +00000091: E001 LDI R16,0x01 Load immediate +00000092: 9508 RET Subroutine return @00000093: rand +00000093: E64D LDI R20,0x6D Load immediate +00000094: E45E LDI R21,0x4E Load immediate +00000095: EC66 LDI R22,0xC6 Load immediate +00000096: E471 LDI R23,0x41 Load immediate +00000097: E6E0 LDI R30,0x60 Load immediate +00000098: E0F0 LDI R31,0x00 Load immediate +00000099: 8100 LDD R16,Z+0 Load indirect with displacement +0000009A: 8111 LDD R17,Z+1 Load indirect with displacement +0000009B: 8122 LDD R18,Z+2 Load indirect with displacement +0000009C: 8133 LDD R19,Z+3 Load indirect with displacement +0000009D: DFD3 RCALL PC-0x002C Relative call subroutine +0000009E: 5C07 SUBI R16,0xC7 Subtract immediate +0000009F: 4C1F SBCI R17,0xCF Subtract immediate with carry +000000A0: 4F2F SBCI R18,0xFF Subtract immediate with carry +000000A1: 4F3F SBCI R19,0xFF Subtract immediate with carry +000000A2: 8300 STD Z+0,R16 Store indirect with displacement +000000A3: 8311 STD Z+1,R17 Store indirect with displacement +000000A4: 8322 STD Z+2,R18 Store indirect with displacement +000000A5: 8333 STD Z+3,R19 Store indirect with displacement +000000A6: 0189 MOVW R16,R18 Copy register pair +000000A7: 771F ANDI R17,0x7F Logical AND with immediate +000000A8: 9508 RET Subroutine return @000000A9: __memclr +000000A9: E020 LDI R18,0x00 Load immediate +000000AA: D006 RCALL PC+0x0007 Relative call subroutine +000000AB: F7E9 BRNE PC-0x02 Branch if not equal +000000AC: 9508 RET Subroutine return @000000AD: __flashcpy +000000AD: 9125 LPM R18,Z+ Load program memory and postincrement +000000AE: D002 RCALL PC+0x0003 Relative call subroutine +000000AF: F7E9 BRNE PC-0x02 Branch if not equal +000000B0: 9508 RET Subroutine return +000000B1: 932D ST X+,R18 Store indirect and postincrement +000000B2: 5001 SUBI R16,0x01 Subtract immediate +000000B3: 4010 SBCI R17,0x00 Subtract immediate with carry +000000B4: 2F20 MOV R18,R16 Copy register +000000B5: 2B21 OR R18,R17 Logical OR +000000B6: 9508 RET Subroutine return @000000B7: __segment_init +000000B7: E286 LDI R24,0x26 Load immediate +000000B8: E090 LDI R25,0x00 Load immediate +000000B9: 01FC MOVW R30,R24 Copy register pair +000000BA: 9105 LPM R16,Z+ Load program memory and postincrement +000000BB: 9114 LPM R17,Z Load program memory +000000BC: 01FC MOVW R30,R24 Copy register pair +000000BD: 9632 ADIW R30,0x02 Add immediate to word +000000BE: 91A5 LPM R26,Z+ Load program memory and postincrement +000000BF: 91B4 LPM R27,Z Load program memory +000000C0: 01FC MOVW R30,R24 Copy register pair +000000C1: 9634 ADIW R30,0x04 Add immediate to word +000000C2: 9125 LPM R18,Z+ Load program memory and postincrement +000000C3: 9134 LPM R19,Z Load program memory +000000C4: 2F42 MOV R20,R18 Copy register +000000C5: 2B43 OR R20,R19 Logical OR +000000C6: F019 BREQ PC+0x04 Branch if equal +000000C7: 01F9 MOVW R30,R18 Copy register pair +000000C8: DFE4 RCALL PC-0x001B Relative call subroutine +000000C9: C001 RJMP PC+0x0002 Relative jump +000000CA: DFDE RCALL PC-0x0021 Relative call subroutine +000000CB: 9606 ADIW R24,0x06 Add immediate to word +000000CC: E010 LDI R17,0x00 Load immediate +000000CD: 3382 CPI R24,0x32 Compare with immediate +000000CE: 0791 CPC R25,R17 Compare with carry +000000CF: F348 BRCS PC-0x16 Branch if carry set +000000D0: 9508 RET Subroutine return +000000D1: 0001 ??? Data or unknown opcode +000000D2: 0000 NOP No operation +000000D3: DFDE RCALL PC-0x0021 Relative call subroutine +000000D4: 9606 ADIW R24,0x06 Add immediate to word +000000D5: E010 LDI R17,0x00 Load immediate +000000D6: 3382 CPI R24,0x32 Compare with immediate +000000D7: 0791 CPC R25,R17 Compare with carry +000000D8: F348 BRCS PC-0x16 Branch if carry set +000000D9: 9508 RET Subroutine return
Да, ошибся  всего в 4 раза быстрее, правда я еще нифига не оптимизировал... в 10 раз легко...
|
|
|
|
|
Apr 19 2009, 19:26
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(singlskv @ Apr 19 2009, 21:53)  Да, ошибся  всего в 4 раза быстрее, правда я еще нифига не оптимизировал... в 10 раз легко... Какое отношение имеют ошметки какого-то листинга к выводам о 4x выигрыше в чем-то? Раз уж плавно на IAR перешли, то вот быстренько скопипастил исходник библиотечной IAR функции: Код ;------------------------------------------------------------- ; US_DIVMOD_L02 ; 'short' (i.e. 16 bit) unsigned division and modulo ; On call: PW = dividend (i.e. number to be divided by divisor) ; QW = divisor ; On return: PW = quotient, QW = remainder ; ; NOTE: This subroutine is also called from SS_DIVMOD_L02 ; ; Destroys: P0 P1 Q0 Q1 T0 T1 Z0 ; ; SIZE: 42 bytes ; ; TBD: The optimization for speed when Q1 .NE. 0, described in the ; algorithm has not been implemented here, it will add some ; 8 instructions to the code.
MODULE ?US_DIVMOD_L02 PUBLIC ?US_DIVMOD_L02 RSEG CODE:CODE:NOROOT(1)
; Do not change this function without changing the information in the compiler. 2004-02-26 ?US_DIVMOD_L02: CLR T0 ; Clear remainder CLR T1 ; - "" - LDI Z0,15 ; Loop counter A25: ROL P0 ; Shift quotient/dividend ROL P1 ; ROL T0 ; --> into remainder ROL T1 ; CP T0,Q0 ; Is remainder < divisor ? CPC T1,Q1 BRLO A25_1 ; Yes, but carry 0 expected by algorithm, ; is actually 1 here. ; ; Here if time to subtract, i.e. value in remainder is equal to ; or larger than divisor. ; SUB T0,Q0 SBC T1,Q1 ; Carry 1 expected, is actually 0 ! A25_1: DEC Z0 ; Does not affect carry BRPL A25; All done B25: ROL P0 ; Only quotient shifted ROL P1 ; in last step. #ifdef __HAS_ENHANCED_CORE__ MOVW Q1:Q0,T1:T0; Remainder #else MOV Q0,T0 ; Remainder MOV Q1,T1 #endif COM P0 ; Correct for inverse carry setting COM P1 RET
ENDMOD Которая собственно все и делает. Не подарок,конечно, для AVR получается  То, что Вы предлагаете: Код unsigned long value = rand() * 10; value = value >> 15; Компильните и нормальный листинг выложите сюда. Тогда и можно будет говорить о 10...4 разнице. P.S. А для младших-то AVR умножение эмулировать придется
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 19 2009, 19:41
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Apr 19 2009, 23:26)  Какое отношение имеют ошметки какого-то листинга к выводам о 4x выигрыше в чем-то? Стоп, я скомпилировал именно IAR компилятором и именно тот исходник который показал... И листинг выложен полный... копия из AVR Studio, так что не надо ля-ля... Цитата Раз уж плавно на IAR перешли, то вот быстренько скопипастил исходник библиотечной IAR функции: Которая собственно все и делает. Не подарок,конечно, для AVR получается  Ну и ... ? Цитата То, что Вы предлагаете: Код unsigned long value = rand() * 10; value = value >> 15; Компильните и нормальный листинг выложите сюда. Тогда и можно будет говорить о 10...4 разнице. Дык еще раз предлагаю, делаем 2 проекта и показываем листинг и количество тактов... Или снова слабо и тока ля-ля... Цитата(zltigo @ Apr 19 2009, 23:26)  А для младших-то AVR умножение эмулировать придется  Несомненно делить там будет намного выгоднее
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|