CrcGenerateTable() at \C\7zCrc.c
populates the global structure
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
Shouldn't this function use a flag for skipping recalculating the tables when the tables were already calculated probably from some other thread?
Shouldn't be a good idea checking this proposed "populated crc table" flag on crc functions like g_CrcUpdate() and trigger the crc table creation from there if needed?
Thanks.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, that code needs accurate programming.
Call it once in C code.
I just use
CPP\Common\CRC.cpp
in all C++ code projects that use CRC32.
Shouldn't be a good idea checking this proposed "populated crc table" flag on crc functions like g_CrcUpdate() and trigger the crc table creation from there if needed?
I don't want to get multithreading difficulties of such code (LOCKS and so on). Look: two threads can read flag at same time. So they both will fill array.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK I just wanted to check if I was missing something.
About the flag it's true 2 threads could read it FALSE at the same time w/o synchronization but that will just trigger two simultaneous populate actions thing that does not represents a problem as the "update" of the table values are atomic operations. After this non-harmful "collision" both threads will set the flag to TRUE and the table will not be created again.
Thanks Igor.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My problem now is that some optimization might be removing the "unused" structure then the constructor is never called.
What type of optimization do you mean?
Note that I use such register/init trick in many places:
different CRCs, AES tables, I register all codecs and archive handlers with such constructors.
The only possible problem, that some programmer can remove such init file from project.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ok it seems it is not an optimization defined by me; the CRC.cpp file in debug mode has no optimization at all but the linker does not include a structure that is not used (sure it is a linker optimization).
I'm aware you use the registration trick specially with coders; e.g. registerArc7z() then just using that dummy function somewhere the linker does include the coder definition; OK I do not see registerCRC() and the linker kills the structure and the constructor is never called.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
VS2008 Professional
I think this is the linker parameter;
Linker/Optimization/[Default]
Optimization:Enable the elimination of functions or data that is never referenced.
/OPT:REF or /OPT:/NOREF
of-course I want to remove not used referenced; many times version n is compiled with some code for the version n+1 that the linker removes when linking version n
I already had this problem with the coders. Your trick is nice but it has this problem.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I use /OPT:REF in all compilers in all projects.
So why I have no any problem?
Please check these problems again, make more investigations of problems and write here about any conclusions.
Check different VC versions, if required.
It's important to solve such problem.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
CrcGenerateTable() at \C\7zCrc.c
populates the global structure
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
Shouldn't this function use a flag for skipping recalculating the tables when the tables were already calculated probably from some other thread?
Shouldn't be a good idea checking this proposed "populated crc table" flag on crc functions like g_CrcUpdate() and trigger the crc table creation from there if needed?
Thanks.
Yes, that code needs accurate programming.
Call it once in C code.
I just use
CPP\Common\CRC.cpp
in all C++ code projects that use CRC32.
I don't want to get multithreading difficulties of such code (LOCKS and so on). Look: two threads can read flag at same time. So they both will fill array.
OK I just wanted to check if I was missing something.
About the flag it's true 2 threads could read it FALSE at the same time w/o synchronization but that will just trigger two simultaneous populate actions thing that does not represents a problem as the "update" of the table values are atomic operations. After this non-harmful "collision" both threads will set the flag to TRUE and the table will not be created again.
Thanks Igor.
Hi Igor, I've seen CRC.cpp also uses CrcGenerateTable()
I think this mod is even better than a flag
what do you think?
What exact cases do you see problem?
CRC.cpp calls CrcGenerateTable().
Who calls it second time?
Extracting a file from a 7z file requires the CRC table populated.
In my extraction function if I do not call CrcGenerateTable() the thing crashes.
Then if I'm extracting several files or extracting from different threads that table gets created every time I call my extraction routine (I use C++)
Am I missing something?
You can add CRC.cpp to your project.
I saw it!
CRC.cpp instantiates a global structure whose constructor calls CrcGenerateTable() only once. I wasn't including CRC.cpp.
My problem now is that some optimization might be removing the "unused" structure then the constructor is never called.
Thanks Igor
What type of optimization do you mean?
Note that I use such register/init trick in many places:
different CRCs, AES tables, I register all codecs and archive handlers with such constructors.
The only possible problem, that some programmer can remove such init file from project.
ok it seems it is not an optimization defined by me; the CRC.cpp file in debug mode has no optimization at all but the linker does not include a structure that is not used (sure it is a linker optimization).
I'm aware you use the registration trick specially with coders; e.g. registerArc7z() then just using that dummy function somewhere the linker does include the coder definition; OK I do not see registerCRC() and the linker kills the structure and the constructor is never called.
What compiler?
VS2008 Professional
I think this is the linker parameter;
Linker/Optimization/[Default]
Optimization:Enable the elimination of functions or data that is never referenced.
/OPT:REF or /OPT:/NOREF
of-course I want to remove not used referenced; many times version n is compiled with some code for the version n+1 that the linker removes when linking version n
I already had this problem with the coders. Your trick is nice but it has this problem.
I use /OPT:REF in all compilers in all projects.
So why I have no any problem?
Please check these problems again, make more investigations of problems and write here about any conclusions.
Check different VC versions, if required.
It's important to solve such problem.
OK, I'll go deeper on this.
I'll let you know.
Thanks Igor
Last edit: foxpat 2014-12-09