The best approach would be to write your automata as a shader, so you're operating directly on the GPU and have direct access to VRAM, but of course you'll be "constraint" by how shaders operate.
Alternatively, I'd recommend to use a texture and call update() with a std::vector<sf::Uint8> which holds all the pixel data (can also be retrieved from an sf::Image with getPixelsPtr()).
As for number 2. If you do want to draw primitives, you basically have to use a vertex array (or depending on the updating also vertex buffer), so your just have one draw call instead of thousands.
It's hard to say whether using update on a texture performs better than drawing tons of primitives, it will also heavily depend on the number of "pixels" you're changing etc.
Best would be to simply do a more or less realistic benchmark of each version and see what works better.